From 14dce238450b419a5df2aa171ee91981910463b0 Mon Sep 17 00:00:00 2001 From: "lapayo94@gmail.com" Date: Sun, 15 Jul 2012 20:36:34 +0000 Subject: A new Block handling system :o It was really a lot of work :D Took me the complete weekend :D Would really like to here your opinion on this =) The aim of this is to put all the actions for one block in one place so it is not spread around the source. (ToPickup, Action in cWorld, Action in cChunk, Action here, action there :D) git-svn-id: http://mc-server.googlecode.com/svn/trunk@671 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/blocks/Block.cpp | 302 ++++++++++++++++++++++++++++++++ source/blocks/Block.h | 54 ++++++ source/blocks/BlockCactus.h | 51 ++++++ source/blocks/BlockChest.h | 22 +++ source/blocks/BlockCloth.cpp | 9 + source/blocks/BlockCloth.h | 14 ++ source/blocks/BlockCrops.h | 56 ++++++ source/blocks/BlockDirt.cpp | 9 + source/blocks/BlockDirt.h | 62 +++++++ source/blocks/BlockDispenser.h | 22 +++ source/blocks/BlockDoor.cpp | 60 +++++++ source/blocks/BlockDoor.h | 29 +++ source/blocks/BlockEntity.cpp | 15 ++ source/blocks/BlockEntity.h | 16 ++ source/blocks/BlockFire.cpp | 24 +++ source/blocks/BlockFire.h | 14 ++ source/blocks/BlockFlower.h | 32 ++++ source/blocks/BlockFluid.h | 20 +++ source/blocks/BlockFurnace.h | 27 +++ source/blocks/BlockGlowstone.h | 22 +++ source/blocks/BlockIce.h | 26 +++ source/blocks/BlockLadder.h | 28 +++ source/blocks/BlockLeaves.h | 162 +++++++++++++++++ source/blocks/BlockMelon.h | 24 +++ source/blocks/BlockMushroom.h | 42 +++++ source/blocks/BlockPiston.cpp | 51 ++++++ source/blocks/BlockPiston.h | 15 ++ source/blocks/BlockRedstone.cpp | 41 +++++ source/blocks/BlockRedstone.h | 33 ++++ source/blocks/BlockRedstoneOre.h | 26 +++ source/blocks/BlockRedstoneRepeater.cpp | 34 ++++ source/blocks/BlockRedstoneRepeater.h | 46 +++++ source/blocks/BlockRedstoneTorch.h | 30 ++++ source/blocks/BlockSapling.h | 51 ++++++ source/blocks/BlockSign.h | 42 +++++ source/blocks/BlockSlab.cpp | 17 ++ source/blocks/BlockSlab.h | 33 ++++ source/blocks/BlockSnow.h | 39 +++++ source/blocks/BlockStairs.cpp | 18 ++ source/blocks/BlockStairs.h | 14 ++ source/blocks/BlockStems.h | 41 +++++ source/blocks/BlockStone.h | 18 ++ source/blocks/BlockSugarcane.h | 43 +++++ source/blocks/BlockTallGrass.h | 35 ++++ source/blocks/BlockTorch.cpp | 15 ++ source/blocks/BlockTorch.h | 25 +++ source/blocks/BlockVine.cpp | 17 ++ source/blocks/BlockVine.h | 23 +++ source/blocks/BlockWood.h | 17 ++ source/blocks/BlockWorkbench.cpp | 24 +++ source/blocks/BlockWorkbench.h | 19 ++ 51 files changed, 1909 insertions(+) create mode 100644 source/blocks/Block.cpp create mode 100644 source/blocks/Block.h create mode 100644 source/blocks/BlockCactus.h create mode 100644 source/blocks/BlockChest.h create mode 100644 source/blocks/BlockCloth.cpp create mode 100644 source/blocks/BlockCloth.h create mode 100644 source/blocks/BlockCrops.h create mode 100644 source/blocks/BlockDirt.cpp create mode 100644 source/blocks/BlockDirt.h create mode 100644 source/blocks/BlockDispenser.h create mode 100644 source/blocks/BlockDoor.cpp create mode 100644 source/blocks/BlockDoor.h create mode 100644 source/blocks/BlockEntity.cpp create mode 100644 source/blocks/BlockEntity.h create mode 100644 source/blocks/BlockFire.cpp create mode 100644 source/blocks/BlockFire.h create mode 100644 source/blocks/BlockFlower.h create mode 100644 source/blocks/BlockFluid.h create mode 100644 source/blocks/BlockFurnace.h create mode 100644 source/blocks/BlockGlowstone.h create mode 100644 source/blocks/BlockIce.h create mode 100644 source/blocks/BlockLadder.h create mode 100644 source/blocks/BlockLeaves.h create mode 100644 source/blocks/BlockMelon.h create mode 100644 source/blocks/BlockMushroom.h create mode 100644 source/blocks/BlockPiston.cpp create mode 100644 source/blocks/BlockPiston.h create mode 100644 source/blocks/BlockRedstone.cpp create mode 100644 source/blocks/BlockRedstone.h create mode 100644 source/blocks/BlockRedstoneOre.h create mode 100644 source/blocks/BlockRedstoneRepeater.cpp create mode 100644 source/blocks/BlockRedstoneRepeater.h create mode 100644 source/blocks/BlockRedstoneTorch.h create mode 100644 source/blocks/BlockSapling.h create mode 100644 source/blocks/BlockSign.h create mode 100644 source/blocks/BlockSlab.cpp create mode 100644 source/blocks/BlockSlab.h create mode 100644 source/blocks/BlockSnow.h create mode 100644 source/blocks/BlockStairs.cpp create mode 100644 source/blocks/BlockStairs.h create mode 100644 source/blocks/BlockStems.h create mode 100644 source/blocks/BlockStone.h create mode 100644 source/blocks/BlockSugarcane.h create mode 100644 source/blocks/BlockTallGrass.h create mode 100644 source/blocks/BlockTorch.cpp create mode 100644 source/blocks/BlockTorch.h create mode 100644 source/blocks/BlockVine.cpp create mode 100644 source/blocks/BlockVine.h create mode 100644 source/blocks/BlockWood.h create mode 100644 source/blocks/BlockWorkbench.cpp create mode 100644 source/blocks/BlockWorkbench.h (limited to 'source/blocks') diff --git a/source/blocks/Block.cpp b/source/blocks/Block.cpp new file mode 100644 index 000000000..047caa989 --- /dev/null +++ b/source/blocks/Block.cpp @@ -0,0 +1,302 @@ +#include "Globals.h" +#include "Block.h" +#include "../cItem.h" +#include "../cWorld.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 "BlockDispenser.h" +#include "BlockStairs.h" +#include "BlockLadder.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 "BlockRedstoneOre.h" +#include "BlockStone.h" +#include "BlockMelon.h" +#include "BlockIce.h" + +bool cBlockHandler::m_HandlerInitialized = false; +cBlockHandler *cBlockHandler::m_BlockHandler[256]; + +cBlockHandler *cBlockHandler::GetBlockHandler(char a_BlockID) +{ + if(!m_HandlerInitialized) + { //We have to initialize + memset(m_BlockHandler, 0, sizeof(m_BlockHandler)); + m_HandlerInitialized = true; + } + if(m_BlockHandler[a_BlockID]) + return m_BlockHandler[a_BlockID]; + + return m_BlockHandler[a_BlockID] = CreateBlockHandler(a_BlockID); +} + +cBlockHandler *cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockID) +{ + switch(a_BlockID) + { + case E_BLOCK_WOODEN_DOOR: + case E_BLOCK_IRON_DOOR: + return new cBlockDoorHandler(a_BlockID); + case E_BLOCK_FIRE: + return new cBlockFireHandler(a_BlockID); + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_REDSTONE_TORCH_OFF: + return new cBlockRedstoneTorchHandler(a_BlockID); + case E_BLOCK_REDSTONE_WIRE: + return new cBlockRedstoneHandler(a_BlockID); + case E_BLOCK_PISTON: + case E_BLOCK_STICKY_PISTON: + return new cBlockPistonHandler(a_BlockID); + case E_BLOCK_REDSTONE_REPEATER_ON: + case E_BLOCK_REDSTONE_REPEATER_OFF: + return new cBlockRedstoneRepeaterHandler(a_BlockID); + case E_BLOCK_WORKBENCH: + return new cBlockWorkbenchHandler(a_BlockID); + case E_BLOCK_SNOW: + return new cBlockSnowHandler(a_BlockID); + case E_BLOCK_TALL_GRASS: + return new cBlockTallGrassHandler(a_BlockID); + case E_BLOCK_VINES: + return new cBlockVineHandler(a_BlockID); + case ::E_BLOCK_WOOL: + return new cBlockClothHandler(a_BlockID); + case E_BLOCK_WOODEN_SLAB: + case E_BLOCK_STONE_SLAB: + case E_BLOCK_DOUBLE_WOODEN_SLAB: + case E_BLOCK_DOUBLE_STONE_SLAB: + return new cBlockSlabHandler(a_BlockID); + case E_BLOCK_LOG: + case E_BLOCK_PLANKS: + return new cBlockWoodHandler(a_BlockID); + case E_BLOCK_TORCH: + return new cBlockTorchHandler(a_BlockID); + case E_BLOCK_DIRT: + case E_BLOCK_GRASS: + return new cBlockDirtHandler(a_BlockID); + case E_BLOCK_LEAVES: + return new cBlockLeavesHandler(a_BlockID); + case E_BLOCK_SAPLING: + return new cBlockSaplingHandler(a_BlockID); + case E_BLOCK_WATER: + case E_BLOCK_STATIONARY_WATER: + case E_BLOCK_STATIONARY_LAVA: + case E_BLOCK_LAVA: + return new cBlockFluidHandler(a_BlockID); + case E_BLOCK_DISPENSER: + return new cBlockDispenserHandler(a_BlockID); + case E_BLOCK_FURNACE: + case E_BLOCK_LIT_FURNACE: + return new cBlockFurnaceHandler(a_BlockID); + case E_BLOCK_CHEST: + return new cBlockChestHandler(a_BlockID); + case E_BLOCK_ICE: + return new cBlockIceHandler(a_BlockID); + case E_BLOCK_LADDER: + return new cBlockLadderHandler(a_BlockID); + case E_BLOCK_COBBLESTONE_STAIRS: + case E_BLOCK_BRICK_STAIRS: + case E_BLOCK_STONE_BRICK_STAIRS: + case E_BLOCK_NETHER_BRICK_STAIRS: + case E_BLOCK_WOODEN_STAIRS: + return new cBlockStairsHandler(a_BlockID); + case E_BLOCK_SIGN_POST: + case E_BLOCK_WALLSIGN: + return new cBlockSignHandler(a_BlockID); + case E_BLOCK_CROPS: + return new cBlockCropsHandler(a_BlockID); + case E_BLOCK_SUGARCANE: + return new cBlockSugarcaneHandler(a_BlockID); + case E_BLOCK_YELLOW_FLOWER: + case E_BLOCK_RED_ROSE: + return new cBlockFlowerHandler(a_BlockID); + case E_BLOCK_BROWN_MUSHROOM: + case E_BLOCK_RED_MUSHROOM: + return new cBlockMushroomHandler(a_BlockID); + case E_BLOCK_CACTUS: + return new cBlockCactusHandler(a_BlockID); + case E_BLOCK_MELON_STEM: + case E_BLOCK_PUMPKIN_STEM: + return new cBlockStemsHandler(a_BlockID); + case E_BLOCK_GLOWSTONE: + return new cBlockGlowstoneHandler(a_BlockID); + case E_BLOCK_REDSTONE_ORE: + case E_BLOCK_REDSTONE_ORE_GLOWING: + return new cBlockRedstoneOreHandler(a_BlockID); + case E_BLOCK_STONE: + case E_BLOCK_COBBLESTONE: + return new cBlockStoneHandler(a_BlockID); + case E_BLOCK_MELON: + return new cBlockMelonHandler(a_BlockID); + default: + return new cBlockHandler(a_BlockID); + break; + } +} + +void cBlockHandler::Deinit() +{ + for(int i = 0; i < 256; i++) + { + delete m_BlockHandler[i]; + } +} + +cBlockHandler::cBlockHandler(BLOCKTYPE a_BlockID) +{ + m_BlockID = a_BlockID; +} + +void cBlockHandler::OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z) +{ + +} + +void cBlockHandler::OnPlacedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_X, int a_Y, int a_Z, int a_Dir) +{ +} + +void cBlockHandler::OnDestroyedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_X, int a_Y, int a_Z) +{ +} + +void cBlockHandler::OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir) +{ + //Notify the neighbors + NeighborChanged(a_World, a_X - 1, a_Y, a_Z); + NeighborChanged(a_World, a_X + 1, a_Y, a_Z); + NeighborChanged(a_World, a_X, a_Y - 1, a_Z); + NeighborChanged(a_World, a_X, a_Y + 1, a_Z); + NeighborChanged(a_World, a_X, a_Y, a_Z - 1); + NeighborChanged(a_World, a_X, a_Y, a_Z + 1); +} + +void cBlockHandler::OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) +{ + //Notify the neighbors + NeighborChanged(a_World, a_X - 1, a_Y, a_Z); + NeighborChanged(a_World, a_X + 1, a_Y, a_Z); + NeighborChanged(a_World, a_X, a_Y - 1, a_Z); + NeighborChanged(a_World, a_X, a_Y + 1, a_Z); + NeighborChanged(a_World, a_X, a_Y, a_Z - 1); + NeighborChanged(a_World, a_X, a_Y, a_Z + 1); +} + +void cBlockHandler::NeighborChanged(cWorld *a_World, int a_X, int a_Y, int a_Z) +{ + GetBlockHandler(a_World->GetBlock(a_X, a_Y, a_Z))->OnNeighborChanged(a_World, a_X, a_Y, a_Z); +} + +void cBlockHandler::OnNeighborChanged(cWorld *a_World, int a_X, int a_Y, int a_Z) +{ + +} + +void cBlockHandler::OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) +{ + +} + +void cBlockHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) +{ + a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, a_BlockMeta); + OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir); +} + + +int cBlockHandler::GetTickRate() +{ + return 10; +} + +char cBlockHandler::GetDropCount() +{ + return 1; +} + +int cBlockHandler::GetDropID() +{ + return m_BlockID; +} + +char cBlockHandler::GetDropMeta(char a_BlockMeta) +{ + return a_BlockMeta; //This keeps most textures. The few other blocks have to override this +} + +void cBlockHandler::DropBlock(cWorld *a_World, int a_X, int a_Y, int a_Z) +{ + cItems Drops; + char Meta = a_World->GetBlockMeta(a_X, a_Y, a_Z); + char DropCount = GetDropCount(); + int DropItem = GetDropID(); + if(DropCount > 0 && DropItem != E_ITEM_EMPTY) + { + Drops.push_back(cItem((ENUM_ITEM_ID)DropItem, DropCount, GetDropMeta(Meta))); + a_World->SpawnItemPickups(Drops, a_X, a_Y, a_Z); + } +} + +bool cBlockHandler::CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) +{ + return true; +} + +bool cBlockHandler::IsUseable() +{ + return false; +} + +bool cBlockHandler::IsClickedThrough() +{ + return false; +} + +bool cBlockHandler::IgnoreBuildCollision() +{ + return m_BlockID == E_BLOCK_AIR; +} + +bool cBlockHandler::NeedsRandomTicks() +{ + return false; +} + +bool cBlockHandler::AllowBlockOnTop() +{ + return true; +} + +bool cBlockHandler::CanBePlacedOnSide() +{ + return true; +} + +bool cBlockHandler::DropOnUnsuitable() +{ + return true; +} \ No newline at end of file diff --git a/source/blocks/Block.h b/source/blocks/Block.h new file mode 100644 index 000000000..09cff8487 --- /dev/null +++ b/source/blocks/Block.h @@ -0,0 +1,54 @@ +#pragma once +#include "../Defines.h" + +class cWorld; +class cPlayer; + + + +class cBlockHandler +{ +public: + cBlockHandler(BLOCKTYPE a_BlockID); + //Called when the block gets ticked + virtual void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z); + virtual void OnPlacedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_X, int a_Y, int a_Z, int a_Dir); + virtual void OnDestroyedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_X, int a_Y, int a_Z); + virtual void OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir); + virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z); + virtual void OnNeighborChanged(cWorld *a_World, int a_X, int a_Y, int a_Z); + static void NeighborChanged(cWorld *a_World, int a_X, int a_Y, int a_Z); + virtual void OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z); + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir); + + virtual int GetTickRate(); + virtual char GetDropCount(); + virtual int GetDropID(); + virtual char GetDropMeta(char a_BlockMeta); + virtual bool NeedsRandomTicks(); + //Item is -2 if it wasn´t a player + virtual void DropBlock(cWorld *a_World, int a_X, int a_Y, int a_Z); + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z); + //This gets called if the player tries to place a block ontop of this block (Only if he aims directly on this block) + virtual bool AllowBlockOnTop(); + virtual bool IsUseable(); + virtual bool IsClickedThrough(); + virtual bool IgnoreBuildCollision(); + //Indicates this block can be placed on the side of other blocks. Default: true + virtual bool CanBePlacedOnSide(); + //Does this block drops if it gets destroyed by an unsuitable situation? Default: true + virtual bool DropOnUnsuitable(); + + static cBlockHandler *GetBlockHandler(char a_BlockID); + + static void Deinit(); + +protected: + char m_BlockID; + static cBlockHandler *CreateBlockHandler(BLOCKTYPE a_BlockID); + static cBlockHandler *m_BlockHandler[256]; + static bool m_HandlerInitialized; //used to detect if the blockhandlers are initialized +}; + + +inline cBlockHandler *BlockHandler(char a_BlockID) { return cBlockHandler::GetBlockHandler(a_BlockID); } \ No newline at end of file diff --git a/source/blocks/BlockCactus.h b/source/blocks/BlockCactus.h new file mode 100644 index 000000000..4977d4a98 --- /dev/null +++ b/source/blocks/BlockCactus.h @@ -0,0 +1,51 @@ +#pragma once +#include "Block.h" + + +class cBlockCactusHandler : public cBlockHandler +{ +public: + cBlockCactusHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual char GetDropMeta(char a_BlockMeta) + { + return 0; + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + BLOCKTYPE Surface = a_World->GetBlock(a_X, a_Y - 1, a_Z); + 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 + if ( + (a_World->GetBlock(a_X - 1, a_Y, a_Z) != E_BLOCK_AIR) || + (a_World->GetBlock(a_X + 1, a_Y, a_Z) != E_BLOCK_AIR) || + (a_World->GetBlock(a_X, a_Y, a_Z - 1) != E_BLOCK_AIR) || + (a_World->GetBlock(a_X, a_Y, a_Z + 1) != E_BLOCK_AIR) + ) + { + return false; + } + + return true; + } + + virtual bool AllowBlockOnTop() + { + return false; + } + + + virtual bool CanBePlacedOnSide() + { + return false; + } +}; \ No newline at end of file diff --git a/source/blocks/BlockChest.h b/source/blocks/BlockChest.h new file mode 100644 index 000000000..557b2d640 --- /dev/null +++ b/source/blocks/BlockChest.h @@ -0,0 +1,22 @@ +#pragma once +#include "BlockEntity.h" +#include "../cWorld.h" +#include "../cPiston.h" +#include "../cPlayer.h" + +class cBlockChestHandler : public cBlockEntityHandler +{ +public: + cBlockChestHandler(BLOCKTYPE a_BlockID) + : cBlockEntityHandler(a_BlockID) + { + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) + { + a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0)); + OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir); + } + + +}; \ No newline at end of file diff --git a/source/blocks/BlockCloth.cpp b/source/blocks/BlockCloth.cpp new file mode 100644 index 000000000..a55b8dc7f --- /dev/null +++ b/source/blocks/BlockCloth.cpp @@ -0,0 +1,9 @@ +#include "Globals.h" +#include "BlockCloth.h" +#include "../cItem.h" +#include "../cPlayer.h" + +cBlockClothHandler::cBlockClothHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) +{ +} \ No newline at end of file diff --git a/source/blocks/BlockCloth.h b/source/blocks/BlockCloth.h new file mode 100644 index 000000000..dca7184cb --- /dev/null +++ b/source/blocks/BlockCloth.h @@ -0,0 +1,14 @@ +#pragma once +#include "Block.h" + + +class cBlockClothHandler : public cBlockHandler +{ +public: + cBlockClothHandler(BLOCKTYPE a_BlockID); + char GetDropMeta(char a_BlockMeta) + { + return a_BlockMeta; + } + +}; \ No newline at end of file diff --git a/source/blocks/BlockCrops.h b/source/blocks/BlockCrops.h new file mode 100644 index 000000000..34af1a43c --- /dev/null +++ b/source/blocks/BlockCrops.h @@ -0,0 +1,56 @@ +#pragma once +#include "Block.h" +#include "../MersenneTwister.h" +#include "../cWorld.h" + +class cBlockCropsHandler : public cBlockHandler +{ +public: + cBlockCropsHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual bool NeedsRandomTicks() override + { + return true; + } + + virtual int GetDropID() + { + return E_ITEM_EMPTY; + } + + virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + MTRand rand; + NIBBLETYPE Meta = a_World->GetBlockMeta(a_X, a_Y, a_Z); + + ENUM_ITEM_ID Drop = E_ITEM_EMPTY; + + cItems Drops; + + if(Meta & 0x7) //Is Wheat + { + Drops.push_back(cItem(E_ITEM_WHEAT, 1, 0)); + } + if(rand.randInt(3) == 0) + { //Drop an second seed + Drops.push_back(cItem(E_ITEM_SEEDS, 1, 0)); + } + Drops.push_back(cItem(E_ITEM_SEEDS, 1, 0)); + a_World->SpawnItemPickups(Drops, a_X, a_Y, a_Z); + } + + void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + + //TODO: Handle Growing here + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + return a_World->GetBlock(a_X, a_Y - 1, a_Z) == E_BLOCK_FARMLAND; + } + +}; \ No newline at end of file diff --git a/source/blocks/BlockDirt.cpp b/source/blocks/BlockDirt.cpp new file mode 100644 index 000000000..ea8c6509d --- /dev/null +++ b/source/blocks/BlockDirt.cpp @@ -0,0 +1,9 @@ +#include "Globals.h" +#include "BlockDirt.h" +#include "../cItem.h" +#include "../cWorld.h" + +cBlockDirtHandler::cBlockDirtHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) +{ +} diff --git a/source/blocks/BlockDirt.h b/source/blocks/BlockDirt.h new file mode 100644 index 000000000..49450b16d --- /dev/null +++ b/source/blocks/BlockDirt.h @@ -0,0 +1,62 @@ +#pragma once +#include "Block.h" +#include "../MersenneTwister.h" +#include "../cWorld.h" + +class cBlockDirtHandler : public cBlockHandler +{ +public: + cBlockDirtHandler(BLOCKTYPE a_BlockID); + + + virtual bool NeedsRandomTicks() + { + return m_BlockID == E_BLOCK_GRASS; + } + + virtual int GetDropID() + { + return E_BLOCK_DIRT; + } + + + void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + if(m_BlockID == E_BLOCK_GRASS) + { + //Grass becomes dirt if there is something on top of them + BLOCKTYPE Above = a_World->GetBlock(a_X, a_Y + 1, a_Z); + if(!g_BlockTransparent[Above] && !g_BlockOneHitDig[Above]) + { + a_World->FastSetBlock(a_X, a_Y, a_Z, E_BLOCK_DIRT, 0); + } + + + 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; + a_World->GetBlockTypeMeta(a_X + OfsX, a_Y + OfsY, a_Z + OfsZ, DestBlock, DestMeta); + if(DestBlock != E_BLOCK_DIRT) + { + continue; + } + + BLOCKTYPE AboveDest; + NIBBLETYPE AboveMeta; + a_World->GetBlockTypeMeta(a_X + OfsX, a_Y + OfsY + 1, a_Z + OfsZ, AboveDest, AboveMeta); + if (g_BlockOneHitDig[AboveDest] || g_BlockTransparent[AboveDest]) + { + a_World->FastSetBlock(a_X + OfsX, a_Y + OfsY, a_Z + OfsZ, E_BLOCK_GRASS, 0); + } + } // for i - repeat twice + + } + } + +}; \ No newline at end of file diff --git a/source/blocks/BlockDispenser.h b/source/blocks/BlockDispenser.h new file mode 100644 index 000000000..4ccfe0dfc --- /dev/null +++ b/source/blocks/BlockDispenser.h @@ -0,0 +1,22 @@ +#pragma once +#include "BlockEntity.h" +#include "../cWorld.h" +#include "../cPiston.h" +#include "../cPlayer.h" + +class cBlockDispenserHandler : public cBlockEntityHandler +{ +public: + cBlockDispenserHandler(BLOCKTYPE a_BlockID) + : cBlockEntityHandler(a_BlockID) + { + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) + { + a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0)); + OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir); + } + + +}; \ No newline at end of file diff --git a/source/blocks/BlockDoor.cpp b/source/blocks/BlockDoor.cpp new file mode 100644 index 000000000..e854281a5 --- /dev/null +++ b/source/blocks/BlockDoor.cpp @@ -0,0 +1,60 @@ +#include "Globals.h" +#include "BlockDoor.h" +#include "../cItem.h" +#include "../cWorld.h" +#include "../cDoors.h" +#include "../cPlayer.h" + + +cBlockDoorHandler::cBlockDoorHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) +{ +} + +void cBlockDoorHandler::OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir) +{ + +} + +void cBlockDoorHandler::OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) +{ + char OldMeta = a_World->GetBlockMeta(a_X, a_Y, a_Z); + + if (OldMeta & 8) + { + // Was upper part of door + if (cDoors::IsDoor(a_World->GetBlock(a_X, a_Y - 1, a_Z))) + { + a_World->FastSetBlock(a_X, a_Y - 1, a_Z, E_BLOCK_AIR, 0); + } + } + else + { + // Was lower part + if (cDoors::IsDoor(a_World->GetBlock(a_X, a_Y + 1, a_Z))) + { + a_World->FastSetBlock(a_X, a_Y + 1, a_Z, E_BLOCK_AIR, 0); + } + } +} + +void cBlockDoorHandler::OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) +{ + cDoors::ChangeDoor(a_World, a_X, a_Y, a_Z); +} + +char cBlockDoorHandler::GetDropCount() +{ + return 1; +} + +void cBlockDoorHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) +{ + if (a_World->GetBlock(a_X, a_Y + 1, a_Z) == E_BLOCK_AIR) + { + a_BlockMeta = cDoors::RotationToMetaData(a_Player->GetRotation()); + a_World->SetBlock(a_X, a_Y + 1, a_Z, m_BlockID, a_BlockMeta + 8); + a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, a_BlockMeta); + OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir); + } +} \ No newline at end of file diff --git a/source/blocks/BlockDoor.h b/source/blocks/BlockDoor.h new file mode 100644 index 000000000..180d3b48f --- /dev/null +++ b/source/blocks/BlockDoor.h @@ -0,0 +1,29 @@ +#pragma once +#include "Block.h" + + +class cBlockDoorHandler : public cBlockHandler +{ +public: + cBlockDoorHandler(BLOCKTYPE a_BlockID); + virtual void OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir); + virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z); + virtual void OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z); + virtual char GetDropCount(); + virtual bool IsUseable() + { + return true; + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir); + + virtual int GetDropID() + { + return (m_BlockID == E_BLOCK_WOODEN_DOOR) ? E_ITEM_WOODEN_DOOR : E_ITEM_IRON_DOOR; + } + + virtual bool CanBePlacedOnSide() + { + return false; + } +}; \ No newline at end of file diff --git a/source/blocks/BlockEntity.cpp b/source/blocks/BlockEntity.cpp new file mode 100644 index 000000000..b34b01ee9 --- /dev/null +++ b/source/blocks/BlockEntity.cpp @@ -0,0 +1,15 @@ +#include "Globals.h" +#include "BlockEntity.h" +#include "../cItem.h" +#include "../cPlayer.h" +#include "../cWorld.h" + +cBlockEntityHandler::cBlockEntityHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) +{ +} + +void cBlockEntityHandler::OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) +{ + a_World->UseBlockEntity(a_Player, a_X, a_Y, a_Z); +} diff --git a/source/blocks/BlockEntity.h b/source/blocks/BlockEntity.h new file mode 100644 index 000000000..abdaa7615 --- /dev/null +++ b/source/blocks/BlockEntity.h @@ -0,0 +1,16 @@ +#pragma once +#include "Block.h" + + +class cBlockEntityHandler : public cBlockHandler +{ +public: + cBlockEntityHandler(BLOCKTYPE a_BlockID); + virtual void OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z); + virtual bool IsUseable() + { + return true; + } + + +}; \ No newline at end of file diff --git a/source/blocks/BlockFire.cpp b/source/blocks/BlockFire.cpp new file mode 100644 index 000000000..5ca8dd902 --- /dev/null +++ b/source/blocks/BlockFire.cpp @@ -0,0 +1,24 @@ +#include "Globals.h" +#include "BlockFire.h" +#include "../cItem.h" +#include "../cWorld.h" + +cBlockFireHandler::cBlockFireHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) +{ +} + +void cBlockFireHandler::OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) +{ + a_World->DigBlock(a_X, a_Y, a_Z); +} + +char cBlockFireHandler::GetDropCount() +{ + return -1; +} + +bool cBlockFireHandler::IsClickedThrough() +{ + return true; +} \ No newline at end of file diff --git a/source/blocks/BlockFire.h b/source/blocks/BlockFire.h new file mode 100644 index 000000000..0a5396096 --- /dev/null +++ b/source/blocks/BlockFire.h @@ -0,0 +1,14 @@ +#pragma once +#include "Block.h" + + +class cBlockFireHandler : public cBlockHandler +{ +public: + cBlockFireHandler(BLOCKTYPE a_BlockID); + virtual void OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z); + virtual bool IsClickedThrough(); + virtual char GetDropCount(); + + +}; \ No newline at end of file diff --git a/source/blocks/BlockFlower.h b/source/blocks/BlockFlower.h new file mode 100644 index 000000000..12eaa4dc8 --- /dev/null +++ b/source/blocks/BlockFlower.h @@ -0,0 +1,32 @@ +#pragma once +#include "Block.h" + + +class cBlockFlowerHandler : public cBlockHandler +{ +public: + cBlockFlowerHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual char GetDropMeta(char a_BlockMeta) + { + return 0; + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + return IsBlockTypeOfDirt(a_World->GetBlock(a_X, a_Y - 1, a_Z)); + } + + virtual bool AllowBlockOnTop() + { + return false; + } + + virtual bool CanBePlacedOnSide() + { + return false; + } +}; \ No newline at end of file diff --git a/source/blocks/BlockFluid.h b/source/blocks/BlockFluid.h new file mode 100644 index 000000000..4da785523 --- /dev/null +++ b/source/blocks/BlockFluid.h @@ -0,0 +1,20 @@ +#pragma once +#include "Block.h" + + +class cBlockFluidHandler : public cBlockHandler +{ +public: + cBlockFluidHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + + } + + virtual bool IgnoreBuildCollision() + { + return true; + } + + +}; \ No newline at end of file diff --git a/source/blocks/BlockFurnace.h b/source/blocks/BlockFurnace.h new file mode 100644 index 000000000..927c925bd --- /dev/null +++ b/source/blocks/BlockFurnace.h @@ -0,0 +1,27 @@ +#pragma once +#include "BlockEntity.h" +#include "../cWorld.h" +#include "../cPiston.h" +#include "../cPlayer.h" + +class cBlockFurnaceHandler : public cBlockEntityHandler +{ +public: + cBlockFurnaceHandler(BLOCKTYPE a_BlockID) + : cBlockEntityHandler(a_BlockID) + { + } + + virtual int GetDropID() + { + return E_ITEM_FURNACE; + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) + { + a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0)); + OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir); + } + + +}; \ No newline at end of file diff --git a/source/blocks/BlockGlowstone.h b/source/blocks/BlockGlowstone.h new file mode 100644 index 000000000..8d05cd799 --- /dev/null +++ b/source/blocks/BlockGlowstone.h @@ -0,0 +1,22 @@ +#pragma once +#include "Block.h" + + +class cBlockGlowstoneHandler : public cBlockHandler +{ +public: + cBlockGlowstoneHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual char GetDropMeta(char a_BlockMeta) + { + return 0; + } + + virtual int GetDropID() + { + return E_ITEM_GLOWSTONE_DUST; + } +}; \ No newline at end of file diff --git a/source/blocks/BlockIce.h b/source/blocks/BlockIce.h new file mode 100644 index 000000000..9b356e323 --- /dev/null +++ b/source/blocks/BlockIce.h @@ -0,0 +1,26 @@ +#pragma once +#include "Block.h" +#include "../MersenneTwister.h" +#include "../cWorld.h" + +class cBlockIceHandler : public cBlockHandler +{ +public: + cBlockIceHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual int GetDropID() + { + return E_ITEM_EMPTY; + } + + virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + a_World->FastSetBlock(a_X, a_Y, a_Z, E_BLOCK_STATIONARY_WATER, 8); + //This is called later than the real destroying of this ice block + } + + +}; \ No newline at end of file diff --git a/source/blocks/BlockLadder.h b/source/blocks/BlockLadder.h new file mode 100644 index 000000000..0b63cc8e6 --- /dev/null +++ b/source/blocks/BlockLadder.h @@ -0,0 +1,28 @@ +#pragma once +#include "Block.h" +#include "../cWorld.h" +#include "../cLadder.h" + +class cBlockLadderHandler : public cBlockHandler +{ +public: + cBlockLadderHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) + { + a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cLadder::DirectionToMetaData(a_Dir)); + OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir); + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + char Dir = cLadder::MetaDataToDirection(a_World->GetBlockMeta( a_X, a_Y, a_Z)); + AddDirection( a_X, a_Y, a_Z, Dir, true ); + return a_World->GetBlock( a_X, a_Y, a_Z ) != E_BLOCK_AIR; + } + +}; \ No newline at end of file diff --git a/source/blocks/BlockLeaves.h b/source/blocks/BlockLeaves.h new file mode 100644 index 000000000..4bae2003f --- /dev/null +++ b/source/blocks/BlockLeaves.h @@ -0,0 +1,162 @@ +#pragma once +#include "Block.h" +#include "../MersenneTwister.h" +#include "../cWorld.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, 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_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual int GetDropID() + { + MTRand rand; + + if(rand.randInt(5) == 0) + { + return E_ITEM_SAPLING; + } + + return E_ITEM_EMPTY; + } + + void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + cBlockHandler::OnDestroyed(a_World, a_X, a_Y, a_Z); + + //0.5% chance of dropping an apple + NIBBLETYPE Meta = a_World->GetBlockMeta(a_X, a_Y, a_Z); + //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_X, a_Y, a_Z); + } + } + + virtual void OnNeighborChanged(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + NIBBLETYPE Meta = a_World->GetBlockMeta(a_X, a_Y, a_Z); + a_World->SetBlockMeta(a_X, a_Y, a_Z, Meta & 0x7); //Unset 0x8 bit so it gets checked for decay + } + + virtual bool NeedsRandomTicks() + { + return true; + } + + virtual void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + NIBBLETYPE Meta = a_World->GetBlockMeta(a_X, a_Y, a_Z); + if ((Meta & 0x04) != 0) + { + // Player-placed leaves, don't decay + return; + } + + if (Meta & 0x8) + { + // 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_X - LEAVES_CHECK_DISTANCE, a_X + LEAVES_CHECK_DISTANCE, + a_Y - LEAVES_CHECK_DISTANCE, a_Y + LEAVES_CHECK_DISTANCE, + a_Z - LEAVES_CHECK_DISTANCE, a_Z + LEAVES_CHECK_DISTANCE, + cBlockArea::baTypes) + ) + { + // Cannot check leaves, a chunk is missing too close + return; + } + + if (HasNearLog(Area, a_X, a_Y, a_Z)) + { + // Wood found, the leaves stay; mark them as checked: + a_World->SetBlockMeta(a_X, a_Y, a_Z, Meta | 0x8); + return; + } + // Decay the leaves: + DropBlock(a_World, a_X, a_Y, a_Z); + + a_World->DigBlock(a_X, a_Y, a_Z); + + } +}; + + +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/BlockMelon.h b/source/blocks/BlockMelon.h new file mode 100644 index 000000000..921745795 --- /dev/null +++ b/source/blocks/BlockMelon.h @@ -0,0 +1,24 @@ +#pragma once +#include "Block.h" + + +class cBlockMelonHandler : public cBlockHandler +{ +public: + cBlockMelonHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + + virtual int GetDropID() + { + return E_ITEM_MELON_SLICE; + } + + virtual char GetDropCount() + { + MTRand r1; + return 3 + r1.randInt(4); + } +}; \ No newline at end of file diff --git a/source/blocks/BlockMushroom.h b/source/blocks/BlockMushroom.h new file mode 100644 index 000000000..5b2da6498 --- /dev/null +++ b/source/blocks/BlockMushroom.h @@ -0,0 +1,42 @@ +#pragma once +#include "Block.h" + + +class cBlockMushroomHandler : public cBlockHandler +{ +public: + cBlockMushroomHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual char GetDropMeta(char a_BlockMeta) + { + return 0; + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + switch (a_World->GetBlock(a_X, a_Y - 1, a_Z)) + { + 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 AllowBlockOnTop() + { + return false; + } + + + virtual bool CanBePlacedOnSide() + { + return false; + } +}; \ No newline at end of file diff --git a/source/blocks/BlockPiston.cpp b/source/blocks/BlockPiston.cpp new file mode 100644 index 000000000..98463fd97 --- /dev/null +++ b/source/blocks/BlockPiston.cpp @@ -0,0 +1,51 @@ +#include "Globals.h" +#include "BlockPiston.h" +#include "../cItem.h" +#include "../cWorld.h" +#include "../cRedstone.h" +#include "../cPlayer.h" +#include "../cPiston.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_BlockID) + : cBlockHandler(a_BlockID) +{ +} + +void cBlockPistonHandler::OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir) +{ + +} + +void cBlockPistonHandler::OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) +{ + char OldMeta = a_World->GetBlockMeta(a_X, a_Y, a_Z); + + int newX = a_X; + int newY = a_Y; + int newZ = a_Z; + 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); + } +} + +void cBlockPistonHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) +{ + + a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cPiston::RotationPitchToMetaData(a_Player->GetRotation(), a_Player->GetPitch())); + OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir); + + cRedstone Redstone(a_World); + Redstone.ChangeRedstone(a_X, a_Y, a_Z, false); +} \ No newline at end of file diff --git a/source/blocks/BlockPiston.h b/source/blocks/BlockPiston.h new file mode 100644 index 000000000..69d3a204f --- /dev/null +++ b/source/blocks/BlockPiston.h @@ -0,0 +1,15 @@ +#pragma once +#include "Block.h" + + +class cBlockPistonHandler : public cBlockHandler +{ +public: + cBlockPistonHandler(BLOCKTYPE a_BlockID); + virtual void OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir); + virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z); + + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir); + +}; \ No newline at end of file diff --git a/source/blocks/BlockRedstone.cpp b/source/blocks/BlockRedstone.cpp new file mode 100644 index 000000000..1171d124a --- /dev/null +++ b/source/blocks/BlockRedstone.cpp @@ -0,0 +1,41 @@ +#include "Globals.h" +#include "BlockRedstone.h" +#include "../cItem.h" +#include "../cWorld.h" +#include "../cRedstone.h" +#include "../cTorch.h" + +cBlockRedstoneHandler::cBlockRedstoneHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) +{ +} + +void cBlockRedstoneHandler::OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir) +{ + cRedstone Redstone(a_World); + bool Added = false; + if(a_World->GetBlock(a_X, a_Y, a_Z) == E_BLOCK_REDSTONE_TORCH_ON) + Added = true; + + Redstone.ChangeRedstone(a_X, a_Y, a_Z, Added); +} + +void cBlockRedstoneHandler::OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) +{ + cRedstone Redstone(a_World); + Redstone.ChangeRedstone(a_X, a_Y, a_Z, false); +} + +void cBlockRedstoneHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) +{ + switch(m_BlockID) + { + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_REDSTONE_TORCH_OFF: + a_BlockMeta = cTorch::DirectionToMetaData(a_Dir); + break; + + } + a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, a_BlockMeta); + OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir); +} \ No newline at end of file diff --git a/source/blocks/BlockRedstone.h b/source/blocks/BlockRedstone.h new file mode 100644 index 000000000..21c19d4c5 --- /dev/null +++ b/source/blocks/BlockRedstone.h @@ -0,0 +1,33 @@ +#pragma once +#include "Block.h" +#include "../cWorld.h" + +class cBlockRedstoneHandler : public cBlockHandler +{ +public: + cBlockRedstoneHandler(BLOCKTYPE a_BlockID); + virtual void OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir); + virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z); + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir); + + virtual bool AllowBlockOnTop() + { + return false; + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + return a_World->GetBlock(a_X, a_Y - 1, a_Z) != E_BLOCK_AIR; + } + + virtual int GetDropID() + { + return E_ITEM_REDSTONE_DUST; + } + + virtual bool CanBePlacedOnSide() + { + return false; + } +}; \ No newline at end of file diff --git a/source/blocks/BlockRedstoneOre.h b/source/blocks/BlockRedstoneOre.h new file mode 100644 index 000000000..5658d76ad --- /dev/null +++ b/source/blocks/BlockRedstoneOre.h @@ -0,0 +1,26 @@ +#pragma once +#include "Block.h" +#include "../MersenneTwister.h" +#include "../cWorld.h" + +class cBlockRedstoneOreHandler : public cBlockHandler +{ +public: + cBlockRedstoneOreHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual int GetDropID() + { + return E_ITEM_REDSTONE_DUST; + } + + virtual char GetDropCount() + { + MTRand r1; + return 4 + r1.randInt(1); + } + + +}; \ No newline at end of file diff --git a/source/blocks/BlockRedstoneRepeater.cpp b/source/blocks/BlockRedstoneRepeater.cpp new file mode 100644 index 000000000..639764aa5 --- /dev/null +++ b/source/blocks/BlockRedstoneRepeater.cpp @@ -0,0 +1,34 @@ +#include "Globals.h" +#include "BlockRedstoneRepeater.h" +#include "../cItem.h" +#include "../cWorld.h" +#include "../cRedstone.h" +#include "../cPlayer.h" + +cBlockRedstoneRepeaterHandler::cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) +{ +} + +void cBlockRedstoneRepeaterHandler::OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir) +{ + cRedstone Redstone(a_World); + Redstone.ChangeRedstone(a_X, a_Y, a_Z, false); +} + +void cBlockRedstoneRepeaterHandler::OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) +{ + cRedstone Redstone(a_World); + Redstone.ChangeRedstone(a_X, a_Y, a_Z, false); +} + +void cBlockRedstoneRepeaterHandler::OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) +{ + a_World->FastSetBlock(a_X, a_Y, a_Z, m_BlockID, ((a_World->GetBlockMeta(a_X, a_Y, a_Z) + 0x04) & 0x0f)); +} + +void cBlockRedstoneRepeaterHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) +{ + a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cRedstone::RepeaterRotationToMetaData(a_Player->GetRotation())); + OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir); +} \ No newline at end of file diff --git a/source/blocks/BlockRedstoneRepeater.h b/source/blocks/BlockRedstoneRepeater.h new file mode 100644 index 000000000..e8618cdeb --- /dev/null +++ b/source/blocks/BlockRedstoneRepeater.h @@ -0,0 +1,46 @@ +#pragma once +#include "Block.h" +#include "../cWorld.h" + +class cBlockRedstoneRepeaterHandler : public cBlockHandler +{ +public: + cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockID); + virtual void OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir); + virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z); + + virtual void OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z); + + virtual char GetDropMeta(char a_BlockMeta) + { + return 0; + } + + virtual int GetDropID() + { + return E_ITEM_REDSTONE_REPEATER; + } + + virtual bool IsUseable() + { + return true; + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir); + + virtual bool AllowBlockOnTop() + { + return false; + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + return a_World->GetBlock(a_X, a_Y - 1, a_Z) != E_BLOCK_AIR; + } + + + virtual bool CanBePlacedOnSide() + { + return false; + } +}; \ No newline at end of file diff --git a/source/blocks/BlockRedstoneTorch.h b/source/blocks/BlockRedstoneTorch.h new file mode 100644 index 000000000..6ae37cd1e --- /dev/null +++ b/source/blocks/BlockRedstoneTorch.h @@ -0,0 +1,30 @@ +#pragma once +#include "BlockRedstone.h" +#include "../cTorch.h" + + +class cBlockRedstoneTorchHandler : public cBlockRedstoneHandler +{ +public: + cBlockRedstoneTorchHandler(BLOCKTYPE a_BlockID) + : cBlockRedstoneHandler(a_BlockID) + { + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + char Dir = cTorch::MetaDataToDirection(a_World->GetBlockMeta( a_X, a_Y, a_Z)); + AddDirection( a_X, a_Y, a_Z, Dir, true ); + return a_World->GetBlock( a_X, a_Y, a_Z ) != E_BLOCK_AIR; + } + + virtual int GetDropID() + { + return E_ITEM_REDSTONE_TORCH_ON; + } + + virtual bool CanBePlacedOnSide() + { + return true; + } +}; \ No newline at end of file diff --git a/source/blocks/BlockSapling.h b/source/blocks/BlockSapling.h new file mode 100644 index 000000000..d0498afea --- /dev/null +++ b/source/blocks/BlockSapling.h @@ -0,0 +1,51 @@ +#pragma once +#include "Block.h" +#include "../cWorld.h" + +class cBlockSaplingHandler : public cBlockHandler +{ +public: + cBlockSaplingHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual bool NeedsRandomTicks() override + { + return true; + } + + virtual char GetDropMeta(char a_BlockMeta) + { + return a_BlockMeta & 3; //Only the first 2 bits contain the display information the others are for growing + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + return IsBlockTypeOfDirt(a_World->GetBlock(a_X, a_Y - 1, a_Z)); + } + + virtual bool AllowBlockOnTop() + { + return false; + } + + void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + NIBBLETYPE Meta = a_World->GetBlockMeta(a_X, a_Y, a_Z); + + if ((Meta & 0x08) != 0) + { + a_World->GrowTree(a_X, a_Y, a_Z); + } + else + { + a_World->SetBlockMeta(a_X, a_Y, a_Z, Meta | 0x08); + } + } + + virtual bool CanBePlacedOnSide() + { + return false; + } +}; \ No newline at end of file diff --git a/source/blocks/BlockSign.h b/source/blocks/BlockSign.h new file mode 100644 index 000000000..3b2e208e1 --- /dev/null +++ b/source/blocks/BlockSign.h @@ -0,0 +1,42 @@ +#pragma once +#include "Block.h" +#include "../cWorld.h" +#include "../cSign.h" +#include "../cPlayer.h" + +class cBlockSignHandler : public cBlockHandler +{ +public: + cBlockSignHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) + { + BLOCKTYPE Block; + NIBBLETYPE Meta; + if(a_Dir == 1) + { + Meta = cSign::RotationToMetaData(a_Player->GetRotation()); + Block = E_BLOCK_SIGN_POST; + }else{ + Meta = cSign::DirectionToMetaData(a_Dir); + Block = E_BLOCK_WALLSIGN; + } + + a_World->SetBlock(a_X, a_Y, a_Z, Block, Meta); + OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir); + } + + virtual int GetDropID() + { + return E_ITEM_SIGN; + } + + virtual bool AllowBlockOnTop() + { + return false; + } +}; \ No newline at end of file diff --git a/source/blocks/BlockSlab.cpp b/source/blocks/BlockSlab.cpp new file mode 100644 index 000000000..659dc7986 --- /dev/null +++ b/source/blocks/BlockSlab.cpp @@ -0,0 +1,17 @@ +#include "Globals.h" +#include "BlockSlab.h" +#include "../cItem.h" +#include "../cPlayer.h" +#include "../cWorld.h" + +cBlockSlabHandler::cBlockSlabHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) +{ +} + + +void cBlockSlabHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) +{ + a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, DirectionToMetaData( a_Dir, a_BlockMeta )); + OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir); +} \ No newline at end of file diff --git a/source/blocks/BlockSlab.h b/source/blocks/BlockSlab.h new file mode 100644 index 000000000..05df819b2 --- /dev/null +++ b/source/blocks/BlockSlab.h @@ -0,0 +1,33 @@ +#pragma once +#include "Block.h" + + +class cBlockSlabHandler : public cBlockHandler +{ +public: + cBlockSlabHandler(BLOCKTYPE a_BlockID); + virtual char GetDropMeta(char a_BlockMeta) + { + return a_BlockMeta; + } + + virtual char GetDropCount() + { + if(m_BlockID == E_BLOCK_DOUBLE_STONE_SLAB + || m_BlockID == E_BLOCK_DOUBLE_WOODEN_SLAB) + return 2; + return 1; + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir); + + static char DirectionToMetaData( char a_Direction, NIBBLETYPE Meta ) + { + char result = Meta; + if( a_Direction == 0) + { + result |= 0x8; + } + return result; + } +}; \ No newline at end of file diff --git a/source/blocks/BlockSnow.h b/source/blocks/BlockSnow.h new file mode 100644 index 000000000..75143b73e --- /dev/null +++ b/source/blocks/BlockSnow.h @@ -0,0 +1,39 @@ +#pragma once +#include "Block.h" + + +class cBlockSnowHandler : public cBlockHandler +{ +public: + cBlockSnowHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual bool IgnoreBuildCollision() + { + return true; + } + + virtual int GetDropID() + { + return E_ITEM_SNOWBALL; + } + + virtual char GetDropCount() + { + return 4; + } + + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + return a_World->GetBlock(a_X, a_Y - 1, a_Z) != E_BLOCK_AIR; + } + + virtual bool DropOnUnsuitable() + { + return false; + } + +}; \ No newline at end of file diff --git a/source/blocks/BlockStairs.cpp b/source/blocks/BlockStairs.cpp new file mode 100644 index 000000000..cd4ad9907 --- /dev/null +++ b/source/blocks/BlockStairs.cpp @@ -0,0 +1,18 @@ +#include "Globals.h" +#include "BlockStairs.h" +#include "../cItem.h" +#include "../cVine.h" +#include "../cPlayer.h" +#include "../cWorld.h" +#include "../cStairs.h" + +cBlockStairsHandler::cBlockStairsHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) +{ +} + +void cBlockStairsHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) +{ + a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cStairs::RotationToMetaData(a_Player->GetRotation(), a_Dir)); + OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir); +} \ No newline at end of file diff --git a/source/blocks/BlockStairs.h b/source/blocks/BlockStairs.h new file mode 100644 index 000000000..d7de17c1f --- /dev/null +++ b/source/blocks/BlockStairs.h @@ -0,0 +1,14 @@ +#pragma once +#include "Block.h" + + +class cBlockStairsHandler : public cBlockHandler +{ +public: + cBlockStairsHandler(BLOCKTYPE a_BlockID); + + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir); + + +}; \ No newline at end of file diff --git a/source/blocks/BlockStems.h b/source/blocks/BlockStems.h new file mode 100644 index 000000000..8f1d4ddca --- /dev/null +++ b/source/blocks/BlockStems.h @@ -0,0 +1,41 @@ +#pragma once +#include "Block.h" +#include "../MersenneTwister.h" +#include "../cWorld.h" + +class cBlockStemsHandler : public cBlockHandler +{ +public: + cBlockStemsHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual bool NeedsRandomTicks() + { + return true; + } + + virtual char GetDropMeta(char a_BlockMeta) + { + return 0; + } + + virtual int GetDropID() + { + if(m_BlockID == E_BLOCK_MELON_STEM) + return E_ITEM_MELON_SEEDS; + return E_ITEM_PUMPKIN_SEEDS; + } + + void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + //TODO: Handle Growing here + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + return a_World->GetBlock(a_X, a_Y - 1, a_Z) == E_BLOCK_FARMLAND; + } + +}; \ No newline at end of file diff --git a/source/blocks/BlockStone.h b/source/blocks/BlockStone.h new file mode 100644 index 000000000..d15e4730a --- /dev/null +++ b/source/blocks/BlockStone.h @@ -0,0 +1,18 @@ +#pragma once +#include "Block.h" +#include "../MersenneTwister.h" +#include "../cWorld.h" + +class cBlockStoneHandler : public cBlockHandler +{ +public: + cBlockStoneHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual int GetDropID() + { + return E_ITEM_COBBLESTONE; + } +}; \ No newline at end of file diff --git a/source/blocks/BlockSugarcane.h b/source/blocks/BlockSugarcane.h new file mode 100644 index 000000000..610052880 --- /dev/null +++ b/source/blocks/BlockSugarcane.h @@ -0,0 +1,43 @@ +#pragma once +#include "Block.h" +#include "../MersenneTwister.h" +#include "../cWorld.h" + +class cBlockSugarcaneHandler : public cBlockHandler +{ +public: + cBlockSugarcaneHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual bool NeedsRandomTicks() + { + return true; + } + + virtual int GetDropID() + { + return E_ITEM_SUGARCANE; + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + BLOCKTYPE Block = a_World->GetBlock(a_X, a_Y-1, a_Z); + if(!IsBlockTypeOfDirt(Block) && Block != E_BLOCK_SAND && Block != E_BLOCK_SUGARCANE) + return false; + + return a_World->IsBlockDirectlyWatered(a_X, a_Y - 1, a_Z); + } + + void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + + //TODO: Handle Growing here + } + + virtual bool CanBePlacedOnSide() + { + return false; + } +}; \ No newline at end of file diff --git a/source/blocks/BlockTallGrass.h b/source/blocks/BlockTallGrass.h new file mode 100644 index 000000000..a702bb8ca --- /dev/null +++ b/source/blocks/BlockTallGrass.h @@ -0,0 +1,35 @@ +#pragma once +#include "Block.h" + + +class cBlockTallGrassHandler : public cBlockHandler +{ +public: + cBlockTallGrassHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual bool IgnoreBuildCollision() + { + return true; + } + + virtual int GetDropID() + { + return E_ITEM_SEEDS; + } + + virtual char GetDropCount() + { + MTRand r1; + if(r1.randInt(10) == 5) + return 1; + return 0; + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + return a_World->GetBlock(a_X, a_Y - 1, a_Z) != E_BLOCK_AIR; + } +}; \ No newline at end of file diff --git a/source/blocks/BlockTorch.cpp b/source/blocks/BlockTorch.cpp new file mode 100644 index 000000000..d9597a9ac --- /dev/null +++ b/source/blocks/BlockTorch.cpp @@ -0,0 +1,15 @@ +#include "Globals.h" +#include "BlockTorch.h" +#include "../cTorch.h" +#include "../cWorld.h" + +cBlockTorchHandler::cBlockTorchHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) +{ +} + +void cBlockTorchHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) +{ + a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cTorch::DirectionToMetaData(a_Dir)); + OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir); +} \ No newline at end of file diff --git a/source/blocks/BlockTorch.h b/source/blocks/BlockTorch.h new file mode 100644 index 000000000..1e4827ac1 --- /dev/null +++ b/source/blocks/BlockTorch.h @@ -0,0 +1,25 @@ +#pragma once +#include "Block.h" +#include "../cTorch.h" +#include "../cWorld.h" + + +class cBlockTorchHandler : public cBlockHandler +{ +public: + cBlockTorchHandler(BLOCKTYPE a_BlockID); + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir); + + virtual bool AllowBlockOnTop() + { + return false; + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) + { + char Dir = cTorch::MetaDataToDirection(a_World->GetBlockMeta( a_X, a_Y, a_Z)); + AddDirection( a_X, a_Y, a_Z, Dir, true ); + return a_World->GetBlock( a_X, a_Y, a_Z ) != E_BLOCK_AIR; + } +}; \ No newline at end of file diff --git a/source/blocks/BlockVine.cpp b/source/blocks/BlockVine.cpp new file mode 100644 index 000000000..fda3c818c --- /dev/null +++ b/source/blocks/BlockVine.cpp @@ -0,0 +1,17 @@ +#include "Globals.h" +#include "BlockVine.h" +#include "../cItem.h" +#include "../cVine.h" +#include "../cPlayer.h" +#include "../cWorld.h" + +cBlockVineHandler::cBlockVineHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) +{ +} + +void cBlockVineHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) +{ + a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cVine::DirectionToMetaData(a_Dir)); + OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir); +} \ No newline at end of file diff --git a/source/blocks/BlockVine.h b/source/blocks/BlockVine.h new file mode 100644 index 000000000..d601e622c --- /dev/null +++ b/source/blocks/BlockVine.h @@ -0,0 +1,23 @@ +#pragma once +#include "Block.h" + + +class cBlockVineHandler : public cBlockHandler +{ +public: + cBlockVineHandler(BLOCKTYPE a_BlockID); + + virtual bool IgnoreBuildCollision() + { + return true; + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir); + + + virtual bool AllowBlockOnTop() + { + return false; + } + +}; \ No newline at end of file diff --git a/source/blocks/BlockWood.h b/source/blocks/BlockWood.h new file mode 100644 index 000000000..c93c44b4f --- /dev/null +++ b/source/blocks/BlockWood.h @@ -0,0 +1,17 @@ +#pragma once +#include "Block.h" + + +class cBlockWoodHandler : public cBlockHandler +{ +public: + cBlockWoodHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + char GetDropMeta(char a_BlockMeta) + { + return a_BlockMeta; + } + +}; \ No newline at end of file diff --git a/source/blocks/BlockWorkbench.cpp b/source/blocks/BlockWorkbench.cpp new file mode 100644 index 000000000..095a6e1da --- /dev/null +++ b/source/blocks/BlockWorkbench.cpp @@ -0,0 +1,24 @@ +#include "Globals.h" +#include "BlockWorkbench.h" +#include "../cItem.h" +#include "../cPlayer.h" +#include "../cCraftingWindow.h" + +cBlockWorkbenchHandler::cBlockWorkbenchHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) +{ +} + +void cBlockWorkbenchHandler::OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir) +{ +} + +void cBlockWorkbenchHandler::OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) +{ +} + +void cBlockWorkbenchHandler::OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) +{ + cWindow* Window = new cCraftingWindow(0, true); + a_Player->OpenWindow(Window); +} diff --git a/source/blocks/BlockWorkbench.h b/source/blocks/BlockWorkbench.h new file mode 100644 index 000000000..2a0936c08 --- /dev/null +++ b/source/blocks/BlockWorkbench.h @@ -0,0 +1,19 @@ +#pragma once +#include "Block.h" + + +class cBlockWorkbenchHandler : public cBlockHandler +{ +public: + cBlockWorkbenchHandler(BLOCKTYPE a_BlockID); + virtual void OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir); + virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z); + + virtual void OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z); + virtual bool IsUseable() + { + return true; + } + + +}; \ No newline at end of file -- cgit v1.2.3