From 4df23d19b7be2f274974e3dfe91e716e6296f11c Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sat, 29 Sep 2012 13:59:32 +0000 Subject: Unified folder name-casing git-svn-id: http://mc-server.googlecode.com/svn/trunk@902 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/Blocks/BlockBed.h | 123 +++++++++ source/Blocks/BlockCactus.h | 64 +++++ source/Blocks/BlockChest.h | 26 ++ source/Blocks/BlockCloth.h | 23 ++ source/Blocks/BlockCrops.h | 64 +++++ source/Blocks/BlockDirt.h | 72 +++++ source/Blocks/BlockDispenser.h | 22 ++ source/Blocks/BlockDoor.cpp | 74 ++++++ source/Blocks/BlockDoor.h | 31 +++ source/Blocks/BlockEntity.h | 31 +++ source/Blocks/BlockFire.h | 33 +++ source/Blocks/BlockFlower.h | 38 +++ source/Blocks/BlockFluid.h | 20 ++ source/Blocks/BlockFurnace.h | 27 ++ source/Blocks/BlockGlowstone.h | 22 ++ source/Blocks/BlockGravel.h | 18 ++ source/Blocks/BlockHandler.cpp | 448 ++++++++++++++++++++++++++++++++ source/Blocks/BlockHandler.h | 90 +++++++ source/Blocks/BlockIce.h | 26 ++ source/Blocks/BlockLadder.h | 40 +++ source/Blocks/BlockLeaves.h | 167 ++++++++++++ source/Blocks/BlockMelon.h | 29 +++ source/Blocks/BlockMushroom.h | 47 ++++ source/Blocks/BlockNote.h | 13 + source/Blocks/BlockOre.h | 58 +++++ source/Blocks/BlockPiston.cpp | 51 ++++ source/Blocks/BlockPiston.h | 15 ++ source/Blocks/BlockRedstone.cpp | 41 +++ source/Blocks/BlockRedstone.h | 33 +++ source/Blocks/BlockRedstoneRepeater.cpp | 39 +++ source/Blocks/BlockRedstoneRepeater.h | 52 ++++ source/Blocks/BlockRedstoneTorch.h | 28 ++ source/Blocks/BlockSand.h | 18 ++ source/Blocks/BlockSapling.h | 56 ++++ source/Blocks/BlockSign.h | 47 ++++ source/Blocks/BlockSlab.h | 51 ++++ source/Blocks/BlockSnow.h | 44 ++++ source/Blocks/BlockStairs.h | 22 ++ source/Blocks/BlockStems.h | 46 ++++ source/Blocks/BlockStone.h | 18 ++ source/Blocks/BlockSugarcane.h | 71 +++++ source/Blocks/BlockTallGrass.h | 41 +++ source/Blocks/BlockTorch.h | 166 ++++++++++++ source/Blocks/BlockVine.h | 35 +++ source/Blocks/BlockWood.h | 22 ++ source/Blocks/BlockWorkbench.h | 36 +++ 46 files changed, 2538 insertions(+) create mode 100644 source/Blocks/BlockBed.h create mode 100644 source/Blocks/BlockCactus.h create mode 100644 source/Blocks/BlockChest.h create mode 100644 source/Blocks/BlockCloth.h create mode 100644 source/Blocks/BlockCrops.h 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.h 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/BlockGravel.h create mode 100644 source/Blocks/BlockHandler.cpp create mode 100644 source/Blocks/BlockHandler.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/BlockNote.h create mode 100644 source/Blocks/BlockOre.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/BlockRedstoneRepeater.cpp create mode 100644 source/Blocks/BlockRedstoneRepeater.h create mode 100644 source/Blocks/BlockRedstoneTorch.h create mode 100644 source/Blocks/BlockSand.h create mode 100644 source/Blocks/BlockSapling.h create mode 100644 source/Blocks/BlockSign.h create mode 100644 source/Blocks/BlockSlab.h create mode 100644 source/Blocks/BlockSnow.h 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.h create mode 100644 source/Blocks/BlockVine.h create mode 100644 source/Blocks/BlockWood.h create mode 100644 source/Blocks/BlockWorkbench.h (limited to 'source/Blocks') diff --git a/source/Blocks/BlockBed.h b/source/Blocks/BlockBed.h new file mode 100644 index 000000000..cbef5bb4d --- /dev/null +++ b/source/Blocks/BlockBed.h @@ -0,0 +1,123 @@ +#pragma once +#include "BlockHandler.h" +#include "../World.h" +#include "../Sign.h" +#include "../Player.h" + +class cBlockBedHandler : public cBlockHandler +{ +public: + cBlockBedHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + + } + + + + + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) override + { + if( a_Dir != 1 ) // Can only be placed on the floor + return; + + NIBBLETYPE Meta = RotationToMetaData( a_Player->GetRotation() ); + Vector3i Direction = MetaDataToDirection( Meta ); + + if (a_World->GetBlock(a_X+Direction.x, a_Y, a_Z+Direction.z) != E_BLOCK_AIR) + { + return; + } + + a_World->SetBlock(a_X, a_Y, a_Z, E_BLOCK_BED, Meta); + a_World->SetBlock(a_X + Direction.x, a_Y, a_Z + Direction.z, E_BLOCK_BED, Meta | 0x8); + + OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir); + } + + + + + + virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) override + { + char OldMeta = a_World->GetBlockMeta(a_X, a_Y, a_Z); + + Vector3i ThisPos( a_X, a_Y, a_Z ); + 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); + } + } + } + + + + + + virtual int GetDropID() override + { + return E_ITEM_BED; + } + + virtual NIBBLETYPE GetDropMeta(NIBBLETYPE a_BlockMeta) override + { + return 0; + } + + + + + + virtual bool AllowBlockOnTop() override + { + return false; + } + + + + + + static NIBBLETYPE RotationToMetaData( float a_Rotation ) + { + a_Rotation += 180 + (180/4); // So its not aligned with axis + if( a_Rotation > 360.f ) a_Rotation -= 360.f; + + a_Rotation = (a_Rotation/360) * 4; + + return ((char)a_Rotation+2) % 4; + } + + + + + + static Vector3i MetaDataToDirection( NIBBLETYPE a_MetaData ) + { + switch( a_MetaData ) + { + case 0: // south +z + return Vector3i(0, 0, 1); + case 1: // west -x + return Vector3i(-1, 0, 0); + case 2: // north -z + return Vector3i(0, 0, -1); + case 3: // east +x + return Vector3i(1, 0, 0); + }; + return Vector3i(); + } +}; diff --git a/source/Blocks/BlockCactus.h b/source/Blocks/BlockCactus.h new file mode 100644 index 000000000..964646299 --- /dev/null +++ b/source/Blocks/BlockCactus.h @@ -0,0 +1,64 @@ + +#pragma once +#include "BlockHandler.h" + + + + + +class cBlockCactusHandler : + public cBlockHandler +{ +public: + cBlockCactusHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + + virtual NIBBLETYPE GetDropMeta(NIBBLETYPE a_BlockMeta) override + { + return 0; + } + + + virtual bool CanBeAt(cWorld * a_World, int a_X, int a_Y, int a_Z) override + { + 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 CanBePlacedOnSide() override + { + return false; + } + + + virtual AString GetStepSound(void) override + { + return "step.cloth"; + } + +}; + + + + diff --git a/source/Blocks/BlockChest.h b/source/Blocks/BlockChest.h new file mode 100644 index 000000000..db67fe1c8 --- /dev/null +++ b/source/Blocks/BlockChest.h @@ -0,0 +1,26 @@ +#pragma once +#include "BlockEntity.h" +#include "../World.h" +#include "../Piston.h" +#include "../Player.h" + +class cBlockChestHandler : public cBlockEntityHandler +{ +public: + cBlockChestHandler(BLOCKTYPE a_BlockID) + : cBlockEntityHandler(a_BlockID) + { + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) override + { + 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); + } + + virtual AString GetStepSound(void) override + { + return "step.wood"; + } + +}; diff --git a/source/Blocks/BlockCloth.h b/source/Blocks/BlockCloth.h new file mode 100644 index 000000000..452ad2237 --- /dev/null +++ b/source/Blocks/BlockCloth.h @@ -0,0 +1,23 @@ +#pragma once +#include "BlockHandler.h" + + +class cBlockClothHandler : public cBlockHandler +{ +public: + cBlockClothHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual NIBBLETYPE GetDropMeta(NIBBLETYPE a_BlockMeta) override + { + return a_BlockMeta; + } + + virtual AString GetStepSound(void) override + { + return "step.cloth"; + } + +}; diff --git a/source/Blocks/BlockCrops.h b/source/Blocks/BlockCrops.h new file mode 100644 index 000000000..b30139e79 --- /dev/null +++ b/source/Blocks/BlockCrops.h @@ -0,0 +1,64 @@ +#pragma once +#include "BlockHandler.h" +#include "../MersenneTwister.h" +#include "../World.h" + +class cBlockCropsHandler : public cBlockHandler +{ +public: + cBlockCropsHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual bool NeedsRandomTicks() override + { + return true; + } + + virtual bool AllowBlockOnTop() override + { + return false; + } + + virtual int GetDropID() override + { + return E_ITEM_EMPTY; + } + + virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) override + { + MTRand rand; + NIBBLETYPE Meta = a_World->GetBlockMeta(a_X, a_Y, a_Z); + + 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) override + { + + //TODO: Handle Growing here + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) override + { + return a_World->GetBlock(a_X, a_Y - 1, a_Z) == E_BLOCK_FARMLAND; + } + + virtual AString GetStepSound(void) override + { + return "step.grass"; + } + +}; diff --git a/source/Blocks/BlockDirt.h b/source/Blocks/BlockDirt.h new file mode 100644 index 000000000..5a2487f1b --- /dev/null +++ b/source/Blocks/BlockDirt.h @@ -0,0 +1,72 @@ +#pragma once +#include "BlockHandler.h" +#include "../MersenneTwister.h" +#include "../World.h" + +class cBlockDirtHandler : public cBlockHandler +{ +public: + cBlockDirtHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + + virtual bool NeedsRandomTicks() override + { + return m_BlockID == E_BLOCK_GRASS; + } + + virtual int GetDropID() override + { + return E_BLOCK_DIRT; + } + + + void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z) override + { + if (m_BlockID != E_BLOCK_GRASS) + { + return; + } + + // Grass becomes dirt if there is something on top of it: + 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); + 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; + 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 + } + + virtual AString GetStepSound(void) override + { + return "step.gravel"; + } + +}; diff --git a/source/Blocks/BlockDispenser.h b/source/Blocks/BlockDispenser.h new file mode 100644 index 000000000..eee75a39a --- /dev/null +++ b/source/Blocks/BlockDispenser.h @@ -0,0 +1,22 @@ +#pragma once +#include "BlockEntity.h" +#include "../World.h" +#include "../Piston.h" +#include "../Player.h" + +class cBlockDispenserHandler : public cBlockEntityHandler +{ +public: + cBlockDispenserHandler(BLOCKTYPE a_BlockID) + : cBlockEntityHandler(a_BlockID) + { + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) override + { + 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..deed8a256 --- /dev/null +++ b/source/Blocks/BlockDoor.cpp @@ -0,0 +1,74 @@ +#include "Globals.h" +#include "BlockDoor.h" +#include "../Item.h" +#include "../World.h" +#include "../Doors.h" +#include "../Player.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::OnDigging(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); +} + +void cBlockDoorHandler::OnUse(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, NIBBLETYPE 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); + } +} + +AString cBlockDoorHandler::GetStepSound(void) +{ + if (m_BlockID == E_BLOCK_WOODEN_DOOR) + return "step.wood"; + + else + return "step.stone"; +} diff --git a/source/Blocks/BlockDoor.h b/source/Blocks/BlockDoor.h new file mode 100644 index 000000000..3316f50a4 --- /dev/null +++ b/source/Blocks/BlockDoor.h @@ -0,0 +1,31 @@ +#pragma once +#include "BlockHandler.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) override; + virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) override; + virtual void OnDigging(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) override; + virtual void OnUse(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) override; + virtual AString GetStepSound(void) override; + virtual char GetDropCount() override; + virtual bool IsUseable() override + { + return true; + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) override; + + virtual int GetDropID() override + { + return (m_BlockID == E_BLOCK_WOODEN_DOOR) ? E_ITEM_WOODEN_DOOR : E_ITEM_IRON_DOOR; + } + + virtual bool CanBePlacedOnSide() override + { + return false; + } +}; \ No newline at end of file diff --git a/source/Blocks/BlockEntity.h b/source/Blocks/BlockEntity.h new file mode 100644 index 000000000..caf6ee342 --- /dev/null +++ b/source/Blocks/BlockEntity.h @@ -0,0 +1,31 @@ + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockEntityHandler : public cBlockHandler +{ +public: + cBlockEntityHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual void OnUse(cWorld * a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + a_World->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); + } + + virtual bool IsUseable() override + { + return true; + } +}; + + + + diff --git a/source/Blocks/BlockFire.h b/source/Blocks/BlockFire.h new file mode 100644 index 000000000..1fecf9a14 --- /dev/null +++ b/source/Blocks/BlockFire.h @@ -0,0 +1,33 @@ +#pragma once +#include "BlockHandler.h" + + +class cBlockFireHandler : public cBlockHandler +{ +public: + cBlockFireHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual void OnDigging(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) override + { + a_World->DigBlock(a_X, a_Y, a_Z); + } + + virtual char GetDropCount() override + { + return -1; + } + + virtual bool IsClickedThrough() override + { + return true; + } + + virtual AString GetStepSound(void) override + { + return "step.wood"; + } + +}; diff --git a/source/Blocks/BlockFlower.h b/source/Blocks/BlockFlower.h new file mode 100644 index 000000000..35a55fcac --- /dev/null +++ b/source/Blocks/BlockFlower.h @@ -0,0 +1,38 @@ +#pragma once +#include "BlockHandler.h" + + +class cBlockFlowerHandler : public cBlockHandler +{ +public: + cBlockFlowerHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual NIBBLETYPE GetDropMeta(NIBBLETYPE a_BlockMeta) override + { + return 0; + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) override + { + return IsBlockTypeOfDirt(a_World->GetBlock(a_X, a_Y - 1, a_Z)); + } + + virtual bool AllowBlockOnTop() override + { + return false; + } + + virtual bool CanBePlacedOnSide() override + { + return false; + } + + virtual AString GetStepSound(void) override + { + return "step.grass"; + } + +}; diff --git a/source/Blocks/BlockFluid.h b/source/Blocks/BlockFluid.h new file mode 100644 index 000000000..c5ac660b0 --- /dev/null +++ b/source/Blocks/BlockFluid.h @@ -0,0 +1,20 @@ +#pragma once +#include "BlockHandler.h" + + +class cBlockFluidHandler : public cBlockHandler +{ +public: + cBlockFluidHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + + } + + virtual bool IgnoreBuildCollision() override + { + 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..4157b5049 --- /dev/null +++ b/source/Blocks/BlockFurnace.h @@ -0,0 +1,27 @@ +#pragma once +#include "BlockEntity.h" +#include "../World.h" +#include "../Piston.h" +#include "../Player.h" + +class cBlockFurnaceHandler : public cBlockEntityHandler +{ +public: + cBlockFurnaceHandler(BLOCKTYPE a_BlockID) + : cBlockEntityHandler(a_BlockID) + { + } + + virtual int GetDropID() override + { + return E_ITEM_FURNACE; + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) override + { + 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..0b906e2fe --- /dev/null +++ b/source/Blocks/BlockGlowstone.h @@ -0,0 +1,22 @@ +#pragma once +#include "BlockHandler.h" + + +class cBlockGlowstoneHandler : public cBlockHandler +{ +public: + cBlockGlowstoneHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual NIBBLETYPE GetDropMeta(NIBBLETYPE a_BlockMeta) override + { + return 0; + } + + virtual int GetDropID() override + { + return E_ITEM_GLOWSTONE_DUST; + } +}; \ No newline at end of file diff --git a/source/Blocks/BlockGravel.h b/source/Blocks/BlockGravel.h new file mode 100644 index 000000000..da47db9bb --- /dev/null +++ b/source/Blocks/BlockGravel.h @@ -0,0 +1,18 @@ +#pragma once +#include "BlockHandler.h" + + +class cBlockGravelHandler : public cBlockHandler +{ +public: + cBlockGravelHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual AString GetStepSound(void) override + { + return "step.gravel"; + } + +}; diff --git a/source/Blocks/BlockHandler.cpp b/source/Blocks/BlockHandler.cpp new file mode 100644 index 000000000..e6b384a23 --- /dev/null +++ b/source/Blocks/BlockHandler.cpp @@ -0,0 +1,448 @@ +#include "Globals.h" +#include "BlockHandler.h" +#include "../Item.h" +#include "../World.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 "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 "BlockStone.h" +#include "BlockMelon.h" +#include "BlockIce.h" +#include "BlockOre.h" +#include "BlockNote.h" +#include "BlockBed.h" + + + + + +bool cBlockHandler::m_HandlerInitialized = false; +cBlockHandler *cBlockHandler::m_BlockHandler[256]; + + + + + +cBlockHandler *cBlockHandler::GetBlockHandler(BLOCKTYPE a_BlockID) +{ + if (!m_HandlerInitialized) + { + //We have to initialize + memset(m_BlockHandler, 0, sizeof(m_BlockHandler)); + m_HandlerInitialized = true; + } + if (m_BlockHandler[a_BlockID] != NULL) + { + 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_SAND: + return new cBlockSandHandler(a_BlockID); + case E_BLOCK_GRAVEL: + return new cBlockGravelHandler(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_DIAMOND_ORE: + case E_BLOCK_GOLD_ORE: + case E_BLOCK_REDSTONE_ORE: + case E_BLOCK_REDSTONE_ORE_GLOWING: + case E_BLOCK_EMERALD_ORE: + case E_BLOCK_IRON_ORE: + case E_BLOCK_LAPIS_ORE: + case E_BLOCK_COAL_ORE: + return new cBlockOreHandler(a_BlockID); + case E_BLOCK_STONE: + case E_BLOCK_COBBLESTONE: + return new cBlockStoneHandler(a_BlockID); + case E_BLOCK_MELON: + return new cBlockMelonHandler(a_BlockID); + case E_BLOCK_NOTE_BLOCK: + return new cBlockNoteHandler(a_BlockID); + case E_BLOCK_BED: + return new cBlockBedHandler(a_BlockID); + default: + return new cBlockHandler(a_BlockID); + break; + } +} + + + + + +void cBlockHandler::Deinit() +{ + for(int i = 0; i < 256; i++) + { + delete m_BlockHandler[i]; + } + m_HandlerInitialized = false; +} + + + + + +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::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) +{ +} + + + + + +void cBlockHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) +{ +} + + + + + +void cBlockHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE 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); +} + + + + + +char cBlockHandler::GetDropCount() +{ + return 1; +} + + + + + +int cBlockHandler::GetDropID() +{ + return m_BlockID; +} + + + + + +NIBBLETYPE cBlockHandler::GetDropMeta(NIBBLETYPE 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; + NIBBLETYPE Meta = a_World->GetBlockMeta(a_X, a_Y, a_Z); + char DropCount = GetDropCount(); + short DropItem = (short)GetDropID(); + if (DropCount > 0 && (DropItem != E_ITEM_EMPTY)) + { + Drops.push_back(cItem(DropItem, DropCount, GetDropMeta(Meta))); + a_World->SpawnItemPickups(Drops, a_X, a_Y, a_Z); + } +} + + + + + +AString cBlockHandler::GetStepSound() { + return "step.stone"; +} + + + + + +bool cBlockHandler::CanBePlacedAt(cWorld *a_World, int a_X, int a_Y, int a_Z, char a_Dir) +{ + return CanBeAt(a_World, 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; +} + + + + diff --git a/source/Blocks/BlockHandler.h b/source/Blocks/BlockHandler.h new file mode 100644 index 000000000..859870c4a --- /dev/null +++ b/source/Blocks/BlockHandler.h @@ -0,0 +1,90 @@ +#pragma once +#include "../Defines.h" + +class cWorld; +class cPlayer; + + + +class cBlockHandler +{ +public: + cBlockHandler(BLOCKTYPE a_BlockID); + + // Called when the block gets ticked either by a random tick or by a queued tick + virtual void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z); + + // Will be called by cBlockHandler::PlaceBlock after the player has placed a new block + virtual void OnPlacedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_X, int a_Y, int a_Z, int a_Dir); + // Will be called before the player has destroyed a block + virtual void OnDestroyedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_X, int a_Y, int a_Z); + // Will be called when a new block was placed. Will be called before OnPlacedByPlayer + virtual void OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir); + // Will be called before a block gets destroyed / replaced with air + virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z); + // Will be 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_X, int a_Y, int a_Z); + // Notifies all neighbors of the give block about a change + static void NeighborChanged(cWorld *a_World, int a_X, int a_Y, int a_Z); + // Will be called while the player diggs the block. + virtual void OnDigging(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z); + // Will be called if the user right clicks the block and the block is useable + virtual void OnUse(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z); + // This function handles the real block placement for the give block by a player and also calls the OnPlacedByPlayer function + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir); + + // Indicates how much items are dropped DEFAULT: 1 + virtual char GetDropCount(); + // Indicates the id dropped by this block DEFAULT: BlockID + virtual int GetDropID(); + // Indicates the Drop Meta data based on the block meta DEFAULT: BlockMeta + virtual NIBBLETYPE GetDropMeta(NIBBLETYPE a_BlockMeta); + // This function handles the dropping of a block based on the Drop id, drop count and drop meta. This will not destroy the block + virtual void DropBlock(cWorld *a_World, int a_X, int a_Y, int a_Z); + /// Returns step sound name of block + virtual AString GetStepSound(); + + // Indicates whether this block needs random ticks DEFAULT: False + virtual bool NeedsRandomTicks(); + + /// Checks if the block can stay at the specified coords in the world + virtual bool CanBeAt(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ); + + /// 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 AllowBlockOnTop(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 IgnoreBuildCollision(void); + + /// Indicates this block can be placed on the side of other blocks. Default: true + virtual bool CanBePlacedOnSide(); + + /// Does this block drop if it gets destroyed by an unsuitable situation? Default: true + virtual bool DropOnUnsuitable(); + + + // Static function to get the blockhandler for an specific block id + static cBlockHandler * GetBlockHandler(BLOCKTYPE a_BlockID); + + // Deletes all initialised block handlers + static void Deinit(); + +protected: + BLOCKTYPE m_BlockID; + // Creates a new blockhandler for the given block id. For internal use only, use GetBlockHandler instead. + static cBlockHandler *CreateBlockHandler(BLOCKTYPE a_BlockID); + 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_BlockID) { return cBlockHandler::GetBlockHandler(a_BlockID); } \ No newline at end of file diff --git a/source/Blocks/BlockIce.h b/source/Blocks/BlockIce.h new file mode 100644 index 000000000..cc5cc8920 --- /dev/null +++ b/source/Blocks/BlockIce.h @@ -0,0 +1,26 @@ +#pragma once +#include "BlockHandler.h" +#include "../MersenneTwister.h" +#include "../World.h" + +class cBlockIceHandler : public cBlockHandler +{ +public: + cBlockIceHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual int GetDropID() override + { + return E_ITEM_EMPTY; + } + + virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) override + { + 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..ee48df848 --- /dev/null +++ b/source/Blocks/BlockLadder.h @@ -0,0 +1,40 @@ +#pragma once +#include "BlockHandler.h" +#include "../World.h" +#include "../Ladder.h" + +class cBlockLadderHandler : public cBlockHandler +{ +public: + cBlockLadderHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) override + { + 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 CanBePlacedAt(cWorld *a_World, int a_X, int a_Y, int a_Z, char a_Dir) override + { + AddDirection( a_X, a_Y, a_Z, a_Dir, true ); + return a_World->GetBlock( a_X, a_Y, a_Z ) != E_BLOCK_AIR; + } + + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) override + { + char Dir = cLadder::MetaDataToDirection(a_World->GetBlockMeta( a_X, a_Y, a_Z)); + return CanBePlacedAt(a_World, a_X, a_Y, a_Z, Dir); + } + + + virtual AString GetStepSound(void) override + { + return "step.wood"; + } + +}; diff --git a/source/Blocks/BlockLeaves.h b/source/Blocks/BlockLeaves.h new file mode 100644 index 000000000..65c47f8de --- /dev/null +++ b/source/Blocks/BlockLeaves.h @@ -0,0 +1,167 @@ +#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_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual int GetDropID() override + { + 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) override + { + 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) override + { + 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() override + { + return true; + } + + virtual void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z) override + { + 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); + + } + + virtual AString 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/BlockMelon.h b/source/Blocks/BlockMelon.h new file mode 100644 index 000000000..87fb7e1e8 --- /dev/null +++ b/source/Blocks/BlockMelon.h @@ -0,0 +1,29 @@ +#pragma once +#include "BlockHandler.h" + + +class cBlockMelonHandler : public cBlockHandler +{ +public: + cBlockMelonHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + + virtual int GetDropID() override + { + return E_ITEM_MELON_SLICE; + } + + virtual char GetDropCount() override + { + MTRand r1; + return (char)(3 + r1.randInt(4)); + } + + virtual AString GetStepSound(void) override + { + return "step.wood"; + } +}; diff --git a/source/Blocks/BlockMushroom.h b/source/Blocks/BlockMushroom.h new file mode 100644 index 000000000..c4119bad0 --- /dev/null +++ b/source/Blocks/BlockMushroom.h @@ -0,0 +1,47 @@ +#pragma once +#include "BlockHandler.h" + + +class cBlockMushroomHandler : public cBlockHandler +{ +public: + cBlockMushroomHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual NIBBLETYPE GetDropMeta(NIBBLETYPE a_BlockMeta) override + { + return 0; + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) override + { + 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() override + { + return false; + } + + + virtual bool CanBePlacedOnSide() override + { + return false; + } + + virtual AString GetStepSound(void) override + { + return "step.grass"; + } +}; diff --git a/source/Blocks/BlockNote.h b/source/Blocks/BlockNote.h new file mode 100644 index 000000000..896a5d03b --- /dev/null +++ b/source/Blocks/BlockNote.h @@ -0,0 +1,13 @@ +#pragma once +#include "BlockHandler.h" +#include "BlockEntity.h" + +class cBlockNoteHandler : public cBlockEntityHandler +{ +public: + cBlockNoteHandler(BLOCKTYPE a_BlockID) + : cBlockEntityHandler(a_BlockID) + { + } + +}; diff --git a/source/Blocks/BlockOre.h b/source/Blocks/BlockOre.h new file mode 100644 index 000000000..556a215ce --- /dev/null +++ b/source/Blocks/BlockOre.h @@ -0,0 +1,58 @@ +#pragma once +#include "BlockHandler.h" +#include "../MersenneTwister.h" +#include "../World.h" + +class cBlockOreHandler : public cBlockHandler +{ +public: + cBlockOreHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual char GetDropCount() override + { + MTRand r1; + switch(m_BlockID) + { + case E_BLOCK_LAPIS_ORE: + return 4 + (char)r1.randInt(4); + case E_BLOCK_REDSTONE_ORE: + case E_BLOCK_REDSTONE_ORE_GLOWING: + return 4 + (char)r1.randInt(1); + default: + return 1; + } + } + + virtual NIBBLETYPE GetDropMeta(NIBBLETYPE a_Meta) override + { + switch(m_BlockID) + { + case E_BLOCK_LAPIS_ORE: + return 4; + default: + return 0; + } + } + + virtual int GetDropID() override + { + switch(m_BlockID) + { + case E_BLOCK_DIAMOND_ORE: + return E_ITEM_DIAMOND; + case E_BLOCK_REDSTONE_ORE: + case E_BLOCK_REDSTONE_ORE_GLOWING: + return E_ITEM_REDSTONE_DUST; + case E_BLOCK_EMERALD_ORE: + return E_ITEM_EMERALD; + case E_BLOCK_LAPIS_ORE: + return E_ITEM_DYE; + case E_BLOCK_COAL_ORE: + return E_ITEM_COAL; + } + return m_BlockID; + } +}; \ No newline at end of file diff --git a/source/Blocks/BlockPiston.cpp b/source/Blocks/BlockPiston.cpp new file mode 100644 index 000000000..a4ed13d88 --- /dev/null +++ b/source/Blocks/BlockPiston.cpp @@ -0,0 +1,51 @@ +#include "Globals.h" +#include "BlockPiston.h" +#include "../Item.h" +#include "../World.h" +#include "../Redstone.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_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, NIBBLETYPE 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..dbce9bae5 --- /dev/null +++ b/source/Blocks/BlockPiston.h @@ -0,0 +1,15 @@ +#pragma once +#include "BlockHandler.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) override; + virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) override; + + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) override; + +}; \ No newline at end of file diff --git a/source/Blocks/BlockRedstone.cpp b/source/Blocks/BlockRedstone.cpp new file mode 100644 index 000000000..7653436f4 --- /dev/null +++ b/source/Blocks/BlockRedstone.cpp @@ -0,0 +1,41 @@ +#include "Globals.h" +#include "BlockRedstone.h" +#include "../Item.h" +#include "../World.h" +#include "../Redstone.h" +#include "../Torch.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, NIBBLETYPE 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..9b83b1b29 --- /dev/null +++ b/source/Blocks/BlockRedstone.h @@ -0,0 +1,33 @@ +#pragma once +#include "BlockHandler.h" +#include "../World.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) override; + virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) override; + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) override; + + virtual bool AllowBlockOnTop() override + { + return false; + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) override + { + return a_World->GetBlock(a_X, a_Y - 1, a_Z) != E_BLOCK_AIR; + } + + virtual int GetDropID() override + { + return E_ITEM_REDSTONE_DUST; + } + + virtual bool CanBePlacedOnSide() override + { + return false; + } +}; \ No newline at end of file diff --git a/source/Blocks/BlockRedstoneRepeater.cpp b/source/Blocks/BlockRedstoneRepeater.cpp new file mode 100644 index 000000000..861f6e221 --- /dev/null +++ b/source/Blocks/BlockRedstoneRepeater.cpp @@ -0,0 +1,39 @@ +#include "Globals.h" +#include "BlockRedstoneRepeater.h" +#include "../Item.h" +#include "../World.h" +#include "../Redstone.h" +#include "../Player.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::OnUse(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::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) +{ + OnUse(a_World, a_Player, a_X, a_Y, a_Z); +} + +void cBlockRedstoneRepeaterHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE 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..a928f554f --- /dev/null +++ b/source/Blocks/BlockRedstoneRepeater.h @@ -0,0 +1,52 @@ +#pragma once +#include "BlockHandler.h" +#include "../World.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) override; + virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) override; + + virtual void OnDigging(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) override; + virtual void OnUse(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) override; + + virtual NIBBLETYPE GetDropMeta(NIBBLETYPE a_BlockMeta) override + { + return 0; + } + + virtual int GetDropID() override + { + return E_ITEM_REDSTONE_REPEATER; + } + + virtual bool IsUseable() override + { + return true; + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) override; + + virtual bool AllowBlockOnTop() override + { + return false; + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) override + { + return a_World->GetBlock(a_X, a_Y - 1, a_Z) != E_BLOCK_AIR; + } + + + virtual bool CanBePlacedOnSide() override + { + return false; + } + + virtual AString GetStepSound(void) override + { + return "step.wood"; + } +}; diff --git a/source/Blocks/BlockRedstoneTorch.h b/source/Blocks/BlockRedstoneTorch.h new file mode 100644 index 000000000..eeb2afc5c --- /dev/null +++ b/source/Blocks/BlockRedstoneTorch.h @@ -0,0 +1,28 @@ + +#pragma once +#include "BlockRedstone.h" +#include "BlockTorch.h" +#include "../Torch.h" + + + + + +class cBlockRedstoneTorchHandler : public cBlockTorchHandler +{ +public: + cBlockRedstoneTorchHandler(BLOCKTYPE a_BlockID) + : cBlockTorchHandler(a_BlockID) + { + } + + virtual int GetDropID(void) override + { + return E_ITEM_REDSTONE_TORCH_ON; + } + + virtual AString GetStepSound(void) override + { + return "step.wood"; + } +}; diff --git a/source/Blocks/BlockSand.h b/source/Blocks/BlockSand.h new file mode 100644 index 000000000..69fda5ec6 --- /dev/null +++ b/source/Blocks/BlockSand.h @@ -0,0 +1,18 @@ +#pragma once +#include "BlockHandler.h" + + +class cBlockSandHandler : public cBlockHandler +{ +public: + cBlockSandHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual AString GetStepSound(void) override + { + return "step.sand"; + } + +}; diff --git a/source/Blocks/BlockSapling.h b/source/Blocks/BlockSapling.h new file mode 100644 index 000000000..c9862349a --- /dev/null +++ b/source/Blocks/BlockSapling.h @@ -0,0 +1,56 @@ +#pragma once +#include "BlockHandler.h" +#include "../World.h" + +class cBlockSaplingHandler : public cBlockHandler +{ +public: + cBlockSaplingHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual bool NeedsRandomTicks() override + { + return true; + } + + virtual NIBBLETYPE GetDropMeta(NIBBLETYPE a_BlockMeta) override + { + 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) override + { + return IsBlockTypeOfDirt(a_World->GetBlock(a_X, a_Y - 1, a_Z)); + } + + virtual bool AllowBlockOnTop() override + { + return false; + } + + void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z) override + { + 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() override + { + return false; + } + + virtual AString GetStepSound(void) override + { + return "step.grass"; + } +}; diff --git a/source/Blocks/BlockSign.h b/source/Blocks/BlockSign.h new file mode 100644 index 000000000..dd82605b3 --- /dev/null +++ b/source/Blocks/BlockSign.h @@ -0,0 +1,47 @@ +#pragma once +#include "BlockHandler.h" +#include "../World.h" +#include "../Sign.h" +#include "../Player.h" + +class cBlockSignHandler : public cBlockHandler +{ +public: + cBlockSignHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) override + { + 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() override + { + return E_ITEM_SIGN; + } + + virtual bool AllowBlockOnTop() override + { + return false; + } + + virtual AString GetStepSound(void) override + { + return "step.wood"; + } +}; diff --git a/source/Blocks/BlockSlab.h b/source/Blocks/BlockSlab.h new file mode 100644 index 000000000..ad9970d67 --- /dev/null +++ b/source/Blocks/BlockSlab.h @@ -0,0 +1,51 @@ +#pragma once +#include "BlockHandler.h" + + +class cBlockSlabHandler : public cBlockHandler +{ +public: + cBlockSlabHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual NIBBLETYPE GetDropMeta(NIBBLETYPE a_BlockMeta) override + { + return a_BlockMeta; + } + + virtual char GetDropCount() override + { + 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, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) override + { + 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); + } + + static char DirectionToMetaData( char a_Direction, NIBBLETYPE Meta ) + { + char result = Meta; + if( a_Direction == 0) + { + result |= 0x8; + } + return result; + } + + virtual AString GetStepSound(void) override + { + if (m_BlockID == E_BLOCK_WOODEN_SLAB || m_BlockID ==E_BLOCK_DOUBLE_WOODEN_SLAB) + return "step.wood"; + + else + return "step.stone"; + } +}; diff --git a/source/Blocks/BlockSnow.h b/source/Blocks/BlockSnow.h new file mode 100644 index 000000000..c8e6b4c1c --- /dev/null +++ b/source/Blocks/BlockSnow.h @@ -0,0 +1,44 @@ +#pragma once +#include "BlockHandler.h" + + +class cBlockSnowHandler : public cBlockHandler +{ +public: + cBlockSnowHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual bool IgnoreBuildCollision() override + { + return true; + } + + virtual int GetDropID() override + { + return E_ITEM_SNOWBALL; + } + + virtual char GetDropCount() override + { + return 4; + } + + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) override + { + return a_World->GetBlock(a_X, a_Y - 1, a_Z) != E_BLOCK_AIR; + } + + virtual bool DropOnUnsuitable() override + { + return false; + } + + virtual AString GetStepSound(void) override + { + return "step.cloth"; + } + +}; diff --git a/source/Blocks/BlockStairs.h b/source/Blocks/BlockStairs.h new file mode 100644 index 000000000..4d0007bc5 --- /dev/null +++ b/source/Blocks/BlockStairs.h @@ -0,0 +1,22 @@ +#pragma once +#include "BlockHandler.h" +#include "../Stairs.h" + +class cBlockStairsHandler : public cBlockHandler +{ +public: + cBlockStairsHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + + } + + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) override + { + 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); + } + + //TODO: step sound +}; diff --git a/source/Blocks/BlockStems.h b/source/Blocks/BlockStems.h new file mode 100644 index 000000000..be4519a52 --- /dev/null +++ b/source/Blocks/BlockStems.h @@ -0,0 +1,46 @@ +#pragma once +#include "BlockHandler.h" +#include "../MersenneTwister.h" +#include "../World.h" + +class cBlockStemsHandler : public cBlockHandler +{ +public: + cBlockStemsHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual bool NeedsRandomTicks() override + { + return true; + } + + virtual NIBBLETYPE GetDropMeta(NIBBLETYPE a_BlockMeta) override + { + return 0; + } + + virtual int GetDropID() override + { + 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) override + { + //TODO: Handle Growing here + } + + virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) override + { + return a_World->GetBlock(a_X, a_Y - 1, a_Z) == E_BLOCK_FARMLAND; + } + + virtual AString GetStepSound(void) override + { + return "step.wood"; + } + +}; diff --git a/source/Blocks/BlockStone.h b/source/Blocks/BlockStone.h new file mode 100644 index 000000000..8b645bf1e --- /dev/null +++ b/source/Blocks/BlockStone.h @@ -0,0 +1,18 @@ +#pragma once +#include "BlockHandler.h" +#include "../MersenneTwister.h" +#include "../World.h" + +class cBlockStoneHandler : public cBlockHandler +{ +public: + cBlockStoneHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual int GetDropID() override + { + 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..1d477b42b --- /dev/null +++ b/source/Blocks/BlockSugarcane.h @@ -0,0 +1,71 @@ + +#pragma once +#include "BlockHandler.h" + + + + + +class cBlockSugarcaneHandler : + public cBlockHandler +{ +public: + cBlockSugarcaneHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + + virtual bool NeedsRandomTicks() override + { + return true; + } + + + virtual int GetDropID() override + { + return E_ITEM_SUGARCANE; + } + + + virtual bool CanBeAt(cWorld * a_World, int a_X, int a_Y, int a_Z) override + { + switch (a_World->GetBlock(a_X, a_Y - 1, a_Z)) + { + case E_BLOCK_DIRT: + case E_BLOCK_GRASS: + case E_BLOCK_FARMLAND: + case E_BLOCK_SAND: + { + return a_World->IsBlockDirectlyWatered(a_X, a_Y - 1, a_Z); + } + case E_BLOCK_SUGARCANE: + { + return true; + } + } + return false; + } + + + void OnUpdate(cWorld * a_World, int a_X, int a_Y, int a_Z) override + { + //TODO: Handle Growing here + } + + + virtual bool CanBePlacedOnSide() override + { + return false; + } + + virtual AString GetStepSound(void) override + { + return "step.grass"; + } + +}; + + + + diff --git a/source/Blocks/BlockTallGrass.h b/source/Blocks/BlockTallGrass.h new file mode 100644 index 000000000..f5bb1b373 --- /dev/null +++ b/source/Blocks/BlockTallGrass.h @@ -0,0 +1,41 @@ +#pragma once +#include "BlockHandler.h" + + +class cBlockTallGrassHandler : public cBlockHandler +{ +public: + cBlockTallGrassHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual bool IgnoreBuildCollision() override + { + return true; + } + + virtual int GetDropID() override + { + return E_ITEM_SEEDS; + } + + virtual char GetDropCount() override + { + 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) override + { + return a_World->GetBlock(a_X, a_Y - 1, a_Z) != E_BLOCK_AIR; + } + + virtual AString GetStepSound(void) override + { + return "step.grass"; + } + +}; diff --git a/source/Blocks/BlockTorch.h b/source/Blocks/BlockTorch.h new file mode 100644 index 000000000..450b5ecab --- /dev/null +++ b/source/Blocks/BlockTorch.h @@ -0,0 +1,166 @@ + +#pragma once +#include "BlockHandler.h" +#include "../Torch.h" +#include "../World.h" + + + + + +class cBlockTorchHandler : public cBlockHandler +{ +public: + cBlockTorchHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + + virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) override + { + if(!TorchCanBePlacedAt(a_World, a_X, a_Y, a_Z, a_Dir)) + { + a_Dir = FindSuitableDirection(a_World, a_X, a_Y, a_Z); + + if(a_Dir == BLOCK_FACE_BOTTOM) + return; + } + + 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); + } + + + virtual bool AllowBlockOnTop(void) override + { + return false; + } + + + static bool CanBePlacedOn(BLOCKTYPE a_BlockType, char a_Direction) + { + switch (a_BlockType) + { + case E_BLOCK_STONE: + case E_BLOCK_GRASS: + case E_BLOCK_DIRT: + case E_BLOCK_COBBLESTONE: + case E_BLOCK_PLANKS: + case E_BLOCK_BEDROCK: + case E_BLOCK_SAND: + case E_BLOCK_GRAVEL: + case E_BLOCK_GOLD_ORE: + case E_BLOCK_IRON_ORE: + case E_BLOCK_COAL_ORE: + case E_BLOCK_LOG: + case E_BLOCK_SPONGE: + case E_BLOCK_LAPIS_ORE: + case E_BLOCK_LAPIS_BLOCK: + case E_BLOCK_SANDSTONE: + case E_BLOCK_WOOL: + case E_BLOCK_GOLD_BLOCK: + case E_BLOCK_IRON_BLOCK: + case E_BLOCK_DOUBLE_STONE_SLAB: + case E_BLOCK_BRICK: + case E_BLOCK_BOOKCASE: + case E_BLOCK_MOSSY_COBBLESTONE: + case E_BLOCK_OBSIDIAN: + case E_BLOCK_MOB_SPAWNER: + case E_BLOCK_DIAMOND_ORE: + case E_BLOCK_DIAMOND_BLOCK: + case E_BLOCK_CRAFTING_TABLE: + case E_BLOCK_REDSTONE_ORE: + case E_BLOCK_REDSTONE_ORE_GLOWING: + case E_BLOCK_SNOW_BLOCK: + case E_BLOCK_CLAY: + case E_BLOCK_JUKEBOX: + case E_BLOCK_PUMPKIN: + case E_BLOCK_NETHERRACK: + case E_BLOCK_SOULSAND: + case E_BLOCK_JACK_O_LANTERN: + case E_BLOCK_LOCKED_CHEST: + case E_BLOCK_STONE_BRICKS: + case E_BLOCK_MELON: + case E_BLOCK_MYCELIUM: + case E_BLOCK_NETHER_BRICK: + case E_BLOCK_END_STONE: + case E_BLOCK_REDSTONE_LAMP_OFF: + case E_BLOCK_REDSTONE_LAMP_ON: + case E_BLOCK_DOUBLE_WOODEN_SLAB: + case E_BLOCK_EMERALD_ORE: + case E_BLOCK_ENDER_CHEST: + case E_BLOCK_EMERALD_BLOCK: + { + return true; + } + + 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 false; + } + } + } + + + static bool TorchCanBePlacedAt(cWorld * a_World, int a_X, int a_Y, int a_Z, char a_Dir) + { + // 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_Dir == BLOCK_FACE_BOTTOM) + return false; + + AddDirection( a_X, a_Y, a_Z, a_Dir, true ); + + return CanBePlacedOn(a_World->GetBlock( a_X, a_Y, a_Z ), a_Dir); + } + + // Finds a suitable Direction for the Torch. Returns BLOCK_FACE_BOTTOM on failure + static char FindSuitableDirection(cWorld * a_World, int a_X, int a_Y, int a_Z) + { + for(int i = 1; i <= 5; i++) + { + if(TorchCanBePlacedAt(a_World, a_X, a_Y, a_Z, i)) + return i; + } + return BLOCK_FACE_BOTTOM; + } + + virtual bool CanBePlacedAt(cWorld * a_World, int a_X, int a_Y, int a_Z, char a_Dir) override + { + if(TorchCanBePlacedAt(a_World, a_X, a_Y, a_Z, a_Dir)) + return true; + + return FindSuitableDirection(a_World, a_X, a_Y, a_Z) != BLOCK_FACE_BOTTOM; + } + + + virtual bool CanBeAt(cWorld * a_World, int a_X, int a_Y, int a_Z) override + { + char Dir = cTorch::MetaDataToDirection(a_World->GetBlockMeta( a_X, a_Y, a_Z)); + return TorchCanBePlacedAt(a_World, a_X, a_Y, a_Z, Dir); + } + + virtual NIBBLETYPE GetDropMeta(NIBBLETYPE a_BlockMeta) override + { + return 0; + } + + virtual AString GetStepSound(void) override + { + return "step.wood"; + } +}; + + + + diff --git a/source/Blocks/BlockVine.h b/source/Blocks/BlockVine.h new file mode 100644 index 000000000..56317219a --- /dev/null +++ b/source/Blocks/BlockVine.h @@ -0,0 +1,35 @@ +#pragma once +#include "BlockHandler.h" +#include "../Vine.h" + +class cBlockVineHandler : public cBlockHandler +{ +public: + cBlockVineHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual bool IgnoreBuildCollision() override + { + return true; + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) override + { + 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); + } + + + virtual bool AllowBlockOnTop() override + { + return false; + } + + virtual AString GetStepSound(void) override + { + return "step.grass"; + } + +}; diff --git a/source/Blocks/BlockWood.h b/source/Blocks/BlockWood.h new file mode 100644 index 000000000..d71d5d71c --- /dev/null +++ b/source/Blocks/BlockWood.h @@ -0,0 +1,22 @@ +#pragma once +#include "BlockHandler.h" + + +class cBlockWoodHandler : public cBlockHandler +{ +public: + cBlockWoodHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + NIBBLETYPE GetDropMeta(NIBBLETYPE a_BlockMeta) override + { + return a_BlockMeta; + } + + virtual AString GetStepSound(void) override + { + return "step.wood"; + } + +}; diff --git a/source/Blocks/BlockWorkbench.h b/source/Blocks/BlockWorkbench.h new file mode 100644 index 000000000..c1c004dc5 --- /dev/null +++ b/source/Blocks/BlockWorkbench.h @@ -0,0 +1,36 @@ +#pragma once +#include "BlockHandler.h" +#include "../UI/Window.h" +#include "../Player.h" + + + + + +class cBlockWorkbenchHandler: + public cBlockHandler +{ +public: + cBlockWorkbenchHandler(BLOCKTYPE a_BlockID) + : cBlockHandler(a_BlockID) + { + } + + virtual void OnUse(cWorld * a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + cWindow * Window = new cCraftingWindow(a_BlockX, a_BlockY, a_BlockZ); + a_Player->OpenWindow(Window); + } + + virtual bool IsUseable() override + { + return true; + } + + virtual AString GetStepSound(void) override + { + return "step.wood"; + } + + +}; \ No newline at end of file -- cgit v1.2.3