From 53e22b11857fed62e2313d6d84d90f88ed412ffb Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Mon, 29 Jul 2013 12:13:03 +0100 Subject: Changed everyting to Unix line endings. --- source/Blocks/BlockBed.cpp | 170 +++--- source/Blocks/BlockBed.h | 146 ++--- source/Blocks/BlockBrewingStand.h | 64 +-- source/Blocks/BlockCactus.h | 176 +++---- source/Blocks/BlockCauldron.h | 118 ++--- source/Blocks/BlockChest.h | 444 ++++++++-------- source/Blocks/BlockCloth.h | 68 +-- source/Blocks/BlockCobWeb.h | 60 +-- source/Blocks/BlockCrops.h | 216 ++++---- source/Blocks/BlockDeadBush.h | 94 ++-- source/Blocks/BlockDirt.h | 176 +++---- source/Blocks/BlockDoor.cpp | 176 +++---- source/Blocks/BlockDoor.h | 210 ++++---- source/Blocks/BlockDropSpenser.h | 78 +-- source/Blocks/BlockEnderchest.h | 56 +- source/Blocks/BlockEntity.h | 62 +-- source/Blocks/BlockFarmland.h | 198 +++---- source/Blocks/BlockFenceGate.h | 120 ++--- source/Blocks/BlockFire.h | 84 +-- source/Blocks/BlockFlower.h | 106 ++-- source/Blocks/BlockFlowerPot.h | 210 ++++---- source/Blocks/BlockFluid.h | 100 ++-- source/Blocks/BlockFurnace.h | 94 ++-- source/Blocks/BlockGlass.h | 52 +- source/Blocks/BlockGlowstone.h | 60 +-- source/Blocks/BlockGravel.h | 54 +- source/Blocks/BlockHandler.cpp | 906 ++++++++++++++++---------------- source/Blocks/BlockHandler.h | 316 +++++------ source/Blocks/BlockHopper.h | 92 ++-- source/Blocks/BlockIce.h | 74 +-- source/Blocks/BlockLadder.h | 230 ++++---- source/Blocks/BlockLeaves.h | 368 ++++++------- source/Blocks/BlockLever.cpp | 96 ++-- source/Blocks/BlockLever.h | 122 ++--- source/Blocks/BlockMelon.h | 70 +-- source/Blocks/BlockMushroom.h | 142 ++--- source/Blocks/BlockMycelium.h | 54 +- source/Blocks/BlockNote.h | 26 +- source/Blocks/BlockOre.h | 160 +++--- source/Blocks/BlockPiston.cpp | 138 ++--- source/Blocks/BlockPiston.h | 56 +- source/Blocks/BlockRail.h | 842 ++++++++++++++--------------- source/Blocks/BlockRedstone.cpp | 54 +- source/Blocks/BlockRedstone.h | 92 ++-- source/Blocks/BlockRedstoneRepeater.cpp | 94 ++-- source/Blocks/BlockRedstoneRepeater.h | 120 ++--- source/Blocks/BlockRedstoneTorch.h | 72 +-- source/Blocks/BlockSand.h | 56 +- source/Blocks/BlockSapling.h | 138 ++--- source/Blocks/BlockSign.h | 146 ++--- source/Blocks/BlockSlab.h | 140 ++--- source/Blocks/BlockSnow.h | 104 ++-- source/Blocks/BlockStairs.h | 306 +++++------ source/Blocks/BlockStems.h | 116 ++-- source/Blocks/BlockStone.h | 58 +- source/Blocks/BlockSugarcane.h | 192 +++---- source/Blocks/BlockTallGrass.h | 102 ++-- source/Blocks/BlockTorch.h | 518 +++++++++--------- source/Blocks/BlockVine.h | 400 +++++++------- source/Blocks/BlockWood.h | 54 +- source/Blocks/BlockWorkbench.h | 86 +-- 61 files changed, 4966 insertions(+), 4966 deletions(-) (limited to 'source/Blocks') diff --git a/source/Blocks/BlockBed.cpp b/source/Blocks/BlockBed.cpp index 513874252..2ae6980ac 100644 --- a/source/Blocks/BlockBed.cpp +++ b/source/Blocks/BlockBed.cpp @@ -1,85 +1,85 @@ -#include "Globals.h" -#include "BlockBed.h" - - - - - -void cBlockBedHandler::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 -) -{ - 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); - } -} - - - - - -void cBlockBedHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) -{ - NIBBLETYPE OldMeta = a_World->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) - { - a_World->FastSetBlock(ThisPos - Direction, E_BLOCK_AIR, 0); - } - } - else - { - // Was foot end - if (a_World->GetBlock(ThisPos + Direction) == E_BLOCK_BED) - { - a_World->FastSetBlock(ThisPos + Direction, E_BLOCK_AIR, 0); - } - } -} - - - - - -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) -{ - if (a_World->GetDimension() != 0) - { - a_World->DoExplosiontAt(5, a_BlockX, a_BlockY, a_BlockZ); - } else { - if (a_World->GetTimeOfDay() > 13000) - { - NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - if (Meta & 0x8) - { - // Is pillow - a_World->BroadcastUseBed(*a_Player, a_BlockX, a_BlockY, a_BlockZ); - } - 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 - { - a_World->BroadcastUseBed(*a_Player, a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z); - } - } - } else { - a_Player->SendMessage("You can only sleep at night"); - } - } -} - - - - +#include "Globals.h" +#include "BlockBed.h" + + + + + +void cBlockBedHandler::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 +) +{ + 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); + } +} + + + + + +void cBlockBedHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + NIBBLETYPE OldMeta = a_World->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) + { + a_World->FastSetBlock(ThisPos - Direction, E_BLOCK_AIR, 0); + } + } + else + { + // Was foot end + if (a_World->GetBlock(ThisPos + Direction) == E_BLOCK_BED) + { + a_World->FastSetBlock(ThisPos + Direction, E_BLOCK_AIR, 0); + } + } +} + + + + + +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) +{ + if (a_World->GetDimension() != 0) + { + a_World->DoExplosiontAt(5, a_BlockX, a_BlockY, a_BlockZ); + } else { + if (a_World->GetTimeOfDay() > 13000) + { + NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + if (Meta & 0x8) + { + // Is pillow + a_World->BroadcastUseBed(*a_Player, a_BlockX, a_BlockY, a_BlockZ); + } + 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 + { + a_World->BroadcastUseBed(*a_Player, a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z); + } + } + } else { + a_Player->SendMessage("You can only sleep at night"); + } + } +} + + + + diff --git a/source/Blocks/BlockBed.h b/source/Blocks/BlockBed.h index bf8906750..8286ceb11 100644 --- a/source/Blocks/BlockBed.h +++ b/source/Blocks/BlockBed.h @@ -1,73 +1,73 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../World.h" -#include "../Player.h" - - - - - -class cBlockBedHandler : - public cBlockHandler -{ -public: - cBlockBedHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(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 bool IsUseable(void) override - { - return true; - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - // Reset meta to zero - a_Pickups.push_back(cItem(E_ITEM_BED, 1, 0)); - } - - - virtual bool DoesAllowBlockOnTop() override - { - return false; - } - - - // Bed specific helper functions - static NIBBLETYPE RotationToMetaData(double a_Rotation) - { - a_Rotation += 180 + (180 / 4); // So its not aligned with axis - if (a_Rotation > 360) a_Rotation -= 360; - - a_Rotation = (a_Rotation / 360) * 4; - - return ((char)a_Rotation + 2) % 4; - } - - - static Vector3i MetaDataToDirection(NIBBLETYPE a_MetaData) - { - switch (a_MetaData) - { - case 0: return Vector3i(0, 0, 1); - case 1: return Vector3i(-1, 0, 0); - case 2: return Vector3i(0, 0, -1); - case 3: return Vector3i(1, 0, 0); - } - return Vector3i(); - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../World.h" +#include "../Player.h" + + + + + +class cBlockBedHandler : + public cBlockHandler +{ +public: + cBlockBedHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(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 bool IsUseable(void) override + { + return true; + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Reset meta to zero + a_Pickups.push_back(cItem(E_ITEM_BED, 1, 0)); + } + + + virtual bool DoesAllowBlockOnTop() override + { + return false; + } + + + // Bed specific helper functions + static NIBBLETYPE RotationToMetaData(double a_Rotation) + { + a_Rotation += 180 + (180 / 4); // So its not aligned with axis + if (a_Rotation > 360) a_Rotation -= 360; + + a_Rotation = (a_Rotation / 360) * 4; + + return ((char)a_Rotation + 2) % 4; + } + + + static Vector3i MetaDataToDirection(NIBBLETYPE a_MetaData) + { + switch (a_MetaData) + { + case 0: return Vector3i(0, 0, 1); + case 1: return Vector3i(-1, 0, 0); + case 2: return Vector3i(0, 0, -1); + case 3: return Vector3i(1, 0, 0); + } + return Vector3i(); + } +} ; + + + + diff --git a/source/Blocks/BlockBrewingStand.h b/source/Blocks/BlockBrewingStand.h index 34a2b6c56..57642bcb6 100644 --- a/source/Blocks/BlockBrewingStand.h +++ b/source/Blocks/BlockBrewingStand.h @@ -1,32 +1,32 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockBrewingStandHandler : - public cBlockHandler -{ -public: - cBlockBrewingStandHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - a_Pickups.push_back(cItem(E_ITEM_BREWING_STAND, 1, 0)); - } - - virtual bool IsUseable() override - { - return true; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockBrewingStandHandler : + public cBlockHandler +{ +public: + cBlockBrewingStandHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem(E_ITEM_BREWING_STAND, 1, 0)); + } + + virtual bool IsUseable() override + { + return true; + } +} ; + + + + diff --git a/source/Blocks/BlockCactus.h b/source/Blocks/BlockCactus.h index 516f024d8..1d123bc0a 100644 --- a/source/Blocks/BlockCactus.h +++ b/source/Blocks/BlockCactus.h @@ -1,88 +1,88 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockCactusHandler : - public cBlockHandler -{ -public: - cBlockCactusHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - // Reset meta to 0 - a_Pickups.push_back(cItem(m_BlockType, 1, 0)); - } - - - virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override - { - if (a_RelY <= 0) - { - return false; - } - BLOCKTYPE Surface = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ); - if ((Surface != E_BLOCK_SAND) && (Surface != E_BLOCK_CACTUS)) - { - // Cactus can only be placed on sand and itself - return false; - } - - // Check surroundings. Cacti may ONLY be surrounded by air - static const struct - { - int x, z; - } Coords[] = - { - {-1, 0}, - { 1, 0}, - { 0, -1}, - { 0, 1}, - } ; - for (int i = 0; i < ARRAYCOUNT(Coords); i++) - { - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - if ( - a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta) && - (BlockType != E_BLOCK_AIR) - ) - { - return false; - } - } // for i - Coords[] - - return true; - } - - - virtual bool CanBePlacedOnSide(void) override - { - return false; - } - - - void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override - { - a_World->GrowCactus(a_BlockX, a_BlockY, a_BlockZ, 1); - } - - - virtual const char * GetStepSound(void) override - { - return "step.cloth"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockCactusHandler : + public cBlockHandler +{ +public: + cBlockCactusHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Reset meta to 0 + a_Pickups.push_back(cItem(m_BlockType, 1, 0)); + } + + + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override + { + if (a_RelY <= 0) + { + return false; + } + BLOCKTYPE Surface = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ); + if ((Surface != E_BLOCK_SAND) && (Surface != E_BLOCK_CACTUS)) + { + // Cactus can only be placed on sand and itself + return false; + } + + // Check surroundings. Cacti may ONLY be surrounded by air + static const struct + { + int x, z; + } Coords[] = + { + {-1, 0}, + { 1, 0}, + { 0, -1}, + { 0, 1}, + } ; + for (int i = 0; i < ARRAYCOUNT(Coords); i++) + { + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + if ( + a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta) && + (BlockType != E_BLOCK_AIR) + ) + { + return false; + } + } // for i - Coords[] + + return true; + } + + + virtual bool CanBePlacedOnSide(void) override + { + return false; + } + + + void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + a_World->GrowCactus(a_BlockX, a_BlockY, a_BlockZ, 1); + } + + + virtual const char * GetStepSound(void) override + { + return "step.cloth"; + } +} ; + + + + diff --git a/source/Blocks/BlockCauldron.h b/source/Blocks/BlockCauldron.h index 571235441..b0e00f869 100644 --- a/source/Blocks/BlockCauldron.h +++ b/source/Blocks/BlockCauldron.h @@ -1,59 +1,59 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockCauldronHandler : - public cBlockHandler -{ -public: - cBlockCauldronHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - 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) - { - char Meta = a_World->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); - break; - } - case E_ITEM_GLASS_BOTTLE: - { - if( Meta > 0 ) - { - a_World->SetBlockMeta( a_BlockX, a_BlockY, a_BlockZ, --Meta); - a_Player->GetInventory().RemoveOneEquippedItem(); - cItem NewItem(E_ITEM_POTIONS, 1, 0); - a_Player->GetInventory().AddItem(NewItem); - } - break; - } - } - } - - virtual bool IsUseable() override - { - return true; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockCauldronHandler : + public cBlockHandler +{ +public: + cBlockCauldronHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + 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) + { + char Meta = a_World->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); + break; + } + case E_ITEM_GLASS_BOTTLE: + { + if( Meta > 0 ) + { + a_World->SetBlockMeta( a_BlockX, a_BlockY, a_BlockZ, --Meta); + a_Player->GetInventory().RemoveOneEquippedItem(); + cItem NewItem(E_ITEM_POTIONS, 1, 0); + a_Player->GetInventory().AddItem(NewItem); + } + break; + } + } + } + + virtual bool IsUseable() override + { + return true; + } +} ; + + + + diff --git a/source/Blocks/BlockChest.h b/source/Blocks/BlockChest.h index 5a64a16bb..1975e11b2 100644 --- a/source/Blocks/BlockChest.h +++ b/source/Blocks/BlockChest.h @@ -1,222 +1,222 @@ - -#pragma once - -#include "BlockEntity.h" -#include "../World.h" -#include "../Player.h" - - - - - -class cBlockChestHandler : - public cBlockEntityHandler -{ -public: - cBlockChestHandler(BLOCKTYPE a_BlockType) - : cBlockEntityHandler(a_BlockType) - { - } - - - virtual bool GetPlacementBlockTypeMeta( - 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 - { - a_BlockType = m_BlockType; - - // Is there a doublechest already next to this block? - if (!CanBeAt(a_World, a_BlockX, a_BlockY, a_BlockZ)) - { - // Yup, cannot form a triple-chest, refuse: - return false; - } - - // 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)) - { - return false; - } - double rot = a_Player->GetRotation(); - if ( - (Area.GetRelBlockType(0, 0, 1) == E_BLOCK_CHEST) || - (Area.GetRelBlockType(2, 0, 1) == E_BLOCK_CHEST) - ) - { - a_BlockMeta = ((rot >= -90) && (rot < 90)) ? 2 : 3; - return true; - } - if ( - (Area.GetRelBlockType(0, 0, 1) == E_BLOCK_CHEST) || - (Area.GetRelBlockType(2, 0, 1) == E_BLOCK_CHEST) - ) - { - a_BlockMeta = (rot < 0) ? 4 : 5; - return true; - } - - // Single chest, get meta from rotation only - a_BlockMeta = RotationToMetaData(rot); - return true; - } - - - 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 - { - // 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)) - { - return; - } - - double rot = a_Player->GetRotation(); - // 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) - ) - { - // Forming a double chest in the X direction - return; - } - // 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) - ) - { - // Forming a double chest in the Z direction - return; - } - - // Single chest, no further processing needed - } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } - - - virtual bool CanBeAt(cWorld * a_World, 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)) - { - // Cannot read the surroundings, probably at the edge of loaded chunks. Disallow. - return false; - } - - int NumChestNeighbors = 0; - if (Area.GetRelBlockType(1, 0, 2) == E_BLOCK_CHEST) - { - if ( - (Area.GetRelBlockType(0, 0, 2) == E_BLOCK_CHEST) || - (Area.GetRelBlockType(1, 0, 1) == E_BLOCK_CHEST) || - (Area.GetRelBlockType(1, 0, 3) == E_BLOCK_CHEST) - ) - { - // Already a doublechest neighbor, disallow: - return false; - } - NumChestNeighbors += 1; - } - if (Area.GetRelBlockType(3, 0, 2) == E_BLOCK_CHEST) - { - if ( - (Area.GetRelBlockType(4, 0, 2) == E_BLOCK_CHEST) || - (Area.GetRelBlockType(3, 0, 1) == E_BLOCK_CHEST) || - (Area.GetRelBlockType(3, 0, 3) == E_BLOCK_CHEST) - ) - { - // Already a doublechest neighbor, disallow: - return false; - } - NumChestNeighbors += 1; - } - if (Area.GetRelBlockType(2, 0, 1) == E_BLOCK_CHEST) - { - if ( - (Area.GetRelBlockType(2, 0, 0) == E_BLOCK_CHEST) || - (Area.GetRelBlockType(1, 0, 1) == E_BLOCK_CHEST) || - (Area.GetRelBlockType(3, 0, 1) == E_BLOCK_CHEST) - ) - { - // Already a doublechest neighbor, disallow: - return false; - } - NumChestNeighbors += 1; - } - if (Area.GetRelBlockType(2, 0, 3) == E_BLOCK_CHEST) - { - if ( - (Area.GetRelBlockType(2, 0, 4) == E_BLOCK_CHEST) || - (Area.GetRelBlockType(1, 0, 3) == E_BLOCK_CHEST) || - (Area.GetRelBlockType(3, 0, 3) == E_BLOCK_CHEST) - ) - { - // Already a doublechest neighbor, disallow: - return false; - } - NumChestNeighbors += 1; - } - return (NumChestNeighbors < 2); - } - - - /// Translates player rotation when placing a chest into the chest block metadata. Valid for single chests only - static NIBBLETYPE RotationToMetaData(double a_Rotation) - { - a_Rotation += 90 + 45; // So its not aligned with axis - - if (a_Rotation > 360.f) - { - a_Rotation -= 360.f; - } - if ((a_Rotation >= 0.f) && (a_Rotation < 90.f)) - { - return 0x4; - } - else if ((a_Rotation >= 180) && (a_Rotation < 270)) - { - return 0x5; - } - else if ((a_Rotation >= 90) && (a_Rotation < 180)) - { - return 0x2; - } - else - { - return 0x3; - } - } - - - /// 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) - { - 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); - return true; - } -} ; - - - - + +#pragma once + +#include "BlockEntity.h" +#include "../World.h" +#include "../Player.h" + + + + + +class cBlockChestHandler : + public cBlockEntityHandler +{ +public: + cBlockChestHandler(BLOCKTYPE a_BlockType) + : cBlockEntityHandler(a_BlockType) + { + } + + + virtual bool GetPlacementBlockTypeMeta( + 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 + { + a_BlockType = m_BlockType; + + // Is there a doublechest already next to this block? + if (!CanBeAt(a_World, a_BlockX, a_BlockY, a_BlockZ)) + { + // Yup, cannot form a triple-chest, refuse: + return false; + } + + // 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)) + { + return false; + } + double rot = a_Player->GetRotation(); + if ( + (Area.GetRelBlockType(0, 0, 1) == E_BLOCK_CHEST) || + (Area.GetRelBlockType(2, 0, 1) == E_BLOCK_CHEST) + ) + { + a_BlockMeta = ((rot >= -90) && (rot < 90)) ? 2 : 3; + return true; + } + if ( + (Area.GetRelBlockType(0, 0, 1) == E_BLOCK_CHEST) || + (Area.GetRelBlockType(2, 0, 1) == E_BLOCK_CHEST) + ) + { + a_BlockMeta = (rot < 0) ? 4 : 5; + return true; + } + + // Single chest, get meta from rotation only + a_BlockMeta = RotationToMetaData(rot); + return true; + } + + + 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 + { + // 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)) + { + return; + } + + double rot = a_Player->GetRotation(); + // 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) + ) + { + // Forming a double chest in the X direction + return; + } + // 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) + ) + { + // Forming a double chest in the Z direction + return; + } + + // Single chest, no further processing needed + } + + + virtual const char * GetStepSound(void) override + { + return "step.wood"; + } + + + virtual bool CanBeAt(cWorld * a_World, 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)) + { + // Cannot read the surroundings, probably at the edge of loaded chunks. Disallow. + return false; + } + + int NumChestNeighbors = 0; + if (Area.GetRelBlockType(1, 0, 2) == E_BLOCK_CHEST) + { + if ( + (Area.GetRelBlockType(0, 0, 2) == E_BLOCK_CHEST) || + (Area.GetRelBlockType(1, 0, 1) == E_BLOCK_CHEST) || + (Area.GetRelBlockType(1, 0, 3) == E_BLOCK_CHEST) + ) + { + // Already a doublechest neighbor, disallow: + return false; + } + NumChestNeighbors += 1; + } + if (Area.GetRelBlockType(3, 0, 2) == E_BLOCK_CHEST) + { + if ( + (Area.GetRelBlockType(4, 0, 2) == E_BLOCK_CHEST) || + (Area.GetRelBlockType(3, 0, 1) == E_BLOCK_CHEST) || + (Area.GetRelBlockType(3, 0, 3) == E_BLOCK_CHEST) + ) + { + // Already a doublechest neighbor, disallow: + return false; + } + NumChestNeighbors += 1; + } + if (Area.GetRelBlockType(2, 0, 1) == E_BLOCK_CHEST) + { + if ( + (Area.GetRelBlockType(2, 0, 0) == E_BLOCK_CHEST) || + (Area.GetRelBlockType(1, 0, 1) == E_BLOCK_CHEST) || + (Area.GetRelBlockType(3, 0, 1) == E_BLOCK_CHEST) + ) + { + // Already a doublechest neighbor, disallow: + return false; + } + NumChestNeighbors += 1; + } + if (Area.GetRelBlockType(2, 0, 3) == E_BLOCK_CHEST) + { + if ( + (Area.GetRelBlockType(2, 0, 4) == E_BLOCK_CHEST) || + (Area.GetRelBlockType(1, 0, 3) == E_BLOCK_CHEST) || + (Area.GetRelBlockType(3, 0, 3) == E_BLOCK_CHEST) + ) + { + // Already a doublechest neighbor, disallow: + return false; + } + NumChestNeighbors += 1; + } + return (NumChestNeighbors < 2); + } + + + /// Translates player rotation when placing a chest into the chest block metadata. Valid for single chests only + static NIBBLETYPE RotationToMetaData(double a_Rotation) + { + a_Rotation += 90 + 45; // So its not aligned with axis + + if (a_Rotation > 360.f) + { + a_Rotation -= 360.f; + } + if ((a_Rotation >= 0.f) && (a_Rotation < 90.f)) + { + return 0x4; + } + else if ((a_Rotation >= 180) && (a_Rotation < 270)) + { + return 0x5; + } + else if ((a_Rotation >= 90) && (a_Rotation < 180)) + { + return 0x2; + } + else + { + return 0x3; + } + } + + + /// 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) + { + 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); + return true; + } +} ; + + + + diff --git a/source/Blocks/BlockCloth.h b/source/Blocks/BlockCloth.h index a95f12500..a136d3b9d 100644 --- a/source/Blocks/BlockCloth.h +++ b/source/Blocks/BlockCloth.h @@ -1,34 +1,34 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockClothHandler : - public cBlockHandler -{ -public: - cBlockClothHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - a_Pickups.push_back(cItem(E_BLOCK_WOOL, 1, a_BlockMeta)); - } - - - virtual const char * GetStepSound(void) override - { - return "step.cloth"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockClothHandler : + public cBlockHandler +{ +public: + cBlockClothHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem(E_BLOCK_WOOL, 1, a_BlockMeta)); + } + + + virtual const char * GetStepSound(void) override + { + return "step.cloth"; + } +} ; + + + + diff --git a/source/Blocks/BlockCobWeb.h b/source/Blocks/BlockCobWeb.h index 86bb6e773..982bfaa30 100644 --- a/source/Blocks/BlockCobWeb.h +++ b/source/Blocks/BlockCobWeb.h @@ -1,30 +1,30 @@ - -// BlockCobWeb.h - -// Declares the cBlockCobWebHandler object representing the BlockHandler for cobwebs - -#pragma once - - - - - -class cBlockCobWebHandler : - public cBlockHandler -{ -public: - cBlockCobWebHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_Meta) override - { - a_Pickups.push_back(cItem(E_ITEM_STRING, 1, 0)); - } -} ; - - - - + +// BlockCobWeb.h + +// Declares the cBlockCobWebHandler object representing the BlockHandler for cobwebs + +#pragma once + + + + + +class cBlockCobWebHandler : + public cBlockHandler +{ +public: + cBlockCobWebHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_Meta) override + { + a_Pickups.push_back(cItem(E_ITEM_STRING, 1, 0)); + } +} ; + + + + diff --git a/source/Blocks/BlockCrops.h b/source/Blocks/BlockCrops.h index 7658d2633..4bc76fd50 100644 --- a/source/Blocks/BlockCrops.h +++ b/source/Blocks/BlockCrops.h @@ -1,108 +1,108 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../MersenneTwister.h" -#include "../World.h" - - - - - -/// Common class that takes care of carrots, potatoes and wheat -class cBlockCropsHandler : - public cBlockHandler -{ -public: - cBlockCropsHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual bool DoesAllowBlockOnTop() override - { - return false; - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_Meta) override - { - MTRand rand; - - if (a_Meta == 0x7) - { - // Is fully grown, drop the entire produce: - switch (m_BlockType) - { - 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 - 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 - 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) - { - // With a 5% chance, drop a poisonous potato as well - a_Pickups.push_back(cItem(E_ITEM_POISONOUS_POTATO, 1, 0)); - } - break; - } - default: - { - ASSERT(!"Unhandled block type"); - break; - } - } // switch (m_BlockType) - } - else - { - // Drop 1 item of whatever is growing - switch (m_BlockType) - { - case E_BLOCK_CROPS: a_Pickups.push_back(cItem(E_ITEM_SEEDS, 1, 0)); break; - case E_BLOCK_CARROTS: a_Pickups.push_back(cItem(E_ITEM_CARROT, 1, 0)); break; - case E_BLOCK_POTATOES: a_Pickups.push_back(cItem(E_ITEM_POTATO, 1, 0)); break; - default: - { - ASSERT(!"Unhandled block type"); - break; - } - } - } - } - - - void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override - { - NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - if (Meta < 7) - { - a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_CROPS, ++Meta); - } - } - - - virtual bool CanBeAt(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)); - } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../MersenneTwister.h" +#include "../World.h" + + + + + +/// Common class that takes care of carrots, potatoes and wheat +class cBlockCropsHandler : + public cBlockHandler +{ +public: + cBlockCropsHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual bool DoesAllowBlockOnTop() override + { + return false; + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_Meta) override + { + MTRand rand; + + if (a_Meta == 0x7) + { + // Is fully grown, drop the entire produce: + switch (m_BlockType) + { + 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 + 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 + 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) + { + // With a 5% chance, drop a poisonous potato as well + a_Pickups.push_back(cItem(E_ITEM_POISONOUS_POTATO, 1, 0)); + } + break; + } + default: + { + ASSERT(!"Unhandled block type"); + break; + } + } // switch (m_BlockType) + } + else + { + // Drop 1 item of whatever is growing + switch (m_BlockType) + { + case E_BLOCK_CROPS: a_Pickups.push_back(cItem(E_ITEM_SEEDS, 1, 0)); break; + case E_BLOCK_CARROTS: a_Pickups.push_back(cItem(E_ITEM_CARROT, 1, 0)); break; + case E_BLOCK_POTATOES: a_Pickups.push_back(cItem(E_ITEM_POTATO, 1, 0)); break; + default: + { + ASSERT(!"Unhandled block type"); + break; + } + } + } + } + + + void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + if (Meta < 7) + { + a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_CROPS, ++Meta); + } + } + + + virtual bool CanBeAt(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)); + } + + + virtual const char * GetStepSound(void) override + { + return "step.grass"; + } +} ; + + + + diff --git a/source/Blocks/BlockDeadBush.h b/source/Blocks/BlockDeadBush.h index be0e77e55..379e8e5df 100644 --- a/source/Blocks/BlockDeadBush.h +++ b/source/Blocks/BlockDeadBush.h @@ -1,47 +1,47 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../World.h" - - - - - -class cBlockDeadBushHandler : - public cBlockHandler -{ -public: - cBlockDeadBushHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - // Don't drop anything - } - - - virtual bool CanBeAt(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); - } - - - virtual bool DoesAllowBlockOnTop(void) override - { - return false; - } - - - virtual bool CanBePlacedOnSide() override - { - return false; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../World.h" + + + + + +class cBlockDeadBushHandler : + public cBlockHandler +{ +public: + cBlockDeadBushHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Don't drop anything + } + + + virtual bool CanBeAt(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); + } + + + virtual bool DoesAllowBlockOnTop(void) override + { + return false; + } + + + virtual bool CanBePlacedOnSide() override + { + return false; + } +} ; + + + + diff --git a/source/Blocks/BlockDirt.h b/source/Blocks/BlockDirt.h index 6cec5d99e..b2bc4756c 100644 --- a/source/Blocks/BlockDirt.h +++ b/source/Blocks/BlockDirt.h @@ -1,88 +1,88 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../MersenneTwister.h" -#include "../World.h" - - - - - -/// Handler used for both dirt and grass -class cBlockDirtHandler : - public cBlockHandler -{ -public: - cBlockDirtHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - a_Pickups.push_back(cItem(E_BLOCK_DIRT, 1, 0)); - } - - - virtual void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override - { - if (m_BlockType != E_BLOCK_GRASS) - { - return; - } - - // Grass becomes dirt if there is something on top of it: - if (a_BlockY < cChunkDef::Height - 1) - { - BLOCKTYPE Above = a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ); - if (!g_BlockTransparent[Above] && !g_BlockOneHitDig[Above]) - { - a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_DIRT, 0); - return; - } - } - - // Grass spreads to adjacent blocks: - MTRand 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] - - BLOCKTYPE DestBlock; - NIBBLETYPE DestMeta; - if ((a_BlockY + OfsY < 0) || (a_BlockY + OfsY >= cChunkDef::Height - 1)) - { - // Y Coord out of range - continue; - } - bool IsValid = a_World->GetBlockTypeMeta(a_BlockX + OfsX, a_BlockY + OfsY, a_BlockZ + OfsZ, DestBlock, DestMeta); - if (!IsValid || (DestBlock != E_BLOCK_DIRT)) - { - continue; - } - - BLOCKTYPE AboveDest; - NIBBLETYPE AboveMeta; - IsValid = a_World->GetBlockTypeMeta(a_BlockX + OfsX, a_BlockY + OfsY + 1, a_BlockZ + OfsZ, AboveDest, AboveMeta); - ASSERT(IsValid); // WTF - how did we get the DestBlock if AboveBlock is not valid? - if (g_BlockOneHitDig[AboveDest] || g_BlockTransparent[AboveDest]) - { - a_World->FastSetBlock(a_BlockX + OfsX, a_BlockY + OfsY, a_BlockZ + OfsZ, E_BLOCK_GRASS, 0); - } - } // for i - repeat twice - } - - - virtual const char * GetStepSound(void) override - { - return "step.gravel"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../MersenneTwister.h" +#include "../World.h" + + + + + +/// Handler used for both dirt and grass +class cBlockDirtHandler : + public cBlockHandler +{ +public: + cBlockDirtHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem(E_BLOCK_DIRT, 1, 0)); + } + + + virtual void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + if (m_BlockType != E_BLOCK_GRASS) + { + return; + } + + // Grass becomes dirt if there is something on top of it: + if (a_BlockY < cChunkDef::Height - 1) + { + BLOCKTYPE Above = a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ); + if (!g_BlockTransparent[Above] && !g_BlockOneHitDig[Above]) + { + a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_DIRT, 0); + return; + } + } + + // Grass spreads to adjacent blocks: + MTRand 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] + + BLOCKTYPE DestBlock; + NIBBLETYPE DestMeta; + if ((a_BlockY + OfsY < 0) || (a_BlockY + OfsY >= cChunkDef::Height - 1)) + { + // Y Coord out of range + continue; + } + bool IsValid = a_World->GetBlockTypeMeta(a_BlockX + OfsX, a_BlockY + OfsY, a_BlockZ + OfsZ, DestBlock, DestMeta); + if (!IsValid || (DestBlock != E_BLOCK_DIRT)) + { + continue; + } + + BLOCKTYPE AboveDest; + NIBBLETYPE AboveMeta; + IsValid = a_World->GetBlockTypeMeta(a_BlockX + OfsX, a_BlockY + OfsY + 1, a_BlockZ + OfsZ, AboveDest, AboveMeta); + ASSERT(IsValid); // WTF - how did we get the DestBlock if AboveBlock is not valid? + if (g_BlockOneHitDig[AboveDest] || g_BlockTransparent[AboveDest]) + { + a_World->FastSetBlock(a_BlockX + OfsX, a_BlockY + OfsY, a_BlockZ + OfsZ, E_BLOCK_GRASS, 0); + } + } // for i - repeat twice + } + + + virtual const char * GetStepSound(void) override + { + return "step.gravel"; + } +} ; + + + + diff --git a/source/Blocks/BlockDoor.cpp b/source/Blocks/BlockDoor.cpp index 49ce56e07..b2fe273c5 100644 --- a/source/Blocks/BlockDoor.cpp +++ b/source/Blocks/BlockDoor.cpp @@ -1,88 +1,88 @@ - -#include "Globals.h" -#include "BlockDoor.h" -#include "../Item.h" -#include "../World.h" -#include "../Doors.h" -#include "../Player.h" - - - - - -cBlockDoorHandler::cBlockDoorHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) -{ -} - - - - - -void cBlockDoorHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) -{ - NIBBLETYPE OldMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - - if (OldMeta & 8) - { - // Was upper part of door - if (cDoors::IsDoor(a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ))) - { - a_World->FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0); - } - } - else - { - // Was lower part - if (cDoors::IsDoor(a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))) - { - a_World->FastSetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, E_BLOCK_AIR, 0); - } - } -} - - - - - -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) -{ - cDoors::ChangeDoor(a_World, a_BlockX, a_BlockY, a_BlockZ); -} - - - - - -void cBlockDoorHandler::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 -) -{ - 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_TopBlockMeta = 9; - } - a_World->SetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, a_TopBlockMeta); -} - - - - - -const char * cBlockDoorHandler::GetStepSound(void) -{ - return (m_BlockType == E_BLOCK_WOODEN_DOOR) ? "step.wood" : "step.stone"; -} - - - - + +#include "Globals.h" +#include "BlockDoor.h" +#include "../Item.h" +#include "../World.h" +#include "../Doors.h" +#include "../Player.h" + + + + + +cBlockDoorHandler::cBlockDoorHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) +{ +} + + + + + +void cBlockDoorHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + NIBBLETYPE OldMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + + if (OldMeta & 8) + { + // Was upper part of door + if (cDoors::IsDoor(a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ))) + { + a_World->FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0); + } + } + else + { + // Was lower part + if (cDoors::IsDoor(a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))) + { + a_World->FastSetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, E_BLOCK_AIR, 0); + } + } +} + + + + + +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) +{ + cDoors::ChangeDoor(a_World, a_BlockX, a_BlockY, a_BlockZ); +} + + + + + +void cBlockDoorHandler::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 +) +{ + 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_TopBlockMeta = 9; + } + a_World->SetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, a_TopBlockMeta); +} + + + + + +const char * cBlockDoorHandler::GetStepSound(void) +{ + return (m_BlockType == E_BLOCK_WOODEN_DOOR) ? "step.wood" : "step.stone"; +} + + + + diff --git a/source/Blocks/BlockDoor.h b/source/Blocks/BlockDoor.h index a988c2d4b..19701ffc9 100644 --- a/source/Blocks/BlockDoor.h +++ b/source/Blocks/BlockDoor.h @@ -1,105 +1,105 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../World.h" -#include "../Doors.h" -#include "../Player.h" - - - - - -class cBlockDoorHandler : - public cBlockHandler -{ -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 const char * GetStepSound(void) override; - - - virtual bool GetPlacementBlockTypeMeta( - 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 - { - // If clicking a bottom face, place the door one block lower: - if (a_BlockFace == BLOCK_FACE_BOTTOM) - { - a_BlockY--; - } - - if ( - !CanReplaceBlock(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ)) || - !CanReplaceBlock(a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)) - ) - { - return false; - } - - a_BlockType = m_BlockType; - a_BlockMeta = cDoors::RotationToMetaData(a_Player->GetRotation()); - return true; - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - a_Pickups.push_back(cItem((m_BlockType == E_BLOCK_WOODEN_DOOR) ? E_ITEM_WOODEN_DOOR : E_ITEM_IRON_DOOR, 1, 0)); - } - - - 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 bool IsUseable(void) override - { - return true; - } - - - virtual bool CanBePlacedOnSide(void) override - { - return false; - } - - - virtual bool CanBeAt(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)); - } - - - bool CanReplaceBlock(BLOCKTYPE a_BlockType) - { - switch (a_BlockType) - { - case E_BLOCK_AIR: - case E_BLOCK_TALL_GRASS: - case E_BLOCK_WATER: - case E_BLOCK_STATIONARY_WATER: - case E_BLOCK_LAVA: - case E_BLOCK_STATIONARY_LAVA: - case E_BLOCK_SNOW: - case E_BLOCK_FIRE: - { - return true; - } - } - return false; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../World.h" +#include "../Doors.h" +#include "../Player.h" + + + + + +class cBlockDoorHandler : + public cBlockHandler +{ +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 const char * GetStepSound(void) override; + + + virtual bool GetPlacementBlockTypeMeta( + 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 + { + // If clicking a bottom face, place the door one block lower: + if (a_BlockFace == BLOCK_FACE_BOTTOM) + { + a_BlockY--; + } + + if ( + !CanReplaceBlock(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ)) || + !CanReplaceBlock(a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)) + ) + { + return false; + } + + a_BlockType = m_BlockType; + a_BlockMeta = cDoors::RotationToMetaData(a_Player->GetRotation()); + return true; + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem((m_BlockType == E_BLOCK_WOODEN_DOOR) ? E_ITEM_WOODEN_DOOR : E_ITEM_IRON_DOOR, 1, 0)); + } + + + 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 bool IsUseable(void) override + { + return true; + } + + + virtual bool CanBePlacedOnSide(void) override + { + return false; + } + + + virtual bool CanBeAt(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)); + } + + + bool CanReplaceBlock(BLOCKTYPE a_BlockType) + { + switch (a_BlockType) + { + case E_BLOCK_AIR: + case E_BLOCK_TALL_GRASS: + case E_BLOCK_WATER: + case E_BLOCK_STATIONARY_WATER: + case E_BLOCK_LAVA: + case E_BLOCK_STATIONARY_LAVA: + case E_BLOCK_SNOW: + case E_BLOCK_FIRE: + { + return true; + } + } + return false; + } +} ; + + + + diff --git a/source/Blocks/BlockDropSpenser.h b/source/Blocks/BlockDropSpenser.h index bcc75758d..cfb607a7b 100644 --- a/source/Blocks/BlockDropSpenser.h +++ b/source/Blocks/BlockDropSpenser.h @@ -1,39 +1,39 @@ - -// BlockDropSpenser.h - -// Declares the cBlockDropSpenserHandler class representing the BlockHandler for Dropper and Dispenser blocks - -#pragma once - - - - - -class cBlockDropSpenserHandler : - public cBlockEntityHandler -{ -public: - cBlockDropSpenserHandler(BLOCKTYPE a_BlockType) : - cBlockEntityHandler(a_BlockType) - { - } - - - virtual bool GetPlacementBlockTypeMeta( - 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 - { - a_BlockType = m_BlockType; - - // FIXME: Do not use cPiston class for dispenser placement! - a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0); - return true; - } -} ; - - - - + +// BlockDropSpenser.h + +// Declares the cBlockDropSpenserHandler class representing the BlockHandler for Dropper and Dispenser blocks + +#pragma once + + + + + +class cBlockDropSpenserHandler : + public cBlockEntityHandler +{ +public: + cBlockDropSpenserHandler(BLOCKTYPE a_BlockType) : + cBlockEntityHandler(a_BlockType) + { + } + + + virtual bool GetPlacementBlockTypeMeta( + 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 + { + a_BlockType = m_BlockType; + + // FIXME: Do not use cPiston class for dispenser placement! + a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0); + return true; + } +} ; + + + + diff --git a/source/Blocks/BlockEnderchest.h b/source/Blocks/BlockEnderchest.h index b40deb1f7..0ce813f1c 100644 --- a/source/Blocks/BlockEnderchest.h +++ b/source/Blocks/BlockEnderchest.h @@ -1,28 +1,28 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockEnderchestHandler : - public cBlockHandler -{ -public: - cBlockEnderchestHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - //todo: Drop Ender Chest if using silk touch pickaxe - a_Pickups.push_back(cItem(E_BLOCK_OBSIDIAN, 8, 0)); - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockEnderchestHandler : + public cBlockHandler +{ +public: + cBlockEnderchestHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + //todo: Drop Ender Chest if using silk touch pickaxe + a_Pickups.push_back(cItem(E_BLOCK_OBSIDIAN, 8, 0)); + } +} ; + + + + diff --git a/source/Blocks/BlockEntity.h b/source/Blocks/BlockEntity.h index 8b82b43a6..9c6b23665 100644 --- a/source/Blocks/BlockEntity.h +++ b/source/Blocks/BlockEntity.h @@ -1,31 +1,31 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockEntityHandler : public cBlockHandler -{ -public: - cBlockEntityHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(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 - { - a_World->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); - } - - virtual bool IsUseable() override - { - return true; - } -}; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockEntityHandler : public cBlockHandler +{ +public: + cBlockEntityHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(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 + { + a_World->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); + } + + virtual bool IsUseable() override + { + return true; + } +}; + + + + diff --git a/source/Blocks/BlockFarmland.h b/source/Blocks/BlockFarmland.h index fb2d91a86..6cab1fa38 100644 --- a/source/Blocks/BlockFarmland.h +++ b/source/Blocks/BlockFarmland.h @@ -1,99 +1,99 @@ - -// BlockFarmland.h - -// Declares the cBlcokFarmlandHandler representing the block handler for farmland - - - - - -#pragma once - -#include "BlockHandler.h" -#include "../BlockArea.h" - - - - - -class cBlockFarmlandHandler : - public cBlockHandler -{ - typedef cBlockHandler super; - -public: - cBlockFarmlandHandler(void) : - super(E_BLOCK_FARMLAND) - { - } - - - virtual void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override - { - // TODO: Rain hydrates farmland, too. Check world weather, don't search for water if raining. - // NOTE: The desert biomes do not get precipitation, so another check needs to be made. - - // Search for water in a close proximity: - // Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles - cBlockArea Area; - if (!Area.Read(a_World, a_BlockX - 4, a_BlockX + 4, a_BlockY, a_BlockY + 1, a_BlockZ - 4, a_BlockZ + 4)) - { - // Too close to the world edge, cannot check surroudnings; don't tick at all - return; - } - bool Found = false; - int NumBlocks = Area.GetBlockCount(); - BLOCKTYPE * BlockTypes = Area.GetBlockTypes(); - for (int i = 0; i < NumBlocks; i++) - { - if ( - (BlockTypes[i] == E_BLOCK_WATER) || - (BlockTypes[i] == E_BLOCK_STATIONARY_WATER) - ) - { - Found = true; - break; - } - } - - NIBBLETYPE BlockMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - - if (Found) - { - // Water was found, hydrate the block until hydration reaches 7: - if (BlockMeta < 7) - { - a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, ++BlockMeta); - } - return; - } - - // Water wasn't found, de-hydrate block: - if (BlockMeta > 0) - { - a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FARMLAND, --BlockMeta); - return; - } - - // Farmland too dry. If nothing is growing on top, turn back to dirt: - switch (a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)) - { - case E_BLOCK_CROPS: - case E_BLOCK_MELON_STEM: - case E_BLOCK_PUMPKIN_STEM: - { - // Produce on top, don't revert - break; - } - default: - { - a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_DIRT, 0); - break; - } - } - } -} ; - - - - + +// BlockFarmland.h + +// Declares the cBlcokFarmlandHandler representing the block handler for farmland + + + + + +#pragma once + +#include "BlockHandler.h" +#include "../BlockArea.h" + + + + + +class cBlockFarmlandHandler : + public cBlockHandler +{ + typedef cBlockHandler super; + +public: + cBlockFarmlandHandler(void) : + super(E_BLOCK_FARMLAND) + { + } + + + virtual void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + // TODO: Rain hydrates farmland, too. Check world weather, don't search for water if raining. + // NOTE: The desert biomes do not get precipitation, so another check needs to be made. + + // Search for water in a close proximity: + // Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles + cBlockArea Area; + if (!Area.Read(a_World, a_BlockX - 4, a_BlockX + 4, a_BlockY, a_BlockY + 1, a_BlockZ - 4, a_BlockZ + 4)) + { + // Too close to the world edge, cannot check surroudnings; don't tick at all + return; + } + bool Found = false; + int NumBlocks = Area.GetBlockCount(); + BLOCKTYPE * BlockTypes = Area.GetBlockTypes(); + for (int i = 0; i < NumBlocks; i++) + { + if ( + (BlockTypes[i] == E_BLOCK_WATER) || + (BlockTypes[i] == E_BLOCK_STATIONARY_WATER) + ) + { + Found = true; + break; + } + } + + NIBBLETYPE BlockMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + + if (Found) + { + // Water was found, hydrate the block until hydration reaches 7: + if (BlockMeta < 7) + { + a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, ++BlockMeta); + } + return; + } + + // Water wasn't found, de-hydrate block: + if (BlockMeta > 0) + { + a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FARMLAND, --BlockMeta); + return; + } + + // Farmland too dry. If nothing is growing on top, turn back to dirt: + switch (a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)) + { + case E_BLOCK_CROPS: + case E_BLOCK_MELON_STEM: + case E_BLOCK_PUMPKIN_STEM: + { + // Produce on top, don't revert + break; + } + default: + { + a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_DIRT, 0); + break; + } + } + } +} ; + + + + diff --git a/source/Blocks/BlockFenceGate.h b/source/Blocks/BlockFenceGate.h index a84ce8303..d6f8aa85f 100644 --- a/source/Blocks/BlockFenceGate.h +++ b/source/Blocks/BlockFenceGate.h @@ -1,60 +1,60 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../Doors.h" - - - - - -class cBlockFenceGateHandler : - public cBlockHandler -{ -public: - cBlockFenceGateHandler(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, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override - { - a_BlockType = m_BlockType; - a_BlockMeta = cDoors::RotationToMetaData(a_Player->GetRotation() + 270); - 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 - { - NIBBLETYPE OldMetaData = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - NIBBLETYPE NewMetaData = cDoors::RotationToMetaData(a_Player->GetRotation() + 270); - 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)); - } - else - { - // Standing aside - use last direction - a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, OldMetaData); - } - } - - - virtual bool IsUseable(void) override - { - return true; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../Doors.h" + + + + + +class cBlockFenceGateHandler : + public cBlockHandler +{ +public: + cBlockFenceGateHandler(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, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + a_BlockType = m_BlockType; + a_BlockMeta = cDoors::RotationToMetaData(a_Player->GetRotation() + 270); + 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 + { + NIBBLETYPE OldMetaData = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + NIBBLETYPE NewMetaData = cDoors::RotationToMetaData(a_Player->GetRotation() + 270); + 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)); + } + else + { + // Standing aside - use last direction + a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, OldMetaData); + } + } + + + virtual bool IsUseable(void) override + { + return true; + } +} ; + + + + diff --git a/source/Blocks/BlockFire.h b/source/Blocks/BlockFire.h index 7da66f982..d3ba499b1 100644 --- a/source/Blocks/BlockFire.h +++ b/source/Blocks/BlockFire.h @@ -1,42 +1,42 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockFireHandler : - public cBlockHandler -{ -public: - cBlockFireHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override - { - a_World->DigBlock(a_BlockX, a_BlockY, a_BlockZ); - } - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - // No pickups from this block - } - - virtual bool IsClickedThrough(void) override - { - return true; - } - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockFireHandler : + public cBlockHandler +{ +public: + cBlockFireHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + a_World->DigBlock(a_BlockX, a_BlockY, a_BlockZ); + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // No pickups from this block + } + + virtual bool IsClickedThrough(void) override + { + return true; + } + + virtual const char * GetStepSound(void) override + { + return "step.wood"; + } +} ; + + + + diff --git a/source/Blocks/BlockFlower.h b/source/Blocks/BlockFlower.h index b46273c51..202609538 100644 --- a/source/Blocks/BlockFlower.h +++ b/source/Blocks/BlockFlower.h @@ -1,53 +1,53 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockFlowerHandler : - public cBlockHandler -{ -public: - cBlockFlowerHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - // Reset meta to 0 - a_Pickups.push_back(cItem(m_BlockType, 1, 0)); - } - - - virtual bool CanBeAt(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)); - } - - - virtual bool DoesAllowBlockOnTop(void) override - { - return false; - } - - - virtual bool CanBePlacedOnSide(void) override - { - return false; - } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockFlowerHandler : + public cBlockHandler +{ +public: + cBlockFlowerHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Reset meta to 0 + a_Pickups.push_back(cItem(m_BlockType, 1, 0)); + } + + + virtual bool CanBeAt(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)); + } + + + virtual bool DoesAllowBlockOnTop(void) override + { + return false; + } + + + virtual bool CanBePlacedOnSide(void) override + { + return false; + } + + + virtual const char * GetStepSound(void) override + { + return "step.grass"; + } +} ; + + + + diff --git a/source/Blocks/BlockFlowerPot.h b/source/Blocks/BlockFlowerPot.h index 12cd594de..b0faf5218 100644 --- a/source/Blocks/BlockFlowerPot.h +++ b/source/Blocks/BlockFlowerPot.h @@ -1,105 +1,105 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockFlowerPotHandler : - public cBlockHandler -{ -public: - cBlockFlowerPotHandler(BLOCKTYPE a_BlockType) : - cBlockHandler(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; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockFlowerPotHandler : + public cBlockHandler +{ +public: + cBlockFlowerPotHandler(BLOCKTYPE a_BlockType) : + cBlockHandler(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/source/Blocks/BlockFluid.h b/source/Blocks/BlockFluid.h index b184a5b33..696bfb3ce 100644 --- a/source/Blocks/BlockFluid.h +++ b/source/Blocks/BlockFluid.h @@ -1,50 +1,50 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockFluidHandler : - public cBlockHandler -{ - typedef cBlockHandler super; - -public: - cBlockFluidHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - - } - - - virtual bool DoesIgnoreBuildCollision(void) override - { - return true; - } - - - virtual void Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) override - { - switch (m_BlockType) - { - case E_BLOCK_STATIONARY_LAVA: - { - a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_LAVA, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); - break; - } - case E_BLOCK_STATIONARY_WATER: - { - a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_WATER, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); - break; - } - } - super::Check(a_RelX, a_RelY, a_RelZ, a_Chunk); - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockFluidHandler : + public cBlockHandler +{ + typedef cBlockHandler super; + +public: + cBlockFluidHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + + } + + + virtual bool DoesIgnoreBuildCollision(void) override + { + return true; + } + + + virtual void Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) override + { + switch (m_BlockType) + { + case E_BLOCK_STATIONARY_LAVA: + { + a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_LAVA, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); + break; + } + case E_BLOCK_STATIONARY_WATER: + { + a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_WATER, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); + break; + } + } + super::Check(a_RelX, a_RelY, a_RelZ, a_Chunk); + } +} ; + + + + diff --git a/source/Blocks/BlockFurnace.h b/source/Blocks/BlockFurnace.h index 7231c4d65..b358a1d71 100644 --- a/source/Blocks/BlockFurnace.h +++ b/source/Blocks/BlockFurnace.h @@ -1,47 +1,47 @@ - -#pragma once - -#include "BlockEntity.h" -#include "../World.h" -#include "../Piston.h" -#include "../Player.h" - - - - - -class cBlockFurnaceHandler : - public cBlockEntityHandler -{ -public: - cBlockFurnaceHandler(BLOCKTYPE a_BlockType) : - cBlockEntityHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - a_Pickups.push_back(cItem(E_BLOCK_FURNACE, 1, 0)); - } - - - virtual bool GetPlacementBlockTypeMeta( - 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 - { - a_BlockType = m_BlockType; - - // FIXME: Do not use cPiston class for furnace placement! - a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0); - - return true; - } -} ; - - - - + +#pragma once + +#include "BlockEntity.h" +#include "../World.h" +#include "../Piston.h" +#include "../Player.h" + + + + + +class cBlockFurnaceHandler : + public cBlockEntityHandler +{ +public: + cBlockFurnaceHandler(BLOCKTYPE a_BlockType) : + cBlockEntityHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem(E_BLOCK_FURNACE, 1, 0)); + } + + + virtual bool GetPlacementBlockTypeMeta( + 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 + { + a_BlockType = m_BlockType; + + // FIXME: Do not use cPiston class for furnace placement! + a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0); + + return true; + } +} ; + + + + diff --git a/source/Blocks/BlockGlass.h b/source/Blocks/BlockGlass.h index d5147af96..f6958bbb6 100644 --- a/source/Blocks/BlockGlass.h +++ b/source/Blocks/BlockGlass.h @@ -1,26 +1,26 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockGlassHandler : - public cBlockHandler -{ -public: - cBlockGlassHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockGlassHandler : + public cBlockHandler +{ +public: + cBlockGlassHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + } +} ; + + + + diff --git a/source/Blocks/BlockGlowstone.h b/source/Blocks/BlockGlowstone.h index 5ff9394b7..5f0d95dee 100644 --- a/source/Blocks/BlockGlowstone.h +++ b/source/Blocks/BlockGlowstone.h @@ -1,30 +1,30 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockGlowstoneHandler : - public cBlockHandler -{ -public: - cBlockGlowstoneHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - // Reset meta to 0 - // TODO: More drops? - a_Pickups.push_back(cItem(E_ITEM_GLOWSTONE_DUST, 1, 0)); - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockGlowstoneHandler : + public cBlockHandler +{ +public: + cBlockGlowstoneHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Reset meta to 0 + // TODO: More drops? + a_Pickups.push_back(cItem(E_ITEM_GLOWSTONE_DUST, 1, 0)); + } +} ; + + + + diff --git a/source/Blocks/BlockGravel.h b/source/Blocks/BlockGravel.h index 6324fe06f..e1c9ff390 100644 --- a/source/Blocks/BlockGravel.h +++ b/source/Blocks/BlockGravel.h @@ -1,27 +1,27 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockGravelHandler : - public cBlockHandler -{ -public: - cBlockGravelHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - virtual const char * GetStepSound(void) override - { - return "step.gravel"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockGravelHandler : + public cBlockHandler +{ +public: + cBlockGravelHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual const char * GetStepSound(void) override + { + return "step.gravel"; + } +} ; + + + + diff --git a/source/Blocks/BlockHandler.cpp b/source/Blocks/BlockHandler.cpp index a853c6f68..550a6795c 100644 --- a/source/Blocks/BlockHandler.cpp +++ b/source/Blocks/BlockHandler.cpp @@ -1,453 +1,453 @@ - -#include "Globals.h" -#include "BlockHandler.h" -#include "../Item.h" -#include "../World.h" -#include "../Root.h" -#include "../PluginManager.h" -#include "BlockSand.h" -#include "BlockGravel.h" -#include "BlockDoor.h" -#include "BlockFire.h" -#include "BlockRedstone.h" -#include "BlockRedstoneTorch.h" -#include "BlockRedstoneRepeater.h" -#include "BlockPiston.h" -#include "BlockWorkbench.h" -#include "BlockEntity.h" -#include "BlockVine.h" -#include "BlockTallGrass.h" -#include "BlockSnow.h" -#include "BlockCloth.h" -#include "BlockSlab.h" -#include "BlockDirt.h" -#include "BlockTorch.h" -#include "BlockWood.h" -#include "BlockLeaves.h" -#include "BlockSapling.h" -#include "BlockFluid.h" -#include "BlockChest.h" -#include "BlockFurnace.h" -#include "BlockDropSpenser.h" -#include "BlockStairs.h" -#include "BlockLadder.h" -#include "BlockLever.h" -#include "BlockSign.h" -#include "BlockCrops.h" -#include "BlockSugarcane.h" -#include "BlockFlower.h" -#include "BlockMushroom.h" -#include "BlockCactus.h" -#include "BlockStems.h" -#include "BlockGlowstone.h" -#include "BlockStone.h" -#include "BlockMelon.h" -#include "BlockIce.h" -#include "BlockOre.h" -#include "BlockNote.h" -#include "BlockBed.h" -#include "BlockFarmland.h" -#include "BlockMycelium.h" -#include "BlockRail.h" -#include "BlockGlass.h" -#include "BlockEnderchest.h" -#include "BlockFenceGate.h" -#include "BlockFlowerPot.h" -#include "BlockCauldron.h" -#include "BlockBrewingStand.h" -#include "BlockCobWeb.h" -#include "BlockDeadBush.h" -#include "BlockHopper.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_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_CARROTS: return new cBlockCropsHandler (a_BlockType); - case E_BLOCK_CAULDRON: return new cBlockCauldronHandler (a_BlockType); - case E_BLOCK_CHEST: return new cBlockChestHandler (a_BlockType); - case E_BLOCK_COAL_ORE: return new cBlockOreHandler (a_BlockType); - case E_BLOCK_COBBLESTONE: return new cBlockStoneHandler (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_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); - case E_BLOCK_DIRT: return new cBlockDirtHandler (a_BlockType); - case E_BLOCK_DISPENSER: return new cBlockDropSpenserHandler (a_BlockType); - case E_BLOCK_DOUBLE_STONE_SLAB: return new cBlockSlabHandler (a_BlockType); - case E_BLOCK_DOUBLE_WOODEN_SLAB: return new cBlockSlabHandler (a_BlockType); - case E_BLOCK_DROPPER: return new cBlockDropSpenserHandler (a_BlockType); - case E_BLOCK_EMERALD_ORE: return new cBlockOreHandler (a_BlockType); - case E_BLOCK_ENDER_CHEST: return new cBlockEnderchestHandler (a_BlockType); - case E_BLOCK_FARMLAND: return new cBlockFarmlandHandler; - case E_BLOCK_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType); - case E_BLOCK_FIRE: return new cBlockFireHandler (a_BlockType); - case E_BLOCK_FLOWER_POT: return new cBlockFlowerPotHandler (a_BlockType); - case E_BLOCK_FURNACE: return new cBlockFurnaceHandler (a_BlockType); - case E_BLOCK_GLOWSTONE: return new cBlockGlowstoneHandler (a_BlockType); - case E_BLOCK_GOLD_ORE: return new cBlockOreHandler (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_HOPPER: return new cBlockHopperHandler (a_BlockType); - case E_BLOCK_ICE: return new cBlockIceHandler (a_BlockType); - case E_BLOCK_IRON_DOOR: return new cBlockDoorHandler (a_BlockType); - case E_BLOCK_IRON_ORE: return new cBlockOreHandler (a_BlockType); - case E_BLOCK_JUKEBOX: return new cBlockEntityHandler (a_BlockType); - case E_BLOCK_JUNGLE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); - case E_BLOCK_LADDER: return new cBlockLadderHandler (a_BlockType); - case E_BLOCK_LEVER: return new cBlockLeverHandler (a_BlockType); - case E_BLOCK_LAPIS_ORE: return new cBlockOreHandler (a_BlockType); - case E_BLOCK_LAVA: return new cBlockFluidHandler (a_BlockType); - case E_BLOCK_LEAVES: return new cBlockLeavesHandler (a_BlockType); - case E_BLOCK_LIT_FURNACE: return new cBlockFurnaceHandler (a_BlockType); - case E_BLOCK_LOG: return new cBlockWoodHandler (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_NOTE_BLOCK: return new cBlockNoteHandler (a_BlockType); - case E_BLOCK_PISTON: return new cBlockPistonHandler (a_BlockType); - case E_BLOCK_PLANKS: return new cBlockWoodHandler (a_BlockType); - case E_BLOCK_PUMPKIN_STEM: return new cBlockStemsHandler (a_BlockType); - case E_BLOCK_RAIL: return new cBlockRailHandler (a_BlockType); - case E_BLOCK_POTATOES: return new cBlockCropsHandler (a_BlockType); - case E_BLOCK_POWERED_RAIL: return new cBlockRailHandler (a_BlockType); - case E_BLOCK_REDSTONE_ORE: return new cBlockOreHandler (a_BlockType); - case E_BLOCK_REDSTONE_ORE_GLOWING: return new cBlockOreHandler (a_BlockType); - case E_BLOCK_REDSTONE_REPEATER_OFF: return new cBlockRedstoneRepeaterHandler(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_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); - case E_BLOCK_SANDSTONE_STAIRS: return new cBlockStairsHandler (a_BlockType); - case E_BLOCK_SAPLING: return new cBlockSaplingHandler (a_BlockType); - case E_BLOCK_SIGN_POST: return new cBlockSignHandler (a_BlockType); - case E_BLOCK_SNOW: return new cBlockSnowHandler (a_BlockType); - case E_BLOCK_SPRUCE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); - case E_BLOCK_STATIONARY_LAVA: return new cBlockFluidHandler (a_BlockType); - case E_BLOCK_STATIONARY_WATER: return new cBlockFluidHandler (a_BlockType); - case E_BLOCK_STICKY_PISTON: return new cBlockPistonHandler (a_BlockType); - case E_BLOCK_STONE: return new cBlockStoneHandler (a_BlockType); - case E_BLOCK_STONE_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType); - case E_BLOCK_STONE_SLAB: return new cBlockSlabHandler (a_BlockType); - case E_BLOCK_SUGARCANE: return new cBlockSugarcaneHandler (a_BlockType); - case E_BLOCK_TALL_GRASS: return new cBlockTallGrassHandler (a_BlockType); - case E_BLOCK_TORCH: return new cBlockTorchHandler (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); - case E_BLOCK_WOODEN_DOOR: return new cBlockDoorHandler (a_BlockType); - case E_BLOCK_WOODEN_SLAB: return new cBlockSlabHandler (a_BlockType); - case E_BLOCK_WOODEN_STAIRS: return new cBlockStairsHandler (a_BlockType); - case E_BLOCK_WOOL: return new cBlockClothHandler (a_BlockType); - case E_BLOCK_WORKBENCH: return new cBlockWorkbenchHandler (a_BlockType); - case E_BLOCK_YELLOW_FLOWER: return new cBlockFlowerHandler (a_BlockType); - - default: return new cBlockHandler(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; -} - - - - - -bool cBlockHandler::GetPlacementBlockTypeMeta( - 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 -) -{ - // By default, all blocks can be placed and the meta is copied over from the item's damage value: - a_BlockType = m_BlockType; - a_BlockMeta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage & 0x0f); - return true; -} - - - - - -void cBlockHandler::OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) -{ -} - - - - - -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::OnDestroyedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) -{ -} - - - - - -void cBlockHandler::OnPlaced(cWorld *a_World, 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); -} - - - - - -void cBlockHandler::OnDestroyed(cWorld *a_World, 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); -} - - - - - -void cBlockHandler::NeighborChanged(cWorld *a_World, 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); - } -} - - - - - -void cBlockHandler::OnNeighborChanged(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) -{ -} - - - - - -void cBlockHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) -{ -} - - - - - -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::ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) -{ - // Setting the meta to a_BlockMeta keeps most textures. The few other blocks have to override this. - a_Pickups.push_back(cItem(m_BlockType, 1, a_BlockMeta)); -} - - - - - -void cBlockHandler::DropBlock(cWorld * a_World, 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); - 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); - - if (!Pickups.empty()) - { - a_World->SpawnItemPickups(Pickups, a_BlockX, a_BlockY, a_BlockZ); - } -} - - - - - -const char * cBlockHandler::GetStepSound() -{ - return "step.stone"; -} - - - - - -bool cBlockHandler::CanBeAt(int a_BlockX, int a_BlockY, int a_BlockZ, const cChunk & a_Chunk) -{ - return true; -} - - - - - -bool cBlockHandler::IsUseable() -{ - return false; -} - - - - - -bool cBlockHandler::IsClickedThrough(void) -{ - return false; -} - - - - - -bool cBlockHandler::DoesIgnoreBuildCollision(void) -{ - return (m_BlockType == E_BLOCK_AIR); -} - - - - - -bool cBlockHandler::DoesAllowBlockOnTop(void) -{ - return true; -} - - - - - -bool cBlockHandler::CanBePlacedOnSide(void) -{ - return true; -} - - - - - -bool cBlockHandler::DoesDropOnUnsuitable(void) -{ - return true; -} - - - - - -void cBlockHandler::Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) -{ - if (!CanBeAt(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); - } - - a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0); - } - else - { - // Wake up the simulators for this block: - int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; - int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; - a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp(BlockX, a_RelY, BlockZ, &a_Chunk); - } -} - - - - + +#include "Globals.h" +#include "BlockHandler.h" +#include "../Item.h" +#include "../World.h" +#include "../Root.h" +#include "../PluginManager.h" +#include "BlockSand.h" +#include "BlockGravel.h" +#include "BlockDoor.h" +#include "BlockFire.h" +#include "BlockRedstone.h" +#include "BlockRedstoneTorch.h" +#include "BlockRedstoneRepeater.h" +#include "BlockPiston.h" +#include "BlockWorkbench.h" +#include "BlockEntity.h" +#include "BlockVine.h" +#include "BlockTallGrass.h" +#include "BlockSnow.h" +#include "BlockCloth.h" +#include "BlockSlab.h" +#include "BlockDirt.h" +#include "BlockTorch.h" +#include "BlockWood.h" +#include "BlockLeaves.h" +#include "BlockSapling.h" +#include "BlockFluid.h" +#include "BlockChest.h" +#include "BlockFurnace.h" +#include "BlockDropSpenser.h" +#include "BlockStairs.h" +#include "BlockLadder.h" +#include "BlockLever.h" +#include "BlockSign.h" +#include "BlockCrops.h" +#include "BlockSugarcane.h" +#include "BlockFlower.h" +#include "BlockMushroom.h" +#include "BlockCactus.h" +#include "BlockStems.h" +#include "BlockGlowstone.h" +#include "BlockStone.h" +#include "BlockMelon.h" +#include "BlockIce.h" +#include "BlockOre.h" +#include "BlockNote.h" +#include "BlockBed.h" +#include "BlockFarmland.h" +#include "BlockMycelium.h" +#include "BlockRail.h" +#include "BlockGlass.h" +#include "BlockEnderchest.h" +#include "BlockFenceGate.h" +#include "BlockFlowerPot.h" +#include "BlockCauldron.h" +#include "BlockBrewingStand.h" +#include "BlockCobWeb.h" +#include "BlockDeadBush.h" +#include "BlockHopper.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_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_CARROTS: return new cBlockCropsHandler (a_BlockType); + case E_BLOCK_CAULDRON: return new cBlockCauldronHandler (a_BlockType); + case E_BLOCK_CHEST: return new cBlockChestHandler (a_BlockType); + case E_BLOCK_COAL_ORE: return new cBlockOreHandler (a_BlockType); + case E_BLOCK_COBBLESTONE: return new cBlockStoneHandler (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_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); + case E_BLOCK_DIRT: return new cBlockDirtHandler (a_BlockType); + case E_BLOCK_DISPENSER: return new cBlockDropSpenserHandler (a_BlockType); + case E_BLOCK_DOUBLE_STONE_SLAB: return new cBlockSlabHandler (a_BlockType); + case E_BLOCK_DOUBLE_WOODEN_SLAB: return new cBlockSlabHandler (a_BlockType); + case E_BLOCK_DROPPER: return new cBlockDropSpenserHandler (a_BlockType); + case E_BLOCK_EMERALD_ORE: return new cBlockOreHandler (a_BlockType); + case E_BLOCK_ENDER_CHEST: return new cBlockEnderchestHandler (a_BlockType); + case E_BLOCK_FARMLAND: return new cBlockFarmlandHandler; + case E_BLOCK_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType); + case E_BLOCK_FIRE: return new cBlockFireHandler (a_BlockType); + case E_BLOCK_FLOWER_POT: return new cBlockFlowerPotHandler (a_BlockType); + case E_BLOCK_FURNACE: return new cBlockFurnaceHandler (a_BlockType); + case E_BLOCK_GLOWSTONE: return new cBlockGlowstoneHandler (a_BlockType); + case E_BLOCK_GOLD_ORE: return new cBlockOreHandler (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_HOPPER: return new cBlockHopperHandler (a_BlockType); + case E_BLOCK_ICE: return new cBlockIceHandler (a_BlockType); + case E_BLOCK_IRON_DOOR: return new cBlockDoorHandler (a_BlockType); + case E_BLOCK_IRON_ORE: return new cBlockOreHandler (a_BlockType); + case E_BLOCK_JUKEBOX: return new cBlockEntityHandler (a_BlockType); + case E_BLOCK_JUNGLE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); + case E_BLOCK_LADDER: return new cBlockLadderHandler (a_BlockType); + case E_BLOCK_LEVER: return new cBlockLeverHandler (a_BlockType); + case E_BLOCK_LAPIS_ORE: return new cBlockOreHandler (a_BlockType); + case E_BLOCK_LAVA: return new cBlockFluidHandler (a_BlockType); + case E_BLOCK_LEAVES: return new cBlockLeavesHandler (a_BlockType); + case E_BLOCK_LIT_FURNACE: return new cBlockFurnaceHandler (a_BlockType); + case E_BLOCK_LOG: return new cBlockWoodHandler (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_NOTE_BLOCK: return new cBlockNoteHandler (a_BlockType); + case E_BLOCK_PISTON: return new cBlockPistonHandler (a_BlockType); + case E_BLOCK_PLANKS: return new cBlockWoodHandler (a_BlockType); + case E_BLOCK_PUMPKIN_STEM: return new cBlockStemsHandler (a_BlockType); + case E_BLOCK_RAIL: return new cBlockRailHandler (a_BlockType); + case E_BLOCK_POTATOES: return new cBlockCropsHandler (a_BlockType); + case E_BLOCK_POWERED_RAIL: return new cBlockRailHandler (a_BlockType); + case E_BLOCK_REDSTONE_ORE: return new cBlockOreHandler (a_BlockType); + case E_BLOCK_REDSTONE_ORE_GLOWING: return new cBlockOreHandler (a_BlockType); + case E_BLOCK_REDSTONE_REPEATER_OFF: return new cBlockRedstoneRepeaterHandler(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_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); + case E_BLOCK_SANDSTONE_STAIRS: return new cBlockStairsHandler (a_BlockType); + case E_BLOCK_SAPLING: return new cBlockSaplingHandler (a_BlockType); + case E_BLOCK_SIGN_POST: return new cBlockSignHandler (a_BlockType); + case E_BLOCK_SNOW: return new cBlockSnowHandler (a_BlockType); + case E_BLOCK_SPRUCE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); + case E_BLOCK_STATIONARY_LAVA: return new cBlockFluidHandler (a_BlockType); + case E_BLOCK_STATIONARY_WATER: return new cBlockFluidHandler (a_BlockType); + case E_BLOCK_STICKY_PISTON: return new cBlockPistonHandler (a_BlockType); + case E_BLOCK_STONE: return new cBlockStoneHandler (a_BlockType); + case E_BLOCK_STONE_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType); + case E_BLOCK_STONE_SLAB: return new cBlockSlabHandler (a_BlockType); + case E_BLOCK_SUGARCANE: return new cBlockSugarcaneHandler (a_BlockType); + case E_BLOCK_TALL_GRASS: return new cBlockTallGrassHandler (a_BlockType); + case E_BLOCK_TORCH: return new cBlockTorchHandler (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); + case E_BLOCK_WOODEN_DOOR: return new cBlockDoorHandler (a_BlockType); + case E_BLOCK_WOODEN_SLAB: return new cBlockSlabHandler (a_BlockType); + case E_BLOCK_WOODEN_STAIRS: return new cBlockStairsHandler (a_BlockType); + case E_BLOCK_WOOL: return new cBlockClothHandler (a_BlockType); + case E_BLOCK_WORKBENCH: return new cBlockWorkbenchHandler (a_BlockType); + case E_BLOCK_YELLOW_FLOWER: return new cBlockFlowerHandler (a_BlockType); + + default: return new cBlockHandler(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; +} + + + + + +bool cBlockHandler::GetPlacementBlockTypeMeta( + 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 +) +{ + // By default, all blocks can be placed and the meta is copied over from the item's damage value: + a_BlockType = m_BlockType; + a_BlockMeta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage & 0x0f); + return true; +} + + + + + +void cBlockHandler::OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +{ +} + + + + + +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::OnDestroyedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) +{ +} + + + + + +void cBlockHandler::OnPlaced(cWorld *a_World, 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); +} + + + + + +void cBlockHandler::OnDestroyed(cWorld *a_World, 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); +} + + + + + +void cBlockHandler::NeighborChanged(cWorld *a_World, 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); + } +} + + + + + +void cBlockHandler::OnNeighborChanged(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +{ +} + + + + + +void cBlockHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) +{ +} + + + + + +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::ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) +{ + // Setting the meta to a_BlockMeta keeps most textures. The few other blocks have to override this. + a_Pickups.push_back(cItem(m_BlockType, 1, a_BlockMeta)); +} + + + + + +void cBlockHandler::DropBlock(cWorld * a_World, 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); + 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); + + if (!Pickups.empty()) + { + a_World->SpawnItemPickups(Pickups, a_BlockX, a_BlockY, a_BlockZ); + } +} + + + + + +const char * cBlockHandler::GetStepSound() +{ + return "step.stone"; +} + + + + + +bool cBlockHandler::CanBeAt(int a_BlockX, int a_BlockY, int a_BlockZ, const cChunk & a_Chunk) +{ + return true; +} + + + + + +bool cBlockHandler::IsUseable() +{ + return false; +} + + + + + +bool cBlockHandler::IsClickedThrough(void) +{ + return false; +} + + + + + +bool cBlockHandler::DoesIgnoreBuildCollision(void) +{ + return (m_BlockType == E_BLOCK_AIR); +} + + + + + +bool cBlockHandler::DoesAllowBlockOnTop(void) +{ + return true; +} + + + + + +bool cBlockHandler::CanBePlacedOnSide(void) +{ + return true; +} + + + + + +bool cBlockHandler::DoesDropOnUnsuitable(void) +{ + return true; +} + + + + + +void cBlockHandler::Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) +{ + if (!CanBeAt(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); + } + + a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0); + } + else + { + // Wake up the simulators for this block: + int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; + int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; + a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp(BlockX, a_RelY, BlockZ, &a_Chunk); + } +} + + + + diff --git a/source/Blocks/BlockHandler.h b/source/Blocks/BlockHandler.h index cb52be497..228ce174b 100644 --- a/source/Blocks/BlockHandler.h +++ b/source/Blocks/BlockHandler.h @@ -1,158 +1,158 @@ - -#pragma once - -#include "../Defines.h" -#include "../Item.h" -#include "../Chunk.h" - - - - - -// fwd: -class cWorld; -class cPlayer; - - - - - -class cBlockHandler -{ -public: - cBlockHandler(BLOCKTYPE a_BlockType); - - /// Called when the block gets ticked either by a random tick or by a queued tick - virtual void OnUpdate(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ); - - /** Called before a block is placed into a world. - The handler should return true to allow placement, false to refuse. - Also, the handler should set a_BlockType and a_BlockMeta to correct values for the newly placed block. - 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, - 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); - - /// 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, - 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); - - /// Called before a block gets destroyed / replaced with air - virtual void OnDestroyed(cWorld * a_World, 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); - - /// 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); - - /// 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); - - /// 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); - - /// Called when the item is mined to convert it into pickups. Pickups may specify multiple items. - 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); - - /// 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); - - /** Checks if the block can be placed at this point. - Default: CanBeAt(...) - NOTE: This call doesn't actually place the block - */ - // virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir); - - /// Called when the player tries to place a block on top of this block (Only if he aims directly on this block); return false to disallow - virtual bool DoesAllowBlockOnTop(void); - - /// Called to check whether this block supports a rclk action. If it returns true, OnUse() is called - virtual bool IsUseable(void); - - /** Indicates whether the client will click through this block. - For example digging a fire will hit the block below the fire so fire is clicked through - */ - virtual bool IsClickedThrough(void); - - /** Checks if the player can build "inside" this block. - For example blocks placed "on" snow will be placed at the same position. So: Snow ignores Build collision - */ - virtual bool DoesIgnoreBuildCollision(void); - - /// Indicates this block can be placed on the side of other blocks. Default: true - virtual bool CanBePlacedOnSide(void); - - /// Does this block drop if it gets destroyed by an unsuitable situation? Default: true - virtual bool DoesDropOnUnsuitable(void); - - /** Called when one of the neighbors gets set; equivalent to MC block update. - 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); - - /// Returns the meta for a block after rotating it counter-clockwise from the specified meta. Default: no change - virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) { return a_Meta; } - - /// Returns the meta for a block after rotating it clockwise from the specified meta. Default: no change - virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) { return a_Meta; } - - /// Returns the meta for a block after mirroring it around the XY plane. Default: no change - virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) { return a_Meta; } - - /// Returns the meta for a block after mirroring it around the XZ plane. Default: no change - virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) { return a_Meta; } - - /// Returns the meta for a block after mirroring it around the YZ plane. Default: no change - virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) { return a_Meta; } - - - /// Get the blockhandler for a specific block id - static cBlockHandler * GetBlockHandler(BLOCKTYPE a_BlockType); - - /// Deletes all initialised block handlers - 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 -}; - - - - - -// Shortcut to get the blockhandler for a specific block -inline cBlockHandler * BlockHandler(BLOCKTYPE a_BlockType) -{ - return cBlockHandler::GetBlockHandler(a_BlockType); -} - - - - + +#pragma once + +#include "../Defines.h" +#include "../Item.h" +#include "../Chunk.h" + + + + + +// fwd: +class cWorld; +class cPlayer; + + + + + +class cBlockHandler +{ +public: + cBlockHandler(BLOCKTYPE a_BlockType); + + /// Called when the block gets ticked either by a random tick or by a queued tick + virtual void OnUpdate(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ); + + /** Called before a block is placed into a world. + The handler should return true to allow placement, false to refuse. + Also, the handler should set a_BlockType and a_BlockMeta to correct values for the newly placed block. + 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, + 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); + + /// 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, + 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); + + /// Called before a block gets destroyed / replaced with air + virtual void OnDestroyed(cWorld * a_World, 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); + + /// 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); + + /// 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); + + /// 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); + + /// Called when the item is mined to convert it into pickups. Pickups may specify multiple items. + 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); + + /// 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); + + /** Checks if the block can be placed at this point. + Default: CanBeAt(...) + NOTE: This call doesn't actually place the block + */ + // virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir); + + /// Called when the player tries to place a block on top of this block (Only if he aims directly on this block); return false to disallow + virtual bool DoesAllowBlockOnTop(void); + + /// Called to check whether this block supports a rclk action. If it returns true, OnUse() is called + virtual bool IsUseable(void); + + /** Indicates whether the client will click through this block. + For example digging a fire will hit the block below the fire so fire is clicked through + */ + virtual bool IsClickedThrough(void); + + /** Checks if the player can build "inside" this block. + For example blocks placed "on" snow will be placed at the same position. So: Snow ignores Build collision + */ + virtual bool DoesIgnoreBuildCollision(void); + + /// Indicates this block can be placed on the side of other blocks. Default: true + virtual bool CanBePlacedOnSide(void); + + /// Does this block drop if it gets destroyed by an unsuitable situation? Default: true + virtual bool DoesDropOnUnsuitable(void); + + /** Called when one of the neighbors gets set; equivalent to MC block update. + 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); + + /// Returns the meta for a block after rotating it counter-clockwise from the specified meta. Default: no change + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) { return a_Meta; } + + /// Returns the meta for a block after rotating it clockwise from the specified meta. Default: no change + virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) { return a_Meta; } + + /// Returns the meta for a block after mirroring it around the XY plane. Default: no change + virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) { return a_Meta; } + + /// Returns the meta for a block after mirroring it around the XZ plane. Default: no change + virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) { return a_Meta; } + + /// Returns the meta for a block after mirroring it around the YZ plane. Default: no change + virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) { return a_Meta; } + + + /// Get the blockhandler for a specific block id + static cBlockHandler * GetBlockHandler(BLOCKTYPE a_BlockType); + + /// Deletes all initialised block handlers + 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 +}; + + + + + +// Shortcut to get the blockhandler for a specific block +inline cBlockHandler * BlockHandler(BLOCKTYPE a_BlockType) +{ + return cBlockHandler::GetBlockHandler(a_BlockType); +} + + + + diff --git a/source/Blocks/BlockHopper.h b/source/Blocks/BlockHopper.h index 10f865564..3998276d7 100644 --- a/source/Blocks/BlockHopper.h +++ b/source/Blocks/BlockHopper.h @@ -1,46 +1,46 @@ - -// BlockHopper.h - -// Declares the cBlockHopperHandler class representing the handler for the Hopper block - - - - - -class cBlockHopperHandler : - public cBlockEntityHandler -{ -public: - cBlockHopperHandler(BLOCKTYPE a_BlockType) - : cBlockEntityHandler(a_BlockType) - { - } - - - virtual bool GetPlacementBlockTypeMeta( - 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 - { - a_BlockType = m_BlockType; - - // Convert the blockface into meta: - switch (a_BlockFace) - { - case BLOCK_FACE_BOTTOM: a_BlockMeta = E_META_HOPPER_FACING_YM; break; - case BLOCK_FACE_TOP: a_BlockMeta = E_META_HOPPER_FACING_YM; break; - case BLOCK_FACE_EAST: a_BlockMeta = E_META_HOPPER_FACING_XM; break; - case BLOCK_FACE_NORTH: a_BlockMeta = E_META_HOPPER_FACING_ZP; break; - case BLOCK_FACE_SOUTH: a_BlockMeta = E_META_HOPPER_FACING_ZM; break; - case BLOCK_FACE_WEST: a_BlockMeta = E_META_HOPPER_FACING_XP; break; - default: a_BlockMeta = E_META_HOPPER_UNATTACHED; break; - } - return true; - } -} ; - - - - + +// BlockHopper.h + +// Declares the cBlockHopperHandler class representing the handler for the Hopper block + + + + + +class cBlockHopperHandler : + public cBlockEntityHandler +{ +public: + cBlockHopperHandler(BLOCKTYPE a_BlockType) + : cBlockEntityHandler(a_BlockType) + { + } + + + virtual bool GetPlacementBlockTypeMeta( + 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 + { + a_BlockType = m_BlockType; + + // Convert the blockface into meta: + switch (a_BlockFace) + { + case BLOCK_FACE_BOTTOM: a_BlockMeta = E_META_HOPPER_FACING_YM; break; + case BLOCK_FACE_TOP: a_BlockMeta = E_META_HOPPER_FACING_YM; break; + case BLOCK_FACE_EAST: a_BlockMeta = E_META_HOPPER_FACING_XM; break; + case BLOCK_FACE_NORTH: a_BlockMeta = E_META_HOPPER_FACING_ZP; break; + case BLOCK_FACE_SOUTH: a_BlockMeta = E_META_HOPPER_FACING_ZM; break; + case BLOCK_FACE_WEST: a_BlockMeta = E_META_HOPPER_FACING_XP; break; + default: a_BlockMeta = E_META_HOPPER_UNATTACHED; break; + } + return true; + } +} ; + + + + diff --git a/source/Blocks/BlockIce.h b/source/Blocks/BlockIce.h index 605a8ae1d..11fe425f3 100644 --- a/source/Blocks/BlockIce.h +++ b/source/Blocks/BlockIce.h @@ -1,37 +1,37 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../World.h" - - - - - -class cBlockIceHandler : - public cBlockHandler -{ -public: - cBlockIceHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - // No pickups - } - - - virtual void OnDestroyed(cWorld * a_World, 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_STATIONARY_WATER, 8); - // This is called later than the real destroying of this ice block - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../World.h" + + + + + +class cBlockIceHandler : + public cBlockHandler +{ +public: + cBlockIceHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // No pickups + } + + + virtual void OnDestroyed(cWorld * a_World, 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_STATIONARY_WATER, 8); + // This is called later than the real destroying of this ice block + } +} ; + + + + diff --git a/source/Blocks/BlockLadder.h b/source/Blocks/BlockLadder.h index 93473f757..c0aa25f60 100644 --- a/source/Blocks/BlockLadder.h +++ b/source/Blocks/BlockLadder.h @@ -1,115 +1,115 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../World.h" - - - - - -class cBlockLadderHandler : - public cBlockHandler -{ -public: - cBlockLadderHandler(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, - 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)) - { - a_BlockFace = FindSuitableBlockFace(a_World, a_BlockX, a_BlockY, a_BlockZ); - - if (a_BlockFace == BLOCK_FACE_BOTTOM) - { - return false; - } - } - - a_BlockType = m_BlockType; - a_BlockMeta = DirectionToMetaData(a_BlockFace); - return true; - } - - - static NIBBLETYPE DirectionToMetaData(char 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; - default: return 0x2; - } - } // tolua_export - - - static char 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; - } - } // 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) - { - for (int Face = 2; Face <= 5; Face++) - { - if (LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Face)) - { - return Face; - } - } - return BLOCK_FACE_BOTTOM; - } - - - static bool LadderCanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) - { - if ((a_BlockFace == BLOCK_FACE_BOTTOM) || (a_BlockFace == BLOCK_FACE_TOP)) - { - return false; - } - - AddFaceDirection( a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); - - return g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ)]; - } - - - virtual bool CanBeAt(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)); - 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); - } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../World.h" + + + + + +class cBlockLadderHandler : + public cBlockHandler +{ +public: + cBlockLadderHandler(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, + 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)) + { + a_BlockFace = FindSuitableBlockFace(a_World, a_BlockX, a_BlockY, a_BlockZ); + + if (a_BlockFace == BLOCK_FACE_BOTTOM) + { + return false; + } + } + + a_BlockType = m_BlockType; + a_BlockMeta = DirectionToMetaData(a_BlockFace); + return true; + } + + + static NIBBLETYPE DirectionToMetaData(char 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; + default: return 0x2; + } + } // tolua_export + + + static char 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; + } + } // 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) + { + for (int Face = 2; Face <= 5; Face++) + { + if (LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Face)) + { + return Face; + } + } + return BLOCK_FACE_BOTTOM; + } + + + static bool LadderCanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) + { + if ((a_BlockFace == BLOCK_FACE_BOTTOM) || (a_BlockFace == BLOCK_FACE_TOP)) + { + return false; + } + + AddFaceDirection( a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); + + return g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ)]; + } + + + virtual bool CanBeAt(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)); + 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); + } + + + virtual const char * GetStepSound(void) override + { + return "step.wood"; + } +} ; + + + + diff --git a/source/Blocks/BlockLeaves.h b/source/Blocks/BlockLeaves.h index 3563babcf..6e015b8fa 100644 --- a/source/Blocks/BlockLeaves.h +++ b/source/Blocks/BlockLeaves.h @@ -1,184 +1,184 @@ -#pragma once -#include "BlockHandler.h" -#include "../MersenneTwister.h" -#include "../World.h" -#include "../BlockArea.h" - - - - - -// Leaves can be this many blocks that away (inclusive) from the log not to decay -#define LEAVES_CHECK_DISTANCE 6 - -#define PROCESS_NEIGHBOR(x,y,z) \ - switch (a_Area.GetBlockType(x, y, z)) \ - { \ - case E_BLOCK_LEAVES: a_Area.SetBlockType(x, y, z, (BLOCKTYPE)(E_BLOCK_SPONGE + i + 1)); break; \ - case E_BLOCK_LOG: return true; \ - } - -bool HasNearLog(cBlockArea &a_Area, int a_BlockX, int a_BlockY, int a_BlockZ); - - - - - -class cBlockLeavesHandler : - public cBlockHandler -{ -public: - cBlockLeavesHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(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)); - } - if ((a_BlockMeta & 3) == E_META_SAPLING_APPLE) - { - if (rand.rand(100) == 0) - { - a_Pickups.push_back(cItem(E_ITEM_RED_APPLE, 1, 0)); - } - } - } - - - void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override - { - cBlockHandler::OnDestroyed(a_World, 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) - { - cItems Drops; - Drops.push_back(cItem(E_ITEM_RED_APPLE, 1, 0)); - a_World->SpawnItemPickups(Drops, a_BlockX, a_BlockY, a_BlockZ); - } - } - - - virtual void OnNeighborChanged(cWorld * a_World, 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 - } - - - virtual void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override - { - NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - if ((Meta & 0x04) != 0) - { - // Player-placed leaves, don't decay - return; - } - - if ((Meta & 0x8) != 0) - { - // These leaves have been checked for decay lately and nothing around them changed - return; - } - - // Get the data around the leaves: - cBlockArea Area; - if (!Area.Read( - a_World, - a_BlockX - LEAVES_CHECK_DISTANCE, a_BlockX + LEAVES_CHECK_DISTANCE, - a_BlockY - LEAVES_CHECK_DISTANCE, a_BlockY + LEAVES_CHECK_DISTANCE, - a_BlockZ - LEAVES_CHECK_DISTANCE, a_BlockZ + LEAVES_CHECK_DISTANCE, - cBlockArea::baTypes) - ) - { - // Cannot check leaves, a chunk is missing too close - return; - } - - if (HasNearLog(Area, a_BlockX, a_BlockY, a_BlockZ)) - { - // Wood found, the leaves stay; mark them as checked: - a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x8); - return; - } - // Decay the leaves: - DropBlock(a_World, NULL, a_BlockX, a_BlockY, a_BlockZ); - - a_World->DigBlock(a_BlockX, a_BlockY, a_BlockZ); - - } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } -} ; - - - - - -bool HasNearLog(cBlockArea & a_Area, int a_BlockX, int a_BlockY, int a_BlockZ) -{ - // Filter the blocks into a {leaves, log, other (air)} set: - BLOCKTYPE * Types = a_Area.GetBlockTypes(); - for (int i = a_Area.GetBlockCount() - 1; i > 0; i--) - { - switch (Types[i]) - { - case E_BLOCK_LEAVES: - case E_BLOCK_LOG: - { - break; - } - default: - { - Types[i] = E_BLOCK_AIR; - break; - } - } - } // for i - Types[] - - // Perform a breadth-first search to see if there's a log connected within 4 blocks of the leaves block: - // Simply replace all reachable leaves blocks with a sponge block plus iteration (in the Area) and see if we can reach a log in 4 iterations - a_Area.SetBlockType(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_SPONGE); - for (int i = 0; i < LEAVES_CHECK_DISTANCE; i++) - { - for (int y = a_BlockY - i; y <= a_BlockY + i; y++) - { - for (int z = a_BlockZ - i; z <= a_BlockZ + i; z++) - { - for (int x = a_BlockX - i; x <= a_BlockX + i; x++) - { - if (a_Area.GetBlockType(x, y, z) != E_BLOCK_SPONGE + i) - { - continue; - } - PROCESS_NEIGHBOR(x - 1, y, z); - PROCESS_NEIGHBOR(x + 1, y, z); - PROCESS_NEIGHBOR(x, y, z - 1); - PROCESS_NEIGHBOR(x, y, z + 1); - PROCESS_NEIGHBOR(x, y + 1, z); - PROCESS_NEIGHBOR(x, y - 1, z); - } // for x - } // for z - } // for y - } // for i - BFS iterations - return false; -} - - - - +#pragma once +#include "BlockHandler.h" +#include "../MersenneTwister.h" +#include "../World.h" +#include "../BlockArea.h" + + + + + +// Leaves can be this many blocks that away (inclusive) from the log not to decay +#define LEAVES_CHECK_DISTANCE 6 + +#define PROCESS_NEIGHBOR(x,y,z) \ + switch (a_Area.GetBlockType(x, y, z)) \ + { \ + case E_BLOCK_LEAVES: a_Area.SetBlockType(x, y, z, (BLOCKTYPE)(E_BLOCK_SPONGE + i + 1)); break; \ + case E_BLOCK_LOG: return true; \ + } + +bool HasNearLog(cBlockArea &a_Area, int a_BlockX, int a_BlockY, int a_BlockZ); + + + + + +class cBlockLeavesHandler : + public cBlockHandler +{ +public: + cBlockLeavesHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(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)); + } + if ((a_BlockMeta & 3) == E_META_SAPLING_APPLE) + { + if (rand.rand(100) == 0) + { + a_Pickups.push_back(cItem(E_ITEM_RED_APPLE, 1, 0)); + } + } + } + + + void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + cBlockHandler::OnDestroyed(a_World, 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) + { + cItems Drops; + Drops.push_back(cItem(E_ITEM_RED_APPLE, 1, 0)); + a_World->SpawnItemPickups(Drops, a_BlockX, a_BlockY, a_BlockZ); + } + } + + + virtual void OnNeighborChanged(cWorld * a_World, 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 + } + + + virtual void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + if ((Meta & 0x04) != 0) + { + // Player-placed leaves, don't decay + return; + } + + if ((Meta & 0x8) != 0) + { + // These leaves have been checked for decay lately and nothing around them changed + return; + } + + // Get the data around the leaves: + cBlockArea Area; + if (!Area.Read( + a_World, + a_BlockX - LEAVES_CHECK_DISTANCE, a_BlockX + LEAVES_CHECK_DISTANCE, + a_BlockY - LEAVES_CHECK_DISTANCE, a_BlockY + LEAVES_CHECK_DISTANCE, + a_BlockZ - LEAVES_CHECK_DISTANCE, a_BlockZ + LEAVES_CHECK_DISTANCE, + cBlockArea::baTypes) + ) + { + // Cannot check leaves, a chunk is missing too close + return; + } + + if (HasNearLog(Area, a_BlockX, a_BlockY, a_BlockZ)) + { + // Wood found, the leaves stay; mark them as checked: + a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x8); + return; + } + // Decay the leaves: + DropBlock(a_World, NULL, a_BlockX, a_BlockY, a_BlockZ); + + a_World->DigBlock(a_BlockX, a_BlockY, a_BlockZ); + + } + + + virtual const char * GetStepSound(void) override + { + return "step.grass"; + } +} ; + + + + + +bool HasNearLog(cBlockArea & a_Area, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + // Filter the blocks into a {leaves, log, other (air)} set: + BLOCKTYPE * Types = a_Area.GetBlockTypes(); + for (int i = a_Area.GetBlockCount() - 1; i > 0; i--) + { + switch (Types[i]) + { + case E_BLOCK_LEAVES: + case E_BLOCK_LOG: + { + break; + } + default: + { + Types[i] = E_BLOCK_AIR; + break; + } + } + } // for i - Types[] + + // Perform a breadth-first search to see if there's a log connected within 4 blocks of the leaves block: + // Simply replace all reachable leaves blocks with a sponge block plus iteration (in the Area) and see if we can reach a log in 4 iterations + a_Area.SetBlockType(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_SPONGE); + for (int i = 0; i < LEAVES_CHECK_DISTANCE; i++) + { + for (int y = a_BlockY - i; y <= a_BlockY + i; y++) + { + for (int z = a_BlockZ - i; z <= a_BlockZ + i; z++) + { + for (int x = a_BlockX - i; x <= a_BlockX + i; x++) + { + if (a_Area.GetBlockType(x, y, z) != E_BLOCK_SPONGE + i) + { + continue; + } + PROCESS_NEIGHBOR(x - 1, y, z); + PROCESS_NEIGHBOR(x + 1, y, z); + PROCESS_NEIGHBOR(x, y, z - 1); + PROCESS_NEIGHBOR(x, y, z + 1); + PROCESS_NEIGHBOR(x, y + 1, z); + PROCESS_NEIGHBOR(x, y - 1, z); + } // for x + } // for z + } // for y + } // for i - BFS iterations + return false; +} + + + + diff --git a/source/Blocks/BlockLever.cpp b/source/Blocks/BlockLever.cpp index a9ab1fbbb..6dbff10c1 100644 --- a/source/Blocks/BlockLever.cpp +++ b/source/Blocks/BlockLever.cpp @@ -1,48 +1,48 @@ - -#include "Globals.h" -#include "BlockLever.h" -#include "../Item.h" -#include "../World.h" -#include "../Player.h" -#include "../Simulator/RedstoneSimulator.h" - - - - - -cBlockLeverHandler::cBlockLeverHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) -{ -} - - - - - -void cBlockLeverHandler::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) -{ - // Flip the ON bit on/off. Using XOR bitwise operation to turn it on/off. - NIBBLETYPE Meta = ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08) & 0x0f); - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta); - if (Meta & 0x08) - { - a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f); - } - else - { - a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.5f); - } -} - - - - - -void cBlockLeverHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) -{ - OnUse(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NONE, 8, 8, 8); -} - - - - + +#include "Globals.h" +#include "BlockLever.h" +#include "../Item.h" +#include "../World.h" +#include "../Player.h" +#include "../Simulator/RedstoneSimulator.h" + + + + + +cBlockLeverHandler::cBlockLeverHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) +{ +} + + + + + +void cBlockLeverHandler::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) +{ + // Flip the ON bit on/off. Using XOR bitwise operation to turn it on/off. + NIBBLETYPE Meta = ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08) & 0x0f); + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta); + if (Meta & 0x08) + { + a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f); + } + else + { + a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.5f); + } +} + + + + + +void cBlockLeverHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + OnUse(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NONE, 8, 8, 8); +} + + + + diff --git a/source/Blocks/BlockLever.h b/source/Blocks/BlockLever.h index 42a16fd9b..362cf563e 100644 --- a/source/Blocks/BlockLever.h +++ b/source/Blocks/BlockLever.h @@ -1,61 +1,61 @@ -#pragma once - -#include "BlockHandler.h" -#include "../World.h" -#include "../Simulator/RedstoneSimulator.h" - - - - - -class cBlockLeverHandler : - public cBlockHandler -{ -public: - cBlockLeverHandler(BLOCKTYPE a_BlockType); - - virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, 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 ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - // Reset meta to 0 - a_Pickups.push_back(cItem(E_BLOCK_LEVER, 1, 0)); - } - - - virtual bool IsUseable(void) override - { - return true; - } - - - virtual bool GetPlacementBlockTypeMeta( - 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 - { - a_BlockType = m_BlockType; - a_BlockMeta = cRedstoneSimulator::LeverDirectionToMetaData(a_BlockFace); - return true; - } - - - virtual bool DoesAllowBlockOnTop(void) override - { - return false; - } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } -} ; - - - - +#pragma once + +#include "BlockHandler.h" +#include "../World.h" +#include "../Simulator/RedstoneSimulator.h" + + + + + +class cBlockLeverHandler : + public cBlockHandler +{ +public: + cBlockLeverHandler(BLOCKTYPE a_BlockType); + + virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, 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 ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Reset meta to 0 + a_Pickups.push_back(cItem(E_BLOCK_LEVER, 1, 0)); + } + + + virtual bool IsUseable(void) override + { + return true; + } + + + virtual bool GetPlacementBlockTypeMeta( + 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 + { + a_BlockType = m_BlockType; + a_BlockMeta = cRedstoneSimulator::LeverDirectionToMetaData(a_BlockFace); + return true; + } + + + virtual bool DoesAllowBlockOnTop(void) override + { + return false; + } + + + virtual const char * GetStepSound(void) override + { + return "step.wood"; + } +} ; + + + + diff --git a/source/Blocks/BlockMelon.h b/source/Blocks/BlockMelon.h index d985ef126..2f7d9a461 100644 --- a/source/Blocks/BlockMelon.h +++ b/source/Blocks/BlockMelon.h @@ -1,35 +1,35 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockMelonHandler : - public cBlockHandler -{ -public: - cBlockMelonHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - MTRand r1; - a_Pickups.push_back(cItem(E_ITEM_MELON_SLICE, (char)(3 + r1.randInt(4)), 0)); - } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockMelonHandler : + public cBlockHandler +{ +public: + cBlockMelonHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + MTRand r1; + a_Pickups.push_back(cItem(E_ITEM_MELON_SLICE, (char)(3 + r1.randInt(4)), 0)); + } + + + virtual const char * GetStepSound(void) override + { + return "step.wood"; + } +} ; + + + + diff --git a/source/Blocks/BlockMushroom.h b/source/Blocks/BlockMushroom.h index 62cc898c0..b3b23e2ba 100644 --- a/source/Blocks/BlockMushroom.h +++ b/source/Blocks/BlockMushroom.h @@ -1,71 +1,71 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockMushroomHandler : - public cBlockHandler -{ -public: - cBlockMushroomHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - // Reset meta to 0 - a_Pickups.push_back(cItem(m_BlockType, 1, 0)); - } - - - virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override - { - if (a_RelY <= 0) - { - return false; - } - - // TODO: Cannot be at too much daylight - - switch (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)) - { - case E_BLOCK_GLASS: - case E_BLOCK_CACTUS: - case E_BLOCK_ICE: - case E_BLOCK_LEAVES: - case E_BLOCK_AIR: - { - return false; - } - } - return true; - } - - - virtual bool DoesAllowBlockOnTop(void) override - { - return false; - } - - - virtual bool CanBePlacedOnSide(void) override - { - return false; - } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockMushroomHandler : + public cBlockHandler +{ +public: + cBlockMushroomHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Reset meta to 0 + a_Pickups.push_back(cItem(m_BlockType, 1, 0)); + } + + + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override + { + if (a_RelY <= 0) + { + return false; + } + + // TODO: Cannot be at too much daylight + + switch (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)) + { + case E_BLOCK_GLASS: + case E_BLOCK_CACTUS: + case E_BLOCK_ICE: + case E_BLOCK_LEAVES: + case E_BLOCK_AIR: + { + return false; + } + } + return true; + } + + + virtual bool DoesAllowBlockOnTop(void) override + { + return false; + } + + + virtual bool CanBePlacedOnSide(void) override + { + return false; + } + + + virtual const char * GetStepSound(void) override + { + return "step.grass"; + } +} ; + + + + diff --git a/source/Blocks/BlockMycelium.h b/source/Blocks/BlockMycelium.h index 8e1f577e1..0ed7162ac 100644 --- a/source/Blocks/BlockMycelium.h +++ b/source/Blocks/BlockMycelium.h @@ -1,27 +1,27 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockMyceliumHandler : - public cBlockHandler -{ -public: - cBlockMyceliumHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - a_Pickups.push_back(cItem(E_BLOCK_DIRT, 1, 0)); - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockMyceliumHandler : + public cBlockHandler +{ +public: + cBlockMyceliumHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem(E_BLOCK_DIRT, 1, 0)); + } +} ; + + + + diff --git a/source/Blocks/BlockNote.h b/source/Blocks/BlockNote.h index 5884a1eb3..fef38d845 100644 --- a/source/Blocks/BlockNote.h +++ b/source/Blocks/BlockNote.h @@ -1,13 +1,13 @@ -#pragma once -#include "BlockHandler.h" -#include "BlockEntity.h" - -class cBlockNoteHandler : public cBlockEntityHandler -{ -public: - cBlockNoteHandler(BLOCKTYPE a_BlockType) - : cBlockEntityHandler(a_BlockType) - { - } - -}; +#pragma once +#include "BlockHandler.h" +#include "BlockEntity.h" + +class cBlockNoteHandler : public cBlockEntityHandler +{ +public: + cBlockNoteHandler(BLOCKTYPE a_BlockType) + : cBlockEntityHandler(a_BlockType) + { + } + +}; diff --git a/source/Blocks/BlockOre.h b/source/Blocks/BlockOre.h index 1bfd8d17c..9684dbb19 100644 --- a/source/Blocks/BlockOre.h +++ b/source/Blocks/BlockOre.h @@ -1,80 +1,80 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../MersenneTwister.h" -#include "../World.h" - - - - - -class cBlockOreHandler : - public cBlockHandler -{ -public: - cBlockOreHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - short ItemType = m_BlockType; - char Count = 1; - short Meta = 0; - - MTRand r1; - switch (m_BlockType) - { - case E_BLOCK_LAPIS_ORE: - { - ItemType = E_ITEM_DYE; - Count = 4 + (char)r1.randInt(4); - Meta = 4; - break; - } - case E_BLOCK_REDSTONE_ORE: - case E_BLOCK_REDSTONE_ORE_GLOWING: - { - Count = 4 + (char)r1.randInt(1); - break; - } - default: - { - Count = 1; - break; - } - } - - switch (m_BlockType) - { - case E_BLOCK_DIAMOND_ORE: - { - ItemType = E_ITEM_DIAMOND; - break; - } - case E_BLOCK_REDSTONE_ORE: - case E_BLOCK_REDSTONE_ORE_GLOWING: - { - ItemType = E_ITEM_REDSTONE_DUST; - break; - } - case E_BLOCK_EMERALD_ORE: - { - ItemType = E_ITEM_EMERALD; - break; - } - case E_BLOCK_COAL_ORE: - { - ItemType = E_ITEM_COAL; - break; - } - } - a_Pickups.push_back(cItem(ItemType, Count, Meta)); - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../MersenneTwister.h" +#include "../World.h" + + + + + +class cBlockOreHandler : + public cBlockHandler +{ +public: + cBlockOreHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + short ItemType = m_BlockType; + char Count = 1; + short Meta = 0; + + MTRand r1; + switch (m_BlockType) + { + case E_BLOCK_LAPIS_ORE: + { + ItemType = E_ITEM_DYE; + Count = 4 + (char)r1.randInt(4); + Meta = 4; + break; + } + case E_BLOCK_REDSTONE_ORE: + case E_BLOCK_REDSTONE_ORE_GLOWING: + { + Count = 4 + (char)r1.randInt(1); + break; + } + default: + { + Count = 1; + break; + } + } + + switch (m_BlockType) + { + case E_BLOCK_DIAMOND_ORE: + { + ItemType = E_ITEM_DIAMOND; + break; + } + case E_BLOCK_REDSTONE_ORE: + case E_BLOCK_REDSTONE_ORE_GLOWING: + { + ItemType = E_ITEM_REDSTONE_DUST; + break; + } + case E_BLOCK_EMERALD_ORE: + { + ItemType = E_ITEM_EMERALD; + break; + } + case E_BLOCK_COAL_ORE: + { + ItemType = E_ITEM_COAL; + break; + } + } + a_Pickups.push_back(cItem(ItemType, Count, Meta)); + } +} ; + + + + diff --git a/source/Blocks/BlockPiston.cpp b/source/Blocks/BlockPiston.cpp index 29312e97c..d0f90559e 100644 --- a/source/Blocks/BlockPiston.cpp +++ b/source/Blocks/BlockPiston.cpp @@ -1,69 +1,69 @@ - -#include "Globals.h" -#include "BlockPiston.h" -#include "../Item.h" -#include "../World.h" -#include "../Player.h" -#include "../Piston.h" - - - - - -#define AddPistonDir(x, y, z, dir, amount) \ - switch (dir) \ - { \ - case 0: (y) -= (amount); break; \ - case 1: (y) += (amount); break; \ - case 2: (z) -= (amount); break; \ - case 3: (z) += (amount); break; \ - case 4: (x) -= (amount); break; \ - case 5: (x) += (amount); break; \ - } - - - - -cBlockPistonHandler::cBlockPistonHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) -{ -} - - - - - -void cBlockPistonHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) -{ - char OldMeta = a_World->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) - { - a_World->SetBlock(newX, newY, newZ, E_BLOCK_AIR, 0); - } -} - - - - - -bool cBlockPistonHandler::GetPlacementBlockTypeMeta( - 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 -) -{ - a_BlockType = m_BlockType; - a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), a_Player->GetPitch()); - return true; -} - - - - + +#include "Globals.h" +#include "BlockPiston.h" +#include "../Item.h" +#include "../World.h" +#include "../Player.h" +#include "../Piston.h" + + + + + +#define AddPistonDir(x, y, z, dir, amount) \ + switch (dir) \ + { \ + case 0: (y) -= (amount); break; \ + case 1: (y) += (amount); break; \ + case 2: (z) -= (amount); break; \ + case 3: (z) += (amount); break; \ + case 4: (x) -= (amount); break; \ + case 5: (x) += (amount); break; \ + } + + + + +cBlockPistonHandler::cBlockPistonHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) +{ +} + + + + + +void cBlockPistonHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + char OldMeta = a_World->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) + { + a_World->SetBlock(newX, newY, newZ, E_BLOCK_AIR, 0); + } +} + + + + + +bool cBlockPistonHandler::GetPlacementBlockTypeMeta( + 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 +) +{ + a_BlockType = m_BlockType; + a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), a_Player->GetPitch()); + return true; +} + + + + diff --git a/source/Blocks/BlockPiston.h b/source/Blocks/BlockPiston.h index 5d9d5c2b7..ef6a4fa97 100644 --- a/source/Blocks/BlockPiston.h +++ b/source/Blocks/BlockPiston.h @@ -1,28 +1,28 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockPistonHandler : - public cBlockHandler -{ -public: - cBlockPistonHandler(BLOCKTYPE a_BlockType); - - virtual void OnDestroyed(cWorld *a_World, 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, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override; -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockPistonHandler : + public cBlockHandler +{ +public: + cBlockPistonHandler(BLOCKTYPE a_BlockType); + + virtual void OnDestroyed(cWorld *a_World, 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, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override; +} ; + + + + diff --git a/source/Blocks/BlockRail.h b/source/Blocks/BlockRail.h index 60865abf5..65d120923 100644 --- a/source/Blocks/BlockRail.h +++ b/source/Blocks/BlockRail.h @@ -1,421 +1,421 @@ - -#pragma once - -#include "BlockEntity.h" -#include "../World.h" - - - - - -/// Meta values for the rail -enum ENUM_RAIL_DIRECTIONS -{ - E_RAIL_NORTH_SOUTH = 0, - E_RAIL_EAST_WEST = 1, - E_RAIL_ASCEND_EAST = 2, - E_RAIL_ASCEND_WEST = 3, - E_RAIL_ASCEND_NORTH = 4, - E_RAIL_ASCEND_SOUTH = 5, - E_RAIL_CURVED_SOUTH_EAST = 6, - E_RAIL_CURVED_SOUTH_WEST = 7, - E_RAIL_CURVED_NORTH_WEST = 8, - E_RAIL_CURVED_NORTH_EAST = 9, - - // Some useful synonyms: - E_RAIL_DIR_X = E_RAIL_EAST_WEST, - E_RAIL_DIR_Z = E_RAIL_NORTH_SOUTH, - E_RAIL_ASCEND_XP = E_RAIL_ASCEND_EAST, - E_RAIL_ASCEND_XM = E_RAIL_ASCEND_WEST, - E_RAIL_ASCEND_ZM = E_RAIL_ASCEND_NORTH, - E_RAIL_ASCEND_ZP = E_RAIL_ASCEND_SOUTH, - E_RAIL_CURVED_XPZP = E_RAIL_CURVED_SOUTH_EAST, - E_RAIL_CURVED_XMZP = E_RAIL_CURVED_SOUTH_WEST, - E_RAIL_CURVED_XMZM = E_RAIL_CURVED_NORTH_WEST, - E_RAIL_CURVED_XPZM = E_RAIL_CURVED_NORTH_EAST, -} ; - - - - - -enum ENUM_PURE -{ - E_PURE_UPDOWN = 0, - E_PURE_DOWN = 1, - E_PURE_NONE = 2 -}; - - - - - -class cBlockRailHandler : - public cBlockHandler -{ -public: - cBlockRailHandler(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, - 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); - return true; - } - - - virtual void OnNeighborChanged(cWorld *a_World, 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))) - { - a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ)); - } - } - - - virtual bool CanBeAt(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)]) - { - return false; - } - - NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ); - switch (Meta) - { - case E_RAIL_ASCEND_EAST: - case E_RAIL_ASCEND_WEST: - case E_RAIL_ASCEND_NORTH: - case E_RAIL_ASCEND_SOUTH: - { - // Mapping between the meta and the neighbors that need checking - Meta -= E_RAIL_ASCEND_EAST; // Base index at zero - static const struct - { - int x, z; - } Coords[] = - { - { 1, 0}, // east, XP - {-1, 0}, // west, XM - { 0, -1}, // north, ZM - { 0, 1}, // south, ZP - } ; - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - if (!a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[Meta].x, a_RelY, a_RelZ + Coords[Meta].z, BlockType, BlockMeta)) - { - // Too close to the edge, cannot simulate - return true; - } - return g_BlockIsSolid[BlockType]; - } - } - return true; - } - - NIBBLETYPE FindMeta(cWorld *a_World, 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] = 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)) - 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)) - 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)) - Neighbors[3] = true; - for (int i = 0; i < 8; i++) - { - if (Neighbors[i]) - { - RailsCnt++; - } - } - if (RailsCnt == 1) - { - if (Neighbors[7]) return E_RAIL_ASCEND_SOUTH; - else if (Neighbors[6]) return E_RAIL_ASCEND_NORTH; - else if (Neighbors[5]) return E_RAIL_ASCEND_WEST; - else if (Neighbors[4]) return E_RAIL_ASCEND_EAST; - else if (Neighbors[0] || Neighbors[1]) return E_RAIL_EAST_WEST; - else if (Neighbors[2] || Neighbors[3]) return E_RAIL_NORTH_SOUTH; - ASSERT(!"Weird neighbor count"); - return Meta; - } - for (int i = 0; i < 4; i++) - { - if (Neighbors[i + 4]) - { - Neighbors[i] = true; - } - } - if (RailsCnt > 1) - { - if (Neighbors[3] && Neighbors[0]) return E_RAIL_CURVED_SOUTH_EAST; - else if (Neighbors[3] && Neighbors[1]) return E_RAIL_CURVED_SOUTH_WEST; - else if (Neighbors[2] && Neighbors[0]) return E_RAIL_CURVED_NORTH_EAST; - else if (Neighbors[2] && Neighbors[1]) return E_RAIL_CURVED_NORTH_WEST; - else if (Neighbors[7] && Neighbors[2]) return E_RAIL_ASCEND_SOUTH; - else if (Neighbors[3] && Neighbors[6]) return E_RAIL_ASCEND_NORTH; - else if (Neighbors[5] && Neighbors[0]) return E_RAIL_ASCEND_WEST; - else if (Neighbors[4] && Neighbors[1]) return E_RAIL_ASCEND_EAST; - else if (Neighbors[0] && Neighbors[1]) return E_RAIL_EAST_WEST; - else if (Neighbors[2] && Neighbors[3]) return E_RAIL_NORTH_SOUTH; - ASSERT(!"Weird neighbor count"); - } - return Meta; - } - - - bool IsUnstable(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) - { - if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL) - { - return false; - } - NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - switch (Meta) - { - case E_RAIL_NORTH_SOUTH: - { - 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) - ) - { - return true; - } - break; - } - - case E_RAIL_EAST_WEST: - { - 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) - ) - { - return true; - } - break; - } - - case E_RAIL_ASCEND_EAST: - { - 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) - ) - { - return true; - } - break; - } - - case E_RAIL_ASCEND_WEST: - { - 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) - ) - { - return true; - } - break; - } - - case E_RAIL_ASCEND_NORTH: - { - 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) - ) - { - return true; - } - break; - } - - case E_RAIL_ASCEND_SOUTH: - { - 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) - ) - { - return true; - } - break; - } - - case E_RAIL_CURVED_SOUTH_EAST: - { - 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) - ) - { - return true; - } - break; - } - - case E_RAIL_CURVED_SOUTH_WEST: - { - 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) - ) - { - return true; - } - break; - } - - case E_RAIL_CURVED_NORTH_WEST: - { - 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) - ) - { - return true; - } - break; - } - - case E_RAIL_CURVED_NORTH_EAST: - { - 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) - ) - { - return true; - } - break; - } - } - return false; - } - - - bool IsNotConnected(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char 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 ((a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure != E_PURE_UPDOWN)) - { - if ((a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure == E_PURE_NONE)) - { - return true; - } - else - { - Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ); - } - } - else - { - Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY + 1, a_BlockZ); - } - } - else - { - Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - } - - switch (a_BlockFace) - { - case BLOCK_FACE_NORTH: - { - if ( - (Meta == E_RAIL_NORTH_SOUTH) || - (Meta == E_RAIL_ASCEND_NORTH) || - (Meta == E_RAIL_ASCEND_SOUTH) || - (Meta == E_RAIL_CURVED_SOUTH_EAST) || - (Meta == E_RAIL_CURVED_SOUTH_WEST) - ) - { - return false; - } - break; - } - - case BLOCK_FACE_SOUTH: - { - if ( - (Meta == E_RAIL_NORTH_SOUTH) || - (Meta == E_RAIL_ASCEND_NORTH) || - (Meta == E_RAIL_ASCEND_SOUTH) || - (Meta == E_RAIL_CURVED_NORTH_EAST) || - (Meta == E_RAIL_CURVED_NORTH_WEST) - ) - { - return false; - } - break; - } - - case BLOCK_FACE_EAST: - { - if ( - (Meta == E_RAIL_EAST_WEST) || - (Meta == E_RAIL_ASCEND_EAST) || - (Meta == E_RAIL_ASCEND_WEST) || - (Meta == E_RAIL_CURVED_SOUTH_WEST) || - (Meta == E_RAIL_CURVED_NORTH_WEST) - ) - { - return false; - } - break; - } - case BLOCK_FACE_WEST: - { - if ( - (Meta == E_RAIL_EAST_WEST) || - (Meta == E_RAIL_ASCEND_EAST) || - (Meta == E_RAIL_ASCEND_WEST) || - (Meta == E_RAIL_CURVED_SOUTH_EAST) || - (Meta == E_RAIL_CURVED_NORTH_EAST) - ) - { - return false; - } - break; - } - } - return true; - } -} ; - - - - + +#pragma once + +#include "BlockEntity.h" +#include "../World.h" + + + + + +/// Meta values for the rail +enum ENUM_RAIL_DIRECTIONS +{ + E_RAIL_NORTH_SOUTH = 0, + E_RAIL_EAST_WEST = 1, + E_RAIL_ASCEND_EAST = 2, + E_RAIL_ASCEND_WEST = 3, + E_RAIL_ASCEND_NORTH = 4, + E_RAIL_ASCEND_SOUTH = 5, + E_RAIL_CURVED_SOUTH_EAST = 6, + E_RAIL_CURVED_SOUTH_WEST = 7, + E_RAIL_CURVED_NORTH_WEST = 8, + E_RAIL_CURVED_NORTH_EAST = 9, + + // Some useful synonyms: + E_RAIL_DIR_X = E_RAIL_EAST_WEST, + E_RAIL_DIR_Z = E_RAIL_NORTH_SOUTH, + E_RAIL_ASCEND_XP = E_RAIL_ASCEND_EAST, + E_RAIL_ASCEND_XM = E_RAIL_ASCEND_WEST, + E_RAIL_ASCEND_ZM = E_RAIL_ASCEND_NORTH, + E_RAIL_ASCEND_ZP = E_RAIL_ASCEND_SOUTH, + E_RAIL_CURVED_XPZP = E_RAIL_CURVED_SOUTH_EAST, + E_RAIL_CURVED_XMZP = E_RAIL_CURVED_SOUTH_WEST, + E_RAIL_CURVED_XMZM = E_RAIL_CURVED_NORTH_WEST, + E_RAIL_CURVED_XPZM = E_RAIL_CURVED_NORTH_EAST, +} ; + + + + + +enum ENUM_PURE +{ + E_PURE_UPDOWN = 0, + E_PURE_DOWN = 1, + E_PURE_NONE = 2 +}; + + + + + +class cBlockRailHandler : + public cBlockHandler +{ +public: + cBlockRailHandler(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, + 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); + return true; + } + + + virtual void OnNeighborChanged(cWorld *a_World, 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))) + { + a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ)); + } + } + + + virtual bool CanBeAt(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)]) + { + return false; + } + + NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ); + switch (Meta) + { + case E_RAIL_ASCEND_EAST: + case E_RAIL_ASCEND_WEST: + case E_RAIL_ASCEND_NORTH: + case E_RAIL_ASCEND_SOUTH: + { + // Mapping between the meta and the neighbors that need checking + Meta -= E_RAIL_ASCEND_EAST; // Base index at zero + static const struct + { + int x, z; + } Coords[] = + { + { 1, 0}, // east, XP + {-1, 0}, // west, XM + { 0, -1}, // north, ZM + { 0, 1}, // south, ZP + } ; + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + if (!a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[Meta].x, a_RelY, a_RelZ + Coords[Meta].z, BlockType, BlockMeta)) + { + // Too close to the edge, cannot simulate + return true; + } + return g_BlockIsSolid[BlockType]; + } + } + return true; + } + + NIBBLETYPE FindMeta(cWorld *a_World, 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] = 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)) + 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)) + 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)) + Neighbors[3] = true; + for (int i = 0; i < 8; i++) + { + if (Neighbors[i]) + { + RailsCnt++; + } + } + if (RailsCnt == 1) + { + if (Neighbors[7]) return E_RAIL_ASCEND_SOUTH; + else if (Neighbors[6]) return E_RAIL_ASCEND_NORTH; + else if (Neighbors[5]) return E_RAIL_ASCEND_WEST; + else if (Neighbors[4]) return E_RAIL_ASCEND_EAST; + else if (Neighbors[0] || Neighbors[1]) return E_RAIL_EAST_WEST; + else if (Neighbors[2] || Neighbors[3]) return E_RAIL_NORTH_SOUTH; + ASSERT(!"Weird neighbor count"); + return Meta; + } + for (int i = 0; i < 4; i++) + { + if (Neighbors[i + 4]) + { + Neighbors[i] = true; + } + } + if (RailsCnt > 1) + { + if (Neighbors[3] && Neighbors[0]) return E_RAIL_CURVED_SOUTH_EAST; + else if (Neighbors[3] && Neighbors[1]) return E_RAIL_CURVED_SOUTH_WEST; + else if (Neighbors[2] && Neighbors[0]) return E_RAIL_CURVED_NORTH_EAST; + else if (Neighbors[2] && Neighbors[1]) return E_RAIL_CURVED_NORTH_WEST; + else if (Neighbors[7] && Neighbors[2]) return E_RAIL_ASCEND_SOUTH; + else if (Neighbors[3] && Neighbors[6]) return E_RAIL_ASCEND_NORTH; + else if (Neighbors[5] && Neighbors[0]) return E_RAIL_ASCEND_WEST; + else if (Neighbors[4] && Neighbors[1]) return E_RAIL_ASCEND_EAST; + else if (Neighbors[0] && Neighbors[1]) return E_RAIL_EAST_WEST; + else if (Neighbors[2] && Neighbors[3]) return E_RAIL_NORTH_SOUTH; + ASSERT(!"Weird neighbor count"); + } + return Meta; + } + + + bool IsUnstable(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) + { + if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL) + { + return false; + } + NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + switch (Meta) + { + case E_RAIL_NORTH_SOUTH: + { + 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) + ) + { + return true; + } + break; + } + + case E_RAIL_EAST_WEST: + { + 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) + ) + { + return true; + } + break; + } + + case E_RAIL_ASCEND_EAST: + { + 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) + ) + { + return true; + } + break; + } + + case E_RAIL_ASCEND_WEST: + { + 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) + ) + { + return true; + } + break; + } + + case E_RAIL_ASCEND_NORTH: + { + 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) + ) + { + return true; + } + break; + } + + case E_RAIL_ASCEND_SOUTH: + { + 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) + ) + { + return true; + } + break; + } + + case E_RAIL_CURVED_SOUTH_EAST: + { + 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) + ) + { + return true; + } + break; + } + + case E_RAIL_CURVED_SOUTH_WEST: + { + 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) + ) + { + return true; + } + break; + } + + case E_RAIL_CURVED_NORTH_WEST: + { + 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) + ) + { + return true; + } + break; + } + + case E_RAIL_CURVED_NORTH_EAST: + { + 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) + ) + { + return true; + } + break; + } + } + return false; + } + + + bool IsNotConnected(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char 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 ((a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure != E_PURE_UPDOWN)) + { + if ((a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure == E_PURE_NONE)) + { + return true; + } + else + { + Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ); + } + } + else + { + Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY + 1, a_BlockZ); + } + } + else + { + Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + } + + switch (a_BlockFace) + { + case BLOCK_FACE_NORTH: + { + if ( + (Meta == E_RAIL_NORTH_SOUTH) || + (Meta == E_RAIL_ASCEND_NORTH) || + (Meta == E_RAIL_ASCEND_SOUTH) || + (Meta == E_RAIL_CURVED_SOUTH_EAST) || + (Meta == E_RAIL_CURVED_SOUTH_WEST) + ) + { + return false; + } + break; + } + + case BLOCK_FACE_SOUTH: + { + if ( + (Meta == E_RAIL_NORTH_SOUTH) || + (Meta == E_RAIL_ASCEND_NORTH) || + (Meta == E_RAIL_ASCEND_SOUTH) || + (Meta == E_RAIL_CURVED_NORTH_EAST) || + (Meta == E_RAIL_CURVED_NORTH_WEST) + ) + { + return false; + } + break; + } + + case BLOCK_FACE_EAST: + { + if ( + (Meta == E_RAIL_EAST_WEST) || + (Meta == E_RAIL_ASCEND_EAST) || + (Meta == E_RAIL_ASCEND_WEST) || + (Meta == E_RAIL_CURVED_SOUTH_WEST) || + (Meta == E_RAIL_CURVED_NORTH_WEST) + ) + { + return false; + } + break; + } + case BLOCK_FACE_WEST: + { + if ( + (Meta == E_RAIL_EAST_WEST) || + (Meta == E_RAIL_ASCEND_EAST) || + (Meta == E_RAIL_ASCEND_WEST) || + (Meta == E_RAIL_CURVED_SOUTH_EAST) || + (Meta == E_RAIL_CURVED_NORTH_EAST) + ) + { + return false; + } + break; + } + } + return true; + } +} ; + + + + diff --git a/source/Blocks/BlockRedstone.cpp b/source/Blocks/BlockRedstone.cpp index f433be4ef..35cdc34cf 100644 --- a/source/Blocks/BlockRedstone.cpp +++ b/source/Blocks/BlockRedstone.cpp @@ -1,27 +1,27 @@ - -#include "Globals.h" -#include "BlockRedstone.h" -#include "../Item.h" -#include "../World.h" - - - - - -cBlockRedstoneHandler::cBlockRedstoneHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) -{ -} - - - - - -void cBlockRedstoneHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) -{ - // Nothing needed yet -} - - - - + +#include "Globals.h" +#include "BlockRedstone.h" +#include "../Item.h" +#include "../World.h" + + + + + +cBlockRedstoneHandler::cBlockRedstoneHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) +{ +} + + + + + +void cBlockRedstoneHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + // Nothing needed yet +} + + + + diff --git a/source/Blocks/BlockRedstone.h b/source/Blocks/BlockRedstone.h index 3a4649d7e..ae0466937 100644 --- a/source/Blocks/BlockRedstone.h +++ b/source/Blocks/BlockRedstone.h @@ -1,46 +1,46 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../World.h" - - - - - -class cBlockRedstoneHandler : - public cBlockHandler -{ -public: - cBlockRedstoneHandler(BLOCKTYPE a_BlockType); - - virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; - - virtual bool DoesAllowBlockOnTop(void) override - { - return false; - } - - - virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override - { - return ((a_RelY > 0) && g_BlockIsSolid[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]); - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - // Reset meta to 0 - a_Pickups.push_back(cItem(E_ITEM_REDSTONE_DUST, 1)); - } - - - virtual bool CanBePlacedOnSide(void) override - { - return false; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../World.h" + + + + + +class cBlockRedstoneHandler : + public cBlockHandler +{ +public: + cBlockRedstoneHandler(BLOCKTYPE a_BlockType); + + virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; + + virtual bool DoesAllowBlockOnTop(void) override + { + return false; + } + + + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override + { + return ((a_RelY > 0) && g_BlockIsSolid[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]); + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Reset meta to 0 + a_Pickups.push_back(cItem(E_ITEM_REDSTONE_DUST, 1)); + } + + + virtual bool CanBePlacedOnSide(void) override + { + return false; + } +} ; + + + + diff --git a/source/Blocks/BlockRedstoneRepeater.cpp b/source/Blocks/BlockRedstoneRepeater.cpp index 15b736cbc..9857dd223 100644 --- a/source/Blocks/BlockRedstoneRepeater.cpp +++ b/source/Blocks/BlockRedstoneRepeater.cpp @@ -1,47 +1,47 @@ - -#include "Globals.h" -#include "BlockRedstoneRepeater.h" -#include "../Item.h" -#include "../World.h" -#include "../Player.h" -#include "../Simulator/RedstoneSimulator.h" - - - - - -cBlockRedstoneRepeaterHandler::cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) -{ -} - - - - - -void cBlockRedstoneRepeaterHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) -{ - // Nothing needed yet -} - - - - - -void cBlockRedstoneRepeaterHandler::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) -{ - a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) + 0x04) & 0x0f)); -} - - - - - -void cBlockRedstoneRepeaterHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) -{ - OnUse(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NONE, 8, 8, 8); -} - - - - + +#include "Globals.h" +#include "BlockRedstoneRepeater.h" +#include "../Item.h" +#include "../World.h" +#include "../Player.h" +#include "../Simulator/RedstoneSimulator.h" + + + + + +cBlockRedstoneRepeaterHandler::cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) +{ +} + + + + + +void cBlockRedstoneRepeaterHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + // Nothing needed yet +} + + + + + +void cBlockRedstoneRepeaterHandler::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) +{ + a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) + 0x04) & 0x0f)); +} + + + + + +void cBlockRedstoneRepeaterHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + OnUse(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NONE, 8, 8, 8); +} + + + + diff --git a/source/Blocks/BlockRedstoneRepeater.h b/source/Blocks/BlockRedstoneRepeater.h index 4a16149fd..f3e250963 100644 --- a/source/Blocks/BlockRedstoneRepeater.h +++ b/source/Blocks/BlockRedstoneRepeater.h @@ -1,60 +1,60 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../World.h" - - - - - -class cBlockRedstoneRepeaterHandler : - public cBlockHandler -{ -public: - cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType); - virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; - - virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, 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 ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - // Reset meta to 0 - a_Pickups.push_back(cItem(E_ITEM_REDSTONE_REPEATER, 1, 0)); - } - - - virtual bool IsUseable(void) override - { - return true; - } - - - virtual bool DoesAllowBlockOnTop(void) override - { - return false; - } - - - virtual bool CanBeAt(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 CanBePlacedOnSide(void) override - { - return false; - } - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../World.h" + + + + + +class cBlockRedstoneRepeaterHandler : + public cBlockHandler +{ +public: + cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType); + virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; + + virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, 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 ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Reset meta to 0 + a_Pickups.push_back(cItem(E_ITEM_REDSTONE_REPEATER, 1, 0)); + } + + + virtual bool IsUseable(void) override + { + return true; + } + + + virtual bool DoesAllowBlockOnTop(void) override + { + return false; + } + + + virtual bool CanBeAt(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 CanBePlacedOnSide(void) override + { + return false; + } + + virtual const char * GetStepSound(void) override + { + return "step.wood"; + } +} ; + + + + diff --git a/source/Blocks/BlockRedstoneTorch.h b/source/Blocks/BlockRedstoneTorch.h index c8256ce64..cb897ba3f 100644 --- a/source/Blocks/BlockRedstoneTorch.h +++ b/source/Blocks/BlockRedstoneTorch.h @@ -1,36 +1,36 @@ - -#pragma once - -#include "BlockRedstone.h" -#include "BlockTorch.h" - - - - - -class cBlockRedstoneTorchHandler : - public cBlockTorchHandler -{ -public: - cBlockRedstoneTorchHandler(BLOCKTYPE a_BlockType) - : cBlockTorchHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - // Always drop the ON torch, meta 0 - a_Pickups.push_back(cItem(E_BLOCK_REDSTONE_TORCH_ON, 1, 0)); - } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } -} ; - - - - + +#pragma once + +#include "BlockRedstone.h" +#include "BlockTorch.h" + + + + + +class cBlockRedstoneTorchHandler : + public cBlockTorchHandler +{ +public: + cBlockRedstoneTorchHandler(BLOCKTYPE a_BlockType) + : cBlockTorchHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Always drop the ON torch, meta 0 + a_Pickups.push_back(cItem(E_BLOCK_REDSTONE_TORCH_ON, 1, 0)); + } + + + virtual const char * GetStepSound(void) override + { + return "step.wood"; + } +} ; + + + + diff --git a/source/Blocks/BlockSand.h b/source/Blocks/BlockSand.h index 878770d22..3fc271483 100644 --- a/source/Blocks/BlockSand.h +++ b/source/Blocks/BlockSand.h @@ -1,28 +1,28 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockSandHandler : - public cBlockHandler -{ -public: - cBlockSandHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - virtual const char * GetStepSound(void) override - { - return "step.sand"; - } - -}; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockSandHandler : + public cBlockHandler +{ +public: + cBlockSandHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual const char * GetStepSound(void) override + { + return "step.sand"; + } + +}; + + + + diff --git a/source/Blocks/BlockSapling.h b/source/Blocks/BlockSapling.h index 957331886..17ef4984f 100644 --- a/source/Blocks/BlockSapling.h +++ b/source/Blocks/BlockSapling.h @@ -1,69 +1,69 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../World.h" - - - - - -class cBlockSaplingHandler : - public cBlockHandler -{ -public: - cBlockSaplingHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - // Only the first 2 bits contain the display information, the others are for growing - a_Pickups.push_back(cItem(E_BLOCK_SAPLING, 1, a_BlockMeta & 3)); - } - - - virtual bool CanBeAt(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)); - } - - - virtual bool DoesAllowBlockOnTop(void) override - { - return false; - } - - - void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override - { - NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - - if ((Meta & 0x08) != 0) - { - a_World->GrowTree(a_BlockX, a_BlockY, a_BlockZ); - } - else - { - a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x08); - } - } - - - virtual bool CanBePlacedOnSide() override - { - return false; - } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../World.h" + + + + + +class cBlockSaplingHandler : + public cBlockHandler +{ +public: + cBlockSaplingHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Only the first 2 bits contain the display information, the others are for growing + a_Pickups.push_back(cItem(E_BLOCK_SAPLING, 1, a_BlockMeta & 3)); + } + + + virtual bool CanBeAt(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)); + } + + + virtual bool DoesAllowBlockOnTop(void) override + { + return false; + } + + + void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + + if ((Meta & 0x08) != 0) + { + a_World->GrowTree(a_BlockX, a_BlockY, a_BlockZ); + } + else + { + a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x08); + } + } + + + virtual bool CanBePlacedOnSide() override + { + return false; + } + + + virtual const char * GetStepSound(void) override + { + return "step.grass"; + } +} ; + + + + diff --git a/source/Blocks/BlockSign.h b/source/Blocks/BlockSign.h index 4bdccb47e..a89ae0c49 100644 --- a/source/Blocks/BlockSign.h +++ b/source/Blocks/BlockSign.h @@ -1,73 +1,73 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../World.h" -#include "../Player.h" - - - - - -class cBlockSignHandler : - public cBlockHandler -{ -public: - cBlockSignHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - a_Pickups.push_back(cItem(E_ITEM_SIGN, 1, 0)); - } - - - virtual bool DoesAllowBlockOnTop(void) override - { - return false; - } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } - - - static char RotationToMetaData(double a_Rotation) - { - a_Rotation += 180 + (180 / 16); // So it's not aligned with axis - if (a_Rotation > 360) - { - a_Rotation -= 360; - } - - a_Rotation = (a_Rotation / 360) * 16; - - return ((char)a_Rotation) % 16; - } - - - static char DirectionToMetaData(char a_Direction) - { - switch (a_Direction) - { - case 0x2: return 0x2; - case 0x3: return 0x3; - case 0x4: return 0x4; - case 0x5: return 0x5; - default: - { - break; - } - } - return 0x2; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../World.h" +#include "../Player.h" + + + + + +class cBlockSignHandler : + public cBlockHandler +{ +public: + cBlockSignHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem(E_ITEM_SIGN, 1, 0)); + } + + + virtual bool DoesAllowBlockOnTop(void) override + { + return false; + } + + + virtual const char * GetStepSound(void) override + { + return "step.wood"; + } + + + static char RotationToMetaData(double a_Rotation) + { + a_Rotation += 180 + (180 / 16); // So it's not aligned with axis + if (a_Rotation > 360) + { + a_Rotation -= 360; + } + + a_Rotation = (a_Rotation / 360) * 16; + + return ((char)a_Rotation) % 16; + } + + + static char DirectionToMetaData(char a_Direction) + { + switch (a_Direction) + { + case 0x2: return 0x2; + case 0x3: return 0x3; + case 0x4: return 0x4; + case 0x5: return 0x5; + default: + { + break; + } + } + return 0x2; + } +} ; + + + + diff --git a/source/Blocks/BlockSlab.h b/source/Blocks/BlockSlab.h index 2abcc6364..f34f42bae 100644 --- a/source/Blocks/BlockSlab.h +++ b/source/Blocks/BlockSlab.h @@ -1,70 +1,70 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockSlabHandler : - public cBlockHandler -{ -public: - cBlockSlabHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - char Count = ((m_BlockType == E_BLOCK_DOUBLE_STONE_SLAB) || (m_BlockType == E_BLOCK_DOUBLE_WOODEN_SLAB)) ? 2 : 1; - a_Pickups.push_back(cItem(m_BlockType, Count, a_BlockMeta)); - } - - - virtual bool GetPlacementBlockTypeMeta( - 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 - { - a_BlockType = m_BlockType; - NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage & 0x07); - switch (a_BlockFace) - { - case BLOCK_FACE_TOP: a_BlockMeta = Meta & 0x7; break; // Always bottom half of the slab when placing on top of something - case BLOCK_FACE_BOTTOM: a_BlockMeta = Meta | 0x8; break; // Always top half of the slab when placing on bottom of something - case BLOCK_FACE_EAST: - case BLOCK_FACE_NORTH: - case BLOCK_FACE_SOUTH: - case BLOCK_FACE_WEST: - { - if (a_CursorY > 7) - { - // Cursor at the top half of the face, place a top half of slab - a_BlockMeta = Meta | 0x8; - } - else - { - // Cursor at the bottom half of the face, place a bottom half of slab: - a_BlockMeta = Meta & 0x7; - } - break; - } - } // switch (a_BlockFace) - return true; - } - - - virtual const char * GetStepSound(void) override - { - return ((m_BlockType == E_BLOCK_WOODEN_SLAB) || (m_BlockType == E_BLOCK_DOUBLE_WOODEN_SLAB)) ? "step.wood" : "step.stone"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockSlabHandler : + public cBlockHandler +{ +public: + cBlockSlabHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + char Count = ((m_BlockType == E_BLOCK_DOUBLE_STONE_SLAB) || (m_BlockType == E_BLOCK_DOUBLE_WOODEN_SLAB)) ? 2 : 1; + a_Pickups.push_back(cItem(m_BlockType, Count, a_BlockMeta)); + } + + + virtual bool GetPlacementBlockTypeMeta( + 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 + { + a_BlockType = m_BlockType; + NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage & 0x07); + switch (a_BlockFace) + { + case BLOCK_FACE_TOP: a_BlockMeta = Meta & 0x7; break; // Always bottom half of the slab when placing on top of something + case BLOCK_FACE_BOTTOM: a_BlockMeta = Meta | 0x8; break; // Always top half of the slab when placing on bottom of something + case BLOCK_FACE_EAST: + case BLOCK_FACE_NORTH: + case BLOCK_FACE_SOUTH: + case BLOCK_FACE_WEST: + { + if (a_CursorY > 7) + { + // Cursor at the top half of the face, place a top half of slab + a_BlockMeta = Meta | 0x8; + } + else + { + // Cursor at the bottom half of the face, place a bottom half of slab: + a_BlockMeta = Meta & 0x7; + } + break; + } + } // switch (a_BlockFace) + return true; + } + + + virtual const char * GetStepSound(void) override + { + return ((m_BlockType == E_BLOCK_WOODEN_SLAB) || (m_BlockType == E_BLOCK_DOUBLE_WOODEN_SLAB)) ? "step.wood" : "step.stone"; + } +} ; + + + + diff --git a/source/Blocks/BlockSnow.h b/source/Blocks/BlockSnow.h index f150f497c..bdd9f0b87 100644 --- a/source/Blocks/BlockSnow.h +++ b/source/Blocks/BlockSnow.h @@ -1,52 +1,52 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockSnowHandler : - public cBlockHandler -{ -public: - cBlockSnowHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual bool DoesIgnoreBuildCollision(void) override - { - return true; - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - a_Pickups.push_back(cItem(E_ITEM_SNOWBALL, 1, 0)); - } - - - virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override - { - return (a_RelY > 0) && g_BlockIsSnowable[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]; - } - - - virtual bool DoesDropOnUnsuitable(void) override - { - return false; - } - - - virtual const char * GetStepSound(void) override - { - return "step.cloth"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockSnowHandler : + public cBlockHandler +{ +public: + cBlockSnowHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual bool DoesIgnoreBuildCollision(void) override + { + return true; + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem(E_ITEM_SNOWBALL, 1, 0)); + } + + + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override + { + return (a_RelY > 0) && g_BlockIsSnowable[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]; + } + + + virtual bool DoesDropOnUnsuitable(void) override + { + return false; + } + + + virtual const char * GetStepSound(void) override + { + return "step.cloth"; + } +} ; + + + + diff --git a/source/Blocks/BlockStairs.h b/source/Blocks/BlockStairs.h index 6fc316e45..485ebda1a 100644 --- a/source/Blocks/BlockStairs.h +++ b/source/Blocks/BlockStairs.h @@ -1,153 +1,153 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockStairsHandler : - public cBlockHandler -{ -public: - cBlockStairsHandler(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, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override - { - a_BlockType = m_BlockType; - a_BlockMeta = RotationToMetaData(a_Player->GetRotation()); - switch (a_BlockFace) - { - case BLOCK_FACE_TOP: break; - case BLOCK_FACE_BOTTOM: a_BlockMeta = a_BlockMeta | 0x4; break; // When placing onto a bottom face, always place an upside-down stairs block - case BLOCK_FACE_EAST: - case BLOCK_FACE_NORTH: - case BLOCK_FACE_SOUTH: - case BLOCK_FACE_WEST: - { - // When placing onto a sideways face, check cursor, if in top half, make it an upside-down stairs block - if (a_CursorY > 8) - { - a_BlockMeta |= 0x4; - } - break; - } - } - return true; - } - - // TODO: step sound - - - static NIBBLETYPE RotationToMetaData(double a_Rotation) - { - a_Rotation += 90 + 45; // So its not aligned with axis - NIBBLETYPE result = 0x0; - if (a_Rotation > 360) - { - a_Rotation -= 360; - } - if ((a_Rotation >= 0) && (a_Rotation < 90)) - { - return 0x0; - } - else if ((a_Rotation >= 180) && (a_Rotation < 270)) - { - return 0x1; - } - else if ((a_Rotation >= 90) && (a_Rotation < 180)) - { - return 0x2; - } - else - { - return 0x3; - } - } - - - 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: - return (a_Meta & 0x0b) | ((~a_Meta) & 0x04); - } - - - 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; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockStairsHandler : + public cBlockHandler +{ +public: + cBlockStairsHandler(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, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + a_BlockType = m_BlockType; + a_BlockMeta = RotationToMetaData(a_Player->GetRotation()); + switch (a_BlockFace) + { + case BLOCK_FACE_TOP: break; + case BLOCK_FACE_BOTTOM: a_BlockMeta = a_BlockMeta | 0x4; break; // When placing onto a bottom face, always place an upside-down stairs block + case BLOCK_FACE_EAST: + case BLOCK_FACE_NORTH: + case BLOCK_FACE_SOUTH: + case BLOCK_FACE_WEST: + { + // When placing onto a sideways face, check cursor, if in top half, make it an upside-down stairs block + if (a_CursorY > 8) + { + a_BlockMeta |= 0x4; + } + break; + } + } + return true; + } + + // TODO: step sound + + + static NIBBLETYPE RotationToMetaData(double a_Rotation) + { + a_Rotation += 90 + 45; // So its not aligned with axis + NIBBLETYPE result = 0x0; + if (a_Rotation > 360) + { + a_Rotation -= 360; + } + if ((a_Rotation >= 0) && (a_Rotation < 90)) + { + return 0x0; + } + else if ((a_Rotation >= 180) && (a_Rotation < 270)) + { + return 0x1; + } + else if ((a_Rotation >= 90) && (a_Rotation < 180)) + { + return 0x2; + } + else + { + return 0x3; + } + } + + + 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: + return (a_Meta & 0x0b) | ((~a_Meta) & 0x04); + } + + + 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/source/Blocks/BlockStems.h b/source/Blocks/BlockStems.h index 44c4d9cc9..ce02d9cb8 100644 --- a/source/Blocks/BlockStems.h +++ b/source/Blocks/BlockStems.h @@ -1,58 +1,58 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../MersenneTwister.h" -#include "../World.h" - - - - - -class cBlockStemsHandler : - public cBlockHandler -{ -public: - cBlockStemsHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - 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; - a_Pickups.push_back(cItem(ItemType, 1, 0)); - } - - - void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override - { - NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - if (Meta >= 7) - { - // Grow the produce: - a_World->GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, m_BlockType); - } - else - { - // Grow the stem: - a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta + 1); - } - } - - - virtual bool CanBeAt(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)); - } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../MersenneTwister.h" +#include "../World.h" + + + + + +class cBlockStemsHandler : + public cBlockHandler +{ +public: + cBlockStemsHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + 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; + a_Pickups.push_back(cItem(ItemType, 1, 0)); + } + + + void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + if (Meta >= 7) + { + // Grow the produce: + a_World->GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, m_BlockType); + } + else + { + // Grow the stem: + a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta + 1); + } + } + + + virtual bool CanBeAt(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)); + } + + + virtual const char * GetStepSound(void) override + { + return "step.wood"; + } +} ; + + + + diff --git a/source/Blocks/BlockStone.h b/source/Blocks/BlockStone.h index 89bef5969..af4c6509a 100644 --- a/source/Blocks/BlockStone.h +++ b/source/Blocks/BlockStone.h @@ -1,29 +1,29 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../MersenneTwister.h" -#include "../World.h" - - - - - -class cBlockStoneHandler : - public cBlockHandler -{ -public: - cBlockStoneHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - a_Pickups.push_back(cItem(E_BLOCK_COBBLESTONE, 1, 0)); - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../MersenneTwister.h" +#include "../World.h" + + + + + +class cBlockStoneHandler : + public cBlockHandler +{ +public: + cBlockStoneHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem(E_BLOCK_COBBLESTONE, 1, 0)); + } +} ; + + + + diff --git a/source/Blocks/BlockSugarcane.h b/source/Blocks/BlockSugarcane.h index a9503ba37..9d66d6be6 100644 --- a/source/Blocks/BlockSugarcane.h +++ b/source/Blocks/BlockSugarcane.h @@ -1,96 +1,96 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockSugarcaneHandler : - public cBlockHandler -{ -public: - cBlockSugarcaneHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - a_Pickups.push_back(cItem(E_ITEM_SUGARCANE, 1, 0)); - } - - - virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override - { - if (a_RelY <= 0) - { - return false; - } - switch (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)) - { - case E_BLOCK_DIRT: - case E_BLOCK_GRASS: - case E_BLOCK_FARMLAND: - case E_BLOCK_SAND: - { - static const struct - { - int x, z; - } Coords[] = - { - {-1, 0}, - { 1, 0}, - { 0, -1}, - { 0, 1}, - } ; - a_RelY -= 1; - for (int i = 0; i < ARRAYCOUNT(Coords); i++) - { - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - if (!a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta)) - { - // Too close to the edge, cannot simulate - return true; - } - if (IsBlockWater(BlockType)) - { - return true; - } - } // for i - Coords[] - // Not directly neighboring a water block - return false; - } - case E_BLOCK_SUGARCANE: - { - return true; - } - } - return false; - } - - - void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override - { - a_World->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, 1); - } - - - virtual bool CanBePlacedOnSide() override - { - return false; - } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockSugarcaneHandler : + public cBlockHandler +{ +public: + cBlockSugarcaneHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem(E_ITEM_SUGARCANE, 1, 0)); + } + + + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override + { + if (a_RelY <= 0) + { + return false; + } + switch (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)) + { + case E_BLOCK_DIRT: + case E_BLOCK_GRASS: + case E_BLOCK_FARMLAND: + case E_BLOCK_SAND: + { + static const struct + { + int x, z; + } Coords[] = + { + {-1, 0}, + { 1, 0}, + { 0, -1}, + { 0, 1}, + } ; + a_RelY -= 1; + for (int i = 0; i < ARRAYCOUNT(Coords); i++) + { + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + if (!a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta)) + { + // Too close to the edge, cannot simulate + return true; + } + if (IsBlockWater(BlockType)) + { + return true; + } + } // for i - Coords[] + // Not directly neighboring a water block + return false; + } + case E_BLOCK_SUGARCANE: + { + return true; + } + } + return false; + } + + + void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + a_World->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, 1); + } + + + virtual bool CanBePlacedOnSide() override + { + return false; + } + + + virtual const char * GetStepSound(void) override + { + return "step.grass"; + } +} ; + + + + diff --git a/source/Blocks/BlockTallGrass.h b/source/Blocks/BlockTallGrass.h index eea629bf5..cd27ab7e6 100644 --- a/source/Blocks/BlockTallGrass.h +++ b/source/Blocks/BlockTallGrass.h @@ -1,51 +1,51 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockTallGrassHandler : - public cBlockHandler -{ -public: - cBlockTallGrassHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual bool DoesIgnoreBuildCollision(void) override - { - return true; - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - // Drop seeds, sometimes - MTRand r1; - if (r1.randInt(10) == 5) - { - a_Pickups.push_back(cItem(E_ITEM_SEEDS, 1, 0)); - } - } - - - virtual bool CanBeAt(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 - { - return "step.grass"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockTallGrassHandler : + public cBlockHandler +{ +public: + cBlockTallGrassHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual bool DoesIgnoreBuildCollision(void) override + { + return true; + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Drop seeds, sometimes + MTRand r1; + if (r1.randInt(10) == 5) + { + a_Pickups.push_back(cItem(E_ITEM_SEEDS, 1, 0)); + } + } + + + virtual bool CanBeAt(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 + { + return "step.grass"; + } +} ; + + + + diff --git a/source/Blocks/BlockTorch.h b/source/Blocks/BlockTorch.h index 9951b8ea4..00e0a585c 100644 --- a/source/Blocks/BlockTorch.h +++ b/source/Blocks/BlockTorch.h @@ -1,259 +1,259 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../World.h" - - - - - -class cBlockTorchHandler : - public cBlockHandler -{ -public: - cBlockTorchHandler(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, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override - { - // Find proper placement. Use the player-supplied one as the default, but fix if not okay: - if (!TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace)) - { - a_BlockFace = FindSuitableFace(a_World, a_BlockX, a_BlockY, a_BlockZ); - - if (a_BlockFace == BLOCK_FACE_BOTTOM) - { - return false; - } - } - a_BlockType = m_BlockType; - a_BlockMeta = DirectionToMetaData(a_BlockFace); - return true; - } - - - static NIBBLETYPE DirectionToMetaData(char a_Direction) // tolua_export - { // tolua_export - switch (a_Direction) - { - case BLOCK_FACE_BOTTOM: ASSERT(!"Shouldn't be getting this face"); return 0; - case BLOCK_FACE_TOP: return E_META_TORCH_FLOOR; - case BLOCK_FACE_EAST: return E_META_TORCH_EAST; - case BLOCK_FACE_WEST: return E_META_TORCH_WEST; - case BLOCK_FACE_NORTH: return E_META_TORCH_NORTH; - case BLOCK_FACE_SOUTH: return E_META_TORCH_SOUTH; - default: - { - ASSERT(!"Unhandled torch direction!"); - break; - } - }; - return 0x0; - } // tolua_export - - - static char MetaDataToDirection(NIBBLETYPE a_MetaData) // tolua_export - { // tolua_export - switch (a_MetaData) - { - case 0: return BLOCK_FACE_TOP; // by default, the torches stand on the ground - case E_META_TORCH_FLOOR: return BLOCK_FACE_TOP; - case E_META_TORCH_EAST: return BLOCK_FACE_EAST; - case E_META_TORCH_WEST: return BLOCK_FACE_WEST; - case E_META_TORCH_NORTH: return BLOCK_FACE_NORTH; - case E_META_TORCH_SOUTH: return BLOCK_FACE_SOUTH; - default: - { - ASSERT(!"Unhandled torch metadata"); - break; - } - } - return 0; - } // tolua_export - - - static bool IsAttachedTo(const Vector3i & a_TorchPos, char a_TorchMeta, const Vector3i & a_BlockPos) - { - switch (a_TorchMeta) - { - case 0x0: - case E_META_TORCH_FLOOR: return ((a_TorchPos - a_BlockPos).Equals(Vector3i(0, 1, 0))); - case E_META_TORCH_EAST: return ((a_TorchPos - a_BlockPos).Equals(Vector3i(0, 0, -1))); - case E_META_TORCH_WEST: return ((a_TorchPos - a_BlockPos).Equals(Vector3i(0, 0, 1))); - case E_META_TORCH_NORTH: return ((a_TorchPos - a_BlockPos).Equals(Vector3i(-1, 0, 0))); - case E_META_TORCH_SOUTH: return ((a_TorchPos - a_BlockPos).Equals(Vector3i(1, 0, 0))); - default: - { - ASSERT(!"Unhandled torch meta!"); - break; - } - } - return false; - } - - - virtual bool DoesAllowBlockOnTop(void) override - { - return false; - } - - - static bool CanBePlacedOn(BLOCKTYPE a_BlockType, char a_Direction) - { - switch (a_BlockType) - { - case E_BLOCK_GLASS: - case E_BLOCK_FENCE: - case E_BLOCK_NETHER_BRICK_FENCE: - { - return (a_Direction == 0x1); // allow only direction "standing on floor" - } - - default: - { - return g_BlockIsSolid[a_BlockType]; - } - } - } - - - static bool TorchCanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) - { - // TODO: If placing a torch from below, check all 4 XZ neighbors, place it on that neighbor instead - // How to propagate that change up? - // Simon: The easiest way is to calculate the position two times, shouldn´t cost much cpu power :) - - if (a_BlockFace == BLOCK_FACE_BOTTOM) - { - return false; - } - - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); - - return CanBePlacedOn(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ), a_BlockFace); - } - - - /// Finds a suitable Face for the Torch. Returns BLOCK_FACE_BOTTOM on failure - static char FindSuitableFace(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) - { - for (int i = 1; i <= 5; i++) - { - if (TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, i)) - { - return i; - } - } - return BLOCK_FACE_BOTTOM; - } - - - /* - virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override - { - if (TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace)) - { - return true; - } - - return (FindSuitableFace(a_World, a_BlockX, a_BlockY, a_BlockZ) != BLOCK_FACE_BOTTOM); - } - */ - - - virtual bool CanBeAt(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 Face = 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 TorchCanBePlacedAt(a_Chunk.GetWorld(), BlockX, a_RelY, BlockZ, Face); - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - // Always drop meta = 0 - a_Pickups.push_back(cItem(m_BlockType, 1, 0)); - } - - - virtual const char * GetStepSound(void) override - { - 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 - } - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../World.h" + + + + + +class cBlockTorchHandler : + public cBlockHandler +{ +public: + cBlockTorchHandler(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, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + // Find proper placement. Use the player-supplied one as the default, but fix if not okay: + if (!TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace)) + { + a_BlockFace = FindSuitableFace(a_World, a_BlockX, a_BlockY, a_BlockZ); + + if (a_BlockFace == BLOCK_FACE_BOTTOM) + { + return false; + } + } + a_BlockType = m_BlockType; + a_BlockMeta = DirectionToMetaData(a_BlockFace); + return true; + } + + + static NIBBLETYPE DirectionToMetaData(char a_Direction) // tolua_export + { // tolua_export + switch (a_Direction) + { + case BLOCK_FACE_BOTTOM: ASSERT(!"Shouldn't be getting this face"); return 0; + case BLOCK_FACE_TOP: return E_META_TORCH_FLOOR; + case BLOCK_FACE_EAST: return E_META_TORCH_EAST; + case BLOCK_FACE_WEST: return E_META_TORCH_WEST; + case BLOCK_FACE_NORTH: return E_META_TORCH_NORTH; + case BLOCK_FACE_SOUTH: return E_META_TORCH_SOUTH; + default: + { + ASSERT(!"Unhandled torch direction!"); + break; + } + }; + return 0x0; + } // tolua_export + + + static char MetaDataToDirection(NIBBLETYPE a_MetaData) // tolua_export + { // tolua_export + switch (a_MetaData) + { + case 0: return BLOCK_FACE_TOP; // by default, the torches stand on the ground + case E_META_TORCH_FLOOR: return BLOCK_FACE_TOP; + case E_META_TORCH_EAST: return BLOCK_FACE_EAST; + case E_META_TORCH_WEST: return BLOCK_FACE_WEST; + case E_META_TORCH_NORTH: return BLOCK_FACE_NORTH; + case E_META_TORCH_SOUTH: return BLOCK_FACE_SOUTH; + default: + { + ASSERT(!"Unhandled torch metadata"); + break; + } + } + return 0; + } // tolua_export + + + static bool IsAttachedTo(const Vector3i & a_TorchPos, char a_TorchMeta, const Vector3i & a_BlockPos) + { + switch (a_TorchMeta) + { + case 0x0: + case E_META_TORCH_FLOOR: return ((a_TorchPos - a_BlockPos).Equals(Vector3i(0, 1, 0))); + case E_META_TORCH_EAST: return ((a_TorchPos - a_BlockPos).Equals(Vector3i(0, 0, -1))); + case E_META_TORCH_WEST: return ((a_TorchPos - a_BlockPos).Equals(Vector3i(0, 0, 1))); + case E_META_TORCH_NORTH: return ((a_TorchPos - a_BlockPos).Equals(Vector3i(-1, 0, 0))); + case E_META_TORCH_SOUTH: return ((a_TorchPos - a_BlockPos).Equals(Vector3i(1, 0, 0))); + default: + { + ASSERT(!"Unhandled torch meta!"); + break; + } + } + return false; + } + + + virtual bool DoesAllowBlockOnTop(void) override + { + return false; + } + + + static bool CanBePlacedOn(BLOCKTYPE a_BlockType, char a_Direction) + { + switch (a_BlockType) + { + case E_BLOCK_GLASS: + case E_BLOCK_FENCE: + case E_BLOCK_NETHER_BRICK_FENCE: + { + return (a_Direction == 0x1); // allow only direction "standing on floor" + } + + default: + { + return g_BlockIsSolid[a_BlockType]; + } + } + } + + + static bool TorchCanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) + { + // TODO: If placing a torch from below, check all 4 XZ neighbors, place it on that neighbor instead + // How to propagate that change up? + // Simon: The easiest way is to calculate the position two times, shouldn´t cost much cpu power :) + + if (a_BlockFace == BLOCK_FACE_BOTTOM) + { + return false; + } + + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); + + return CanBePlacedOn(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ), a_BlockFace); + } + + + /// Finds a suitable Face for the Torch. Returns BLOCK_FACE_BOTTOM on failure + static char FindSuitableFace(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) + { + for (int i = 1; i <= 5; i++) + { + if (TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, i)) + { + return i; + } + } + return BLOCK_FACE_BOTTOM; + } + + + /* + virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override + { + if (TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace)) + { + return true; + } + + return (FindSuitableFace(a_World, a_BlockX, a_BlockY, a_BlockZ) != BLOCK_FACE_BOTTOM); + } + */ + + + virtual bool CanBeAt(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 Face = 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 TorchCanBePlacedAt(a_Chunk.GetWorld(), BlockX, a_RelY, BlockZ, Face); + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Always drop meta = 0 + a_Pickups.push_back(cItem(m_BlockType, 1, 0)); + } + + + virtual const char * GetStepSound(void) override + { + 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/source/Blocks/BlockVine.h b/source/Blocks/BlockVine.h index 2a88c9b68..0bc935272 100644 --- a/source/Blocks/BlockVine.h +++ b/source/Blocks/BlockVine.h @@ -1,200 +1,200 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockVineHandler : - public cBlockHandler -{ -public: - cBlockVineHandler(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, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override - { - // 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); - if (BlockType == m_BlockType) - { - a_BlockMeta = BlockMeta | DirectionToMetaData(a_BlockFace); - } - else - { - a_BlockMeta = DirectionToMetaData(a_BlockFace); - } - a_BlockType = m_BlockType; - return true; - } - - - static NIBBLETYPE DirectionToMetaData(char a_BlockFace) - { - switch (a_BlockFace) - { - case BLOCK_FACE_NORTH: return 0x1; - case BLOCK_FACE_SOUTH: return 0x4; - case BLOCK_FACE_WEST: return 0x8; - case BLOCK_FACE_EAST: return 0x2; - default: return 0x0; - } - } - - - static char MetaDataToDirection(NIBBLETYPE a_MetaData) - { - switch(a_MetaData) - { - case 0x1: return BLOCK_FACE_NORTH; - case 0x4: return BLOCK_FACE_SOUTH; - case 0x8: return BLOCK_FACE_WEST; - case 0x2: return BLOCK_FACE_EAST; - default: return BLOCK_FACE_TOP; - } - } - - - /// 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]; - } - - - /// Returns the meta that has the maximum allowable sides of the vine, given the surroundings - NIBBLETYPE GetMaxMeta(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) - { - static const struct - { - int x, z; - int Bit; - } Coords[] = - { - { 0, 1, 1}, // south, ZP - {-1, 0, 2}, // west, XM - { 0, -1, 4}, // north, ZM - { 1, 0, 8}, // east, XP - } ; - int res = 0; - for (int i = 0; i < ARRAYCOUNT(Coords); i++) - { - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - if ( - a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta) && - IsBlockAttachable(BlockType) - ) - { - res |= Coords[i].Bit; - } - } - return res; - } - - - void Check(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); - - // Check if vine above us, add its meta to MaxMeta - if ((a_RelY < cChunkDef::Height - 1) && (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ) == m_BlockType)) - { - MaxMeta |= a_Chunk.GetMeta(a_RelX, a_RelY + 1, a_RelZ); - } - - NIBBLETYPE Common = CurMeta & MaxMeta; // Neighbors that we have and are legal - if (Common != CurMeta) - { - // There is a neighbor missing, need to update the meta or even destroy the block - bool HasTop = (a_RelY < cChunkDef::Height - 1) && IsBlockAttachable(a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ)); - if ((Common == 0) && !HasTop) - { - // The vine just lost all its support, destroy the block: - 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); - } - a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0); - return; - } - a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, Common); - } - else - { - // Wake up the simulators for this block: - int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; - int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; - a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp(BlockX, a_RelY, BlockZ, &a_Chunk); - } - } - - - virtual bool DoesIgnoreBuildCollision(void) override - { - return true; - } - - - virtual bool DoesAllowBlockOnTop(void) override - { - return false; - } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } - - - virtual bool DoesDropOnUnsuitable(void) override - { - return false; - } - - - virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override - { - return ((a_Meta >> 1) | (a_Meta << 3)) & 0x0f; // Rotate bits to the right - } - - - virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override - { - 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)); - } - - - 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)); - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockVineHandler : + public cBlockHandler +{ +public: + cBlockVineHandler(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, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + // 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); + if (BlockType == m_BlockType) + { + a_BlockMeta = BlockMeta | DirectionToMetaData(a_BlockFace); + } + else + { + a_BlockMeta = DirectionToMetaData(a_BlockFace); + } + a_BlockType = m_BlockType; + return true; + } + + + static NIBBLETYPE DirectionToMetaData(char a_BlockFace) + { + switch (a_BlockFace) + { + case BLOCK_FACE_NORTH: return 0x1; + case BLOCK_FACE_SOUTH: return 0x4; + case BLOCK_FACE_WEST: return 0x8; + case BLOCK_FACE_EAST: return 0x2; + default: return 0x0; + } + } + + + static char MetaDataToDirection(NIBBLETYPE a_MetaData) + { + switch(a_MetaData) + { + case 0x1: return BLOCK_FACE_NORTH; + case 0x4: return BLOCK_FACE_SOUTH; + case 0x8: return BLOCK_FACE_WEST; + case 0x2: return BLOCK_FACE_EAST; + default: return BLOCK_FACE_TOP; + } + } + + + /// 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]; + } + + + /// Returns the meta that has the maximum allowable sides of the vine, given the surroundings + NIBBLETYPE GetMaxMeta(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) + { + static const struct + { + int x, z; + int Bit; + } Coords[] = + { + { 0, 1, 1}, // south, ZP + {-1, 0, 2}, // west, XM + { 0, -1, 4}, // north, ZM + { 1, 0, 8}, // east, XP + } ; + int res = 0; + for (int i = 0; i < ARRAYCOUNT(Coords); i++) + { + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + if ( + a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta) && + IsBlockAttachable(BlockType) + ) + { + res |= Coords[i].Bit; + } + } + return res; + } + + + void Check(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); + + // Check if vine above us, add its meta to MaxMeta + if ((a_RelY < cChunkDef::Height - 1) && (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ) == m_BlockType)) + { + MaxMeta |= a_Chunk.GetMeta(a_RelX, a_RelY + 1, a_RelZ); + } + + NIBBLETYPE Common = CurMeta & MaxMeta; // Neighbors that we have and are legal + if (Common != CurMeta) + { + // There is a neighbor missing, need to update the meta or even destroy the block + bool HasTop = (a_RelY < cChunkDef::Height - 1) && IsBlockAttachable(a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ)); + if ((Common == 0) && !HasTop) + { + // The vine just lost all its support, destroy the block: + 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); + } + a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0); + return; + } + a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, Common); + } + else + { + // Wake up the simulators for this block: + int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; + int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; + a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp(BlockX, a_RelY, BlockZ, &a_Chunk); + } + } + + + virtual bool DoesIgnoreBuildCollision(void) override + { + return true; + } + + + virtual bool DoesAllowBlockOnTop(void) override + { + return false; + } + + + virtual const char * GetStepSound(void) override + { + return "step.grass"; + } + + + virtual bool DoesDropOnUnsuitable(void) override + { + return false; + } + + + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override + { + return ((a_Meta >> 1) | (a_Meta << 3)) & 0x0f; // Rotate bits to the right + } + + + virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override + { + 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)); + } + + + 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)); + } +} ; + + + + diff --git a/source/Blocks/BlockWood.h b/source/Blocks/BlockWood.h index 907fb587c..4e2246506 100644 --- a/source/Blocks/BlockWood.h +++ b/source/Blocks/BlockWood.h @@ -1,27 +1,27 @@ - -#pragma once - -#include "BlockHandler.h" - - - - - -class cBlockWoodHandler : public cBlockHandler -{ -public: - cBlockWoodHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) - { - } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockWoodHandler : public cBlockHandler +{ +public: + cBlockWoodHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual const char * GetStepSound(void) override + { + return "step.wood"; + } +} ; + + + + diff --git a/source/Blocks/BlockWorkbench.h b/source/Blocks/BlockWorkbench.h index ccd1ded9a..60aa1791b 100644 --- a/source/Blocks/BlockWorkbench.h +++ b/source/Blocks/BlockWorkbench.h @@ -1,43 +1,43 @@ - -#pragma once - -#include "BlockHandler.h" -#include "../UI/Window.h" -#include "../Player.h" - - - - - -class cBlockWorkbenchHandler: - public cBlockHandler -{ -public: - cBlockWorkbenchHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(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 - { - cWindow * Window = new cCraftingWindow(a_BlockX, a_BlockY, a_BlockZ); - a_Player->OpenWindow(Window); - } - - - virtual bool IsUseable(void) override - { - return true; - } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } -} ; - - - - + +#pragma once + +#include "BlockHandler.h" +#include "../UI/Window.h" +#include "../Player.h" + + + + + +class cBlockWorkbenchHandler: + public cBlockHandler +{ +public: + cBlockWorkbenchHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(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 + { + cWindow * Window = new cCraftingWindow(a_BlockX, a_BlockY, a_BlockZ); + a_Player->OpenWindow(Window); + } + + + virtual bool IsUseable(void) override + { + return true; + } + + + virtual const char * GetStepSound(void) override + { + return "step.wood"; + } +} ; + + + + -- cgit v1.2.3