From 43e684071933adef93040e8d4b830d5c6b71cf9a Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sat, 12 Jan 2013 04:46:01 +0000 Subject: Merged branch "branches/hooks" into "trunk". git-svn-id: http://mc-server.googlecode.com/svn/trunk@1139 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/Blocks/BlockBed.cpp | 32 ++--- source/Blocks/BlockBed.h | 4 +- source/Blocks/BlockChest.h | 108 ++++++++++----- source/Blocks/BlockDispenser.h | 25 ++-- source/Blocks/BlockDoor.cpp | 42 +++--- source/Blocks/BlockDoor.h | 67 +++++++++- source/Blocks/BlockEntity.h | 2 +- source/Blocks/BlockFenceGate.h | 35 ++--- source/Blocks/BlockFlowerPot.h | 47 +++++-- source/Blocks/BlockFurnace.h | 16 ++- source/Blocks/BlockHandler.cpp | 37 +++--- source/Blocks/BlockHandler.h | 34 +++-- source/Blocks/BlockLadder.h | 49 ++++--- source/Blocks/BlockLever.cpp | 36 +---- source/Blocks/BlockLever.h | 26 +++- source/Blocks/BlockPiston.cpp | 21 ++- source/Blocks/BlockPiston.h | 27 +++- source/Blocks/BlockRail.h | 225 ++++++++++++++++++-------------- source/Blocks/BlockRedstone.cpp | 28 ---- source/Blocks/BlockRedstone.h | 5 +- source/Blocks/BlockRedstoneRepeater.cpp | 23 +--- source/Blocks/BlockRedstoneRepeater.h | 6 +- source/Blocks/BlockSign.h | 20 --- source/Blocks/BlockSlab.h | 45 +++++-- source/Blocks/BlockStairs.h | 50 +++++-- source/Blocks/BlockTorch.h | 48 ++++--- source/Blocks/BlockVine.h | 28 ++-- source/Blocks/BlockWorkbench.h | 2 +- 28 files changed, 633 insertions(+), 455 deletions(-) (limited to 'source/Blocks') diff --git a/source/Blocks/BlockBed.cpp b/source/Blocks/BlockBed.cpp index 19dfbfd3d..57af759b8 100644 --- a/source/Blocks/BlockBed.cpp +++ b/source/Blocks/BlockBed.cpp @@ -5,25 +5,18 @@ -void cBlockBedHandler::PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) +void cBlockBedHandler::OnPlacedByPlayer( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta +) { - if (a_Dir != 1) // Can only be placed on the floor + if (a_BlockMeta < 8) { - return; + Vector3i Direction = MetaDataToDirection(a_BlockMeta); + a_World->SetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z, E_BLOCK_BED, a_BlockMeta | 0x8); } - - NIBBLETYPE Meta = RotationToMetaData( a_Player->GetRotation() ); - Vector3i Direction = MetaDataToDirection( Meta ); - - if (a_World->GetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z) != E_BLOCK_AIR) - { - return; - } - - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_BED, Meta); - a_World->SetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z, E_BLOCK_BED, Meta | 0x8); - - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); } @@ -58,13 +51,13 @@ void cBlockBedHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, -void cBlockBedHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) +void cBlockBedHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) { NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); if (Meta & 0x8) { // Is pillow - a_World->BroadcastUseBed( *a_Player, a_BlockX, a_BlockY, a_BlockZ ); + a_World->BroadcastUseBed(*a_Player, a_BlockX, a_BlockY, a_BlockZ); } else { @@ -72,9 +65,8 @@ void cBlockBedHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, i Vector3i Direction = MetaDataToDirection( Meta & 0x7 ); if (a_World->GetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z) == E_BLOCK_BED) // Must always use pillow location for sleeping { - a_World->BroadcastUseBed(*a_Player, a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z ); + a_World->BroadcastUseBed(*a_Player, a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z); } - } } diff --git a/source/Blocks/BlockBed.h b/source/Blocks/BlockBed.h index 0c3d3b028..f4e48f195 100644 --- a/source/Blocks/BlockBed.h +++ b/source/Blocks/BlockBed.h @@ -20,9 +20,9 @@ public: } - virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override; + virtual void OnPlacedByPlayer(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; virtual bool IsUseable(void) override diff --git a/source/Blocks/BlockChest.h b/source/Blocks/BlockChest.h index 09d80be76..6de6a8e29 100644 --- a/source/Blocks/BlockChest.h +++ b/source/Blocks/BlockChest.h @@ -19,41 +19,89 @@ public: } - virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override { + a_BlockType = m_BlockType; + + // Is there a doublechest already next to this block? + if (!CanBeAt(a_World, a_BlockX, a_BlockY, a_BlockZ)) + { + // Yup, cannot form a triple-chest, refuse: + return false; + } + // Check if this forms a doublechest, if so, need to adjust the meta: cBlockArea Area; - if (Area.Read(a_World, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1)) + if (!Area.Read(a_World, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1)) { - float rot = a_Player->GetRotation(); - // Choose meta from player rotation, choose only between 2 or 3 - NIBBLETYPE NewMeta = ((rot >= -90) && (rot < 90)) ? 2 : 3; - if ( - CheckAndAdjustNeighbor(a_World, Area, 0, 1, NewMeta) || - CheckAndAdjustNeighbor(a_World, Area, 2, 1, NewMeta) - ) - { - // Forming a double chest in the X direction - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, NewMeta); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); - return; - } - // Choose meta from player rotation, choose only between 4 or 5 - NewMeta = (rot < 0) ? 4 : 5; - if ( - CheckAndAdjustNeighbor(a_World, Area, 1, 0, NewMeta) || - CheckAndAdjustNeighbor(a_World, Area, 2, 2, NewMeta) - ) - { - // Forming a double chest in the Z direction - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, NewMeta); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); - return; - } + return false; + } + float rot = a_Player->GetRotation(); + if ( + (Area.GetRelBlockType(0, 0, 1) == E_BLOCK_CHEST) || + (Area.GetRelBlockType(2, 0, 1) == E_BLOCK_CHEST) + ) + { + a_BlockMeta = ((rot >= -90) && (rot < 90)) ? 2 : 3; + return true; + } + if ( + (Area.GetRelBlockType(0, 0, 1) == E_BLOCK_CHEST) || + (Area.GetRelBlockType(2, 0, 1) == E_BLOCK_CHEST) + ) + { + a_BlockMeta = (rot < 0) ? 4 : 5; + return true; } - // Single chest or unable to read neighbors (don't really care, then): - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, RotationToMetaData(a_Player->GetRotation())); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); + + // Single chest, get meta from rotation only + a_BlockMeta = RotationToMetaData(rot); + return true; + } + + + virtual void OnPlacedByPlayer( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta + ) override + { + // Check if this forms a doublechest, if so, need to adjust the meta: + cBlockArea Area; + if (!Area.Read(a_World, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1)) + { + return; + } + + float rot = a_Player->GetRotation(); + // Choose meta from player rotation, choose only between 2 or 3 + NIBBLETYPE NewMeta = ((rot >= -90) && (rot < 90)) ? 2 : 3; + if ( + CheckAndAdjustNeighbor(a_World, Area, 0, 1, NewMeta) || + CheckAndAdjustNeighbor(a_World, Area, 2, 1, NewMeta) + ) + { + // Forming a double chest in the X direction + return; + } + // Choose meta from player rotation, choose only between 4 or 5 + NewMeta = (rot < 0) ? 4 : 5; + if ( + CheckAndAdjustNeighbor(a_World, Area, 1, 0, NewMeta) || + CheckAndAdjustNeighbor(a_World, Area, 2, 2, NewMeta) + ) + { + // Forming a double chest in the Z direction + return; + } + + // Single chest, no further processing needed } diff --git a/source/Blocks/BlockDispenser.h b/source/Blocks/BlockDispenser.h index 581e0f49b..a1aa45964 100644 --- a/source/Blocks/BlockDispenser.h +++ b/source/Blocks/BlockDispenser.h @@ -14,16 +14,25 @@ class cBlockDispenserHandler : public cBlockEntityHandler { public: - cBlockDispenserHandler(BLOCKTYPE a_BlockType) - : cBlockEntityHandler(a_BlockType) + cBlockDispenserHandler(BLOCKTYPE a_BlockType) : + cBlockEntityHandler(a_BlockType) { } - virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override + + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override { - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0)); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); + a_BlockType = m_BlockType; + a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0); + return true; } - - -}; \ No newline at end of file +} ; + + + + diff --git a/source/Blocks/BlockDoor.cpp b/source/Blocks/BlockDoor.cpp index a2c352d7b..49ce56e07 100644 --- a/source/Blocks/BlockDoor.cpp +++ b/source/Blocks/BlockDoor.cpp @@ -19,18 +19,9 @@ cBlockDoorHandler::cBlockDoorHandler(BLOCKTYPE a_BlockType) -void cBlockDoorHandler::OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) -{ - -} - - - - - void cBlockDoorHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) { - char OldMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + NIBBLETYPE OldMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); if (OldMeta & 8) { @@ -54,7 +45,7 @@ void cBlockDoorHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY -void cBlockDoorHandler::OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) +void cBlockDoorHandler::OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) { cDoors::ChangeDoor(a_World, a_BlockX, a_BlockY, a_BlockZ); } @@ -63,23 +54,24 @@ void cBlockDoorHandler::OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX -void cBlockDoorHandler::PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) +void cBlockDoorHandler::OnPlacedByPlayer( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta +) { - if (a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ) == E_BLOCK_AIR) + NIBBLETYPE a_TopBlockMeta = 8; + if ( + (a_BlockMeta == 0) && (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) == m_BlockType) || + (a_BlockMeta == 1) && (a_World->GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) == m_BlockType) || + (a_BlockMeta == 2) && (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) == m_BlockType) || + (a_BlockMeta == 3) && (a_World->GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) == m_BlockType) + ) { - a_BlockMeta = cDoors::RotationToMetaData(a_Player->GetRotation()); - char a_TopBlockMeta = 8; - if( (a_BlockMeta == 0) && (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) == m_BlockType) || - (a_BlockMeta == 1) && (a_World->GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) == m_BlockType) || - (a_BlockMeta == 2) && (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) == m_BlockType) || - (a_BlockMeta == 3) && (a_World->GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) == m_BlockType)) - { - a_TopBlockMeta = 9; - } - a_World->SetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, a_TopBlockMeta); - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, a_BlockMeta); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); + a_TopBlockMeta = 9; } + a_World->SetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, a_TopBlockMeta); } diff --git a/source/Blocks/BlockDoor.h b/source/Blocks/BlockDoor.h index d2bb27901..0e4a5ff52 100644 --- a/source/Blocks/BlockDoor.h +++ b/source/Blocks/BlockDoor.h @@ -3,6 +3,8 @@ #include "BlockHandler.h" #include "../World.h" +#include "../Doors.h" +#include "../Player.h" @@ -13,32 +15,89 @@ class cBlockDoorHandler : { public: cBlockDoorHandler(BLOCKTYPE a_BlockType); - virtual void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) override; + virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; virtual const char * GetStepSound(void) override; + + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + // If clicking a bottom face, place the door one block lower: + if (a_BlockFace == BLOCK_FACE_BOTTOM) + { + a_BlockY--; + } + + if ( + !CanReplaceBlock(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ)) || + !CanReplaceBlock(a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)) + ) + { + return false; + } + + a_BlockType = m_BlockType; + a_BlockMeta = cDoors::RotationToMetaData(a_Player->GetRotation()); + return true; + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { a_Pickups.push_back(cItem((m_BlockType == E_BLOCK_WOODEN_DOOR) ? E_ITEM_WOODEN_DOOR : E_ITEM_IRON_DOOR, 1, 0)); } - virtual bool IsUseable() override + + virtual void OnPlacedByPlayer( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta + ) override; + + + virtual bool IsUseable(void) override { return true; } - virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override; virtual bool CanBePlacedOnSide(void) override { return false; } + virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override { return (a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) != E_BLOCK_AIR); } + + + bool CanReplaceBlock(BLOCKTYPE a_BlockType) + { + switch (a_BlockType) + { + case E_BLOCK_AIR: + case E_BLOCK_TALL_GRASS: + case E_BLOCK_WATER: + case E_BLOCK_STATIONARY_WATER: + case E_BLOCK_LAVA: + case E_BLOCK_STATIONARY_LAVA: + case E_BLOCK_SNOW: + case E_BLOCK_FIRE: + { + return true; + } + } + return false; + } } ; diff --git a/source/Blocks/BlockEntity.h b/source/Blocks/BlockEntity.h index 458cb33bd..8b82b43a6 100644 --- a/source/Blocks/BlockEntity.h +++ b/source/Blocks/BlockEntity.h @@ -15,7 +15,7 @@ public: { } - virtual void OnUse(cWorld * a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual void OnUse(cWorld * a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { a_World->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); } diff --git a/source/Blocks/BlockFenceGate.h b/source/Blocks/BlockFenceGate.h index 0390bcc7d..0c17a0acc 100644 --- a/source/Blocks/BlockFenceGate.h +++ b/source/Blocks/BlockFenceGate.h @@ -12,41 +12,44 @@ class cBlockFenceGateHandler : public cBlockHandler { public: - cBlockFenceGateHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + cBlockFenceGateHandler(BLOCKTYPE a_BlockType) : + cBlockHandler(a_BlockType) { } - void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) - { - - } - void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override { + a_BlockType = m_BlockType; a_BlockMeta = cDoors::RotationToMetaData(a_Player->GetRotation() + 270); - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, a_BlockMeta); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); + return true; } - void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) + + virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { - char OldMetaData = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - char NewMetaData = cDoors::RotationToMetaData(a_Player->GetRotation() + 270); + NIBBLETYPE OldMetaData = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + NIBBLETYPE NewMetaData = cDoors::RotationToMetaData(a_Player->GetRotation() + 270); OldMetaData ^= 4; //Toggle the gate - if((OldMetaData & 1) == (NewMetaData & 1)) + if ((OldMetaData & 1) == (NewMetaData & 1)) { - //Standing in front of the gate - apply new direction + // Standing in front of the gate - apply new direction a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, (OldMetaData & 4) | (NewMetaData & 3)); } else { - //Standing aside - use last direction + // Standing aside - use last direction a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, OldMetaData); } } - virtual bool IsUseable() override + + virtual bool IsUseable(void) override { return true; } diff --git a/source/Blocks/BlockFlowerPot.h b/source/Blocks/BlockFlowerPot.h index 36f4389c3..ba93430f8 100644 --- a/source/Blocks/BlockFlowerPot.h +++ b/source/Blocks/BlockFlowerPot.h @@ -11,17 +11,21 @@ class cBlockFlowerPotHandler : public cBlockHandler { public: - cBlockFlowerPotHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + cBlockFlowerPotHandler(BLOCKTYPE a_BlockType) : + cBlockHandler(a_BlockType) { } + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { a_Pickups.push_back(cItem(E_ITEM_FLOWER_POT, 1, 0)); - if( a_BlockMeta == 0 ) return; + if (a_BlockMeta == 0) + { + return; + } cItem Plant; - switch( a_BlockMeta ) + switch (a_BlockMeta) { case 1: Plant = cItem(E_ITEM_RED_ROSE, 1, 0); break; case 2: Plant = cItem(E_ITEM_YELLOW_FLOWER, 1, 0); break; @@ -34,21 +38,28 @@ public: case 9: Plant = cItem(E_ITEM_CACTUS, 1, 0); break; case 10: Plant = cItem(E_BLOCK_DEAD_BUSH, 1, 0); break; case 11: Plant = cItem(E_BLOCK_TALL_GRASS, 1, E_META_TALL_GRASS_FERN); break; + default: return; } a_Pickups.push_back(Plant); } + void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) { - char Meta = a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ ); - if( Meta ) return; - switch( a_Player->GetEquippedItem().m_ItemType ) + NIBBLETYPE Meta = a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ ); + if (Meta != 0) + { + // Already filled + return; + } + + switch (a_Player->GetEquippedItem().m_ItemType) { case E_ITEM_RED_ROSE: Meta = 1; break; case E_ITEM_YELLOW_FLOWER: Meta = 2; break; case E_ITEM_SAPLING: { - switch( a_Player->GetEquippedItem().m_ItemDamage ) + switch (a_Player->GetEquippedItem().m_ItemDamage) { case E_META_SAPLING_APPLE: Meta = 3; break; case E_META_SAPLING_CONIFER: Meta = 4; break; @@ -62,17 +73,29 @@ public: case E_ITEM_CACTUS: Meta = 9; break; case E_BLOCK_DEAD_BUSH: Meta = 10; break; case E_BLOCK_TALL_GRASS: - if( a_Player->GetEquippedItem().m_ItemDamage == E_META_TALL_GRASS_FERN ) Meta = 11; break; + { + if (a_Player->GetEquippedItem().m_ItemDamage == E_META_TALL_GRASS_FERN) + { + Meta = 11; + } + else + { + return; + } + break; + } } - if(a_Player->GetGameMode() != eGameMode_Creative) + + if (a_Player->GetGameMode() != eGameMode_Creative) { cItem Item(a_Player->GetEquippedItem().m_ItemType, 1); a_Player->GetInventory().RemoveItem(Item); } - a_World->SetBlockMeta( a_BlockX, a_BlockY, a_BlockZ, Meta ); + a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); } - virtual bool IsUseable() override + + virtual bool IsUseable(void) override { return true; } diff --git a/source/Blocks/BlockFurnace.h b/source/Blocks/BlockFurnace.h index 356014b11..e50641258 100644 --- a/source/Blocks/BlockFurnace.h +++ b/source/Blocks/BlockFurnace.h @@ -14,8 +14,8 @@ class cBlockFurnaceHandler : public cBlockEntityHandler { public: - cBlockFurnaceHandler(BLOCKTYPE a_BlockType) - : cBlockEntityHandler(a_BlockType) + cBlockFurnaceHandler(BLOCKTYPE a_BlockType) : + cBlockEntityHandler(a_BlockType) { } @@ -26,10 +26,16 @@ public: } - virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override { - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0)); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); + a_BlockType = m_BlockType; + a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0); + return true; } } ; diff --git a/source/Blocks/BlockHandler.cpp b/source/Blocks/BlockHandler.cpp index 0356589fa..715db910e 100644 --- a/source/Blocks/BlockHandler.cpp +++ b/source/Blocks/BlockHandler.cpp @@ -207,6 +207,23 @@ cBlockHandler::cBlockHandler(BLOCKTYPE a_BlockType) +bool cBlockHandler::GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta +) +{ + // By default, all blocks can be placed and the meta is copied over from the item's damage value: + a_BlockType = m_BlockType; + a_BlockMeta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage & 0x0f); + return true; +} + + + + + void cBlockHandler::OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) { } @@ -215,7 +232,7 @@ void cBlockHandler::OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a -void cBlockHandler::OnPlacedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) +void cBlockHandler::OnPlacedByPlayer(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { } @@ -231,9 +248,9 @@ void cBlockHandler::OnDestroyedByPlayer(cWorld *a_World, cPlayer * a_Player, int -void cBlockHandler::OnPlaced(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) +void cBlockHandler::OnPlaced(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { - //Notify the neighbors + // Notify the neighbors NeighborChanged(a_World, a_BlockX - 1, a_BlockY, a_BlockZ); NeighborChanged(a_World, a_BlockX + 1, a_BlockY, a_BlockZ); NeighborChanged(a_World, a_BlockX, a_BlockY - 1, a_BlockZ); @@ -248,7 +265,7 @@ void cBlockHandler::OnPlaced(cWorld *a_World, int a_BlockX, int a_BlockY, int a_ void cBlockHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) { - //Notify the neighbors + // Notify the neighbors NeighborChanged(a_World, a_BlockX - 1, a_BlockY, a_BlockZ); NeighborChanged(a_World, a_BlockX + 1, a_BlockY, a_BlockZ); NeighborChanged(a_World, a_BlockX, a_BlockY - 1, a_BlockZ); @@ -286,18 +303,8 @@ void cBlockHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_BlockX, -void cBlockHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) -{ -} - - - - - -void cBlockHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) +void cBlockHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) { - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, a_BlockMeta); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); } diff --git a/source/Blocks/BlockHandler.h b/source/Blocks/BlockHandler.h index 1fb93e893..d2ef527da 100644 --- a/source/Blocks/BlockHandler.h +++ b/source/Blocks/BlockHandler.h @@ -21,18 +21,35 @@ class cBlockHandler public: cBlockHandler(BLOCKTYPE a_BlockType); - // Called when the block gets ticked either by a random tick or by a queued tick + /// Called when the block gets ticked either by a random tick or by a queued tick virtual void OnUpdate(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ); - /// Called by cBlockHandler::PlaceBlock after the player has placed a new block - virtual void OnPlacedByPlayer(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir); + /** Called before a block is placed into a world. + The handler should return true to allow placement, false to refuse. + Also, the handler should set a_BlockType and a_BlockMeta to correct values for the newly placed block. + Called by cItemHandler::GetPlacementBlockTypeMeta() if the item is a block + */ + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ); + + /// Called by cWorld::SetBlock() after the block has been set + virtual void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + + /// Called by cClientHandle::HandlePlaceBlock() after the player has placed a new block. Called after OnPlaced(). + virtual void OnPlacedByPlayer( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta + ); /// Called before the player has destroyed a block virtual void OnDestroyedByPlayer(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ); - /// Called when a new block was placed. Called before OnPlacedByPlayer - virtual void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir); - /// Called before a block gets destroyed / replaced with air virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ); @@ -46,11 +63,8 @@ public: virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ); /// Called if the user right clicks the block and the block is useable - virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ); + virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ); - /// This function handles the real block placement for the give block by a player and also calls OnPlacedByPlayer() - virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir); - /// Called when the item is mined to convert it into pickups. Pickups may specify multiple items. virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta); diff --git a/source/Blocks/BlockLadder.h b/source/Blocks/BlockLadder.h index 0b53c4aaf..5f0b09737 100644 --- a/source/Blocks/BlockLadder.h +++ b/source/Blocks/BlockLadder.h @@ -19,61 +19,70 @@ public: } - virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override { - if (!LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_Dir)) + if (!LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace)) { - a_Dir = FindSuitableDirection(a_World, a_BlockX, a_BlockY, a_BlockZ); + a_BlockFace = FindSuitableBlockFace(a_World, a_BlockX, a_BlockY, a_BlockZ); - if (a_Dir == BLOCK_FACE_BOTTOM) + if (a_BlockFace == BLOCK_FACE_BOTTOM) { - return; + return false; } } - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cLadder::DirectionToMetaData(a_Dir)); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); + a_BlockType = m_BlockType; + a_BlockMeta = cLadder::DirectionToMetaData(a_BlockFace); + return true; } + /// Finds a suitable Direction for the Ladder. Returns BLOCK_FACE_BOTTOM on failure - static char FindSuitableDirection(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) + static char FindSuitableBlockFace(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) { - for (int i = 2; i <= 5; i++) + for (int Face = 2; Face <= 5; Face++) { - if (LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, i)) + if (LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Face)) { - return i; + return Face; } } return BLOCK_FACE_BOTTOM; } - static bool LadderCanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) + static bool LadderCanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) { - if (a_Dir == BLOCK_FACE_BOTTOM || a_Dir == BLOCK_FACE_TOP ) + if ((a_BlockFace == BLOCK_FACE_BOTTOM) || (a_BlockFace == BLOCK_FACE_TOP)) { return false; } - AddDirection( a_BlockX, a_BlockY, a_BlockZ, a_Dir, true ); + AddFaceDirection( a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); - return g_BlockIsSolid[a_World->GetBlock( a_BlockX, a_BlockY, a_BlockZ)]; + return g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ)]; } - virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override + virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override { - if (LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_Dir)) + if (LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace)) + { return true; - return FindSuitableDirection(a_World, a_BlockX, a_BlockY, a_BlockZ) != BLOCK_FACE_BOTTOM; + } + return (FindSuitableBlockFace(a_World, a_BlockX, a_BlockY, a_BlockZ) != BLOCK_FACE_BOTTOM); } virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override { - char Dir = cLadder::MetaDataToDirection(a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ)); - return CanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Dir); + char BlockFace = cLadder::MetaDataToDirection(a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)); + return CanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, BlockFace); } diff --git a/source/Blocks/BlockLever.cpp b/source/Blocks/BlockLever.cpp index cf0255df5..a9ab1fbbb 100644 --- a/source/Blocks/BlockLever.cpp +++ b/source/Blocks/BlockLever.cpp @@ -19,30 +19,12 @@ cBlockLeverHandler::cBlockLeverHandler(BLOCKTYPE a_BlockType) -void cBlockLeverHandler::OnPlaced(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) +void cBlockLeverHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) { - // Noting needed yet -} - - - - - -void cBlockLeverHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) -{ - // Nothing needed yet -} - - - - - -void cBlockLeverHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) -{ - //Flip the ON bit on/off. Using XOR bitwise operation to turn it on/off. + // Flip the ON bit on/off. Using XOR bitwise operation to turn it on/off. NIBBLETYPE Meta = ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08) & 0x0f); a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta); - if(Meta & 0x08) + if (Meta & 0x08) { a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f); } @@ -58,17 +40,7 @@ void cBlockLeverHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, void cBlockLeverHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) { - OnUse(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ); -} - - - - - -void cBlockLeverHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) -{ - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cRedstoneSimulator::LeverDirectionToMetaData(a_Dir)); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); + OnUse(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NONE, 8, 8, 8); } diff --git a/source/Blocks/BlockLever.h b/source/Blocks/BlockLever.h index 7e4d15dda..d03443abd 100644 --- a/source/Blocks/BlockLever.h +++ b/source/Blocks/BlockLever.h @@ -2,6 +2,9 @@ #include "BlockHandler.h" #include "../World.h" +#include "../Simulator/RedstoneSimulator.h" + + @@ -10,11 +13,9 @@ class cBlockLeverHandler : { public: cBlockLeverHandler(BLOCKTYPE a_BlockType); - virtual void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) override; - virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override @@ -30,16 +31,31 @@ public: } - virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override; - + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + a_BlockType = m_BlockType; + a_BlockMeta = cRedstoneSimulator::LeverDirectionToMetaData(a_BlockFace); + return true; + } + virtual bool DoesAllowBlockOnTop(void) override { return false; } + virtual const char * GetStepSound(void) override { return "step.wood"; } } ; + + + + diff --git a/source/Blocks/BlockPiston.cpp b/source/Blocks/BlockPiston.cpp index 2e532b649..bcd1eb56c 100644 --- a/source/Blocks/BlockPiston.cpp +++ b/source/Blocks/BlockPiston.cpp @@ -33,14 +33,6 @@ cBlockPistonHandler::cBlockPistonHandler(BLOCKTYPE a_BlockType) -void cBlockPistonHandler::OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) -{ -} - - - - - void cBlockPistonHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) { char OldMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); @@ -60,11 +52,16 @@ void cBlockPistonHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_Bloc -void cBlockPistonHandler::PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) +bool cBlockPistonHandler::GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta +) { - - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cPiston::RotationPitchToMetaData(a_Player->GetRotation(), a_Player->GetPitch())); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); + a_BlockType = E_BLOCK_REDSTONE_REPEATER_OFF; + a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), a_Player->GetPitch()); + return true; } diff --git a/source/Blocks/BlockPiston.h b/source/Blocks/BlockPiston.h index ce217c2bf..5d9d5c2b7 100644 --- a/source/Blocks/BlockPiston.h +++ b/source/Blocks/BlockPiston.h @@ -1,15 +1,28 @@ + #pragma once + #include "BlockHandler.h" -class cBlockPistonHandler : public cBlockHandler + + + +class cBlockPistonHandler : + public cBlockHandler { public: cBlockPistonHandler(BLOCKTYPE a_BlockType); - virtual void OnPlaced(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) override; - virtual void OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; - - virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override; - -}; \ No newline at end of file + virtual void OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; + + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override; +} ; + + + + diff --git a/source/Blocks/BlockRail.h b/source/Blocks/BlockRail.h index 24947c0bc..733f92c8c 100644 --- a/source/Blocks/BlockRail.h +++ b/source/Blocks/BlockRail.h @@ -42,137 +42,144 @@ public: { } - virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override { - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ)); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); - NeighborChanged(a_World, a_BlockX - 1, a_BlockY + 1, a_BlockZ); - NeighborChanged(a_World, a_BlockX + 1, a_BlockY + 1, a_BlockZ); - NeighborChanged(a_World, a_BlockX, a_BlockY + 1, a_BlockZ - 1); - NeighborChanged(a_World, a_BlockX, a_BlockY + 1, a_BlockZ + 1); - NeighborChanged(a_World, a_BlockX - 1, a_BlockY - 1, a_BlockZ); - NeighborChanged(a_World, a_BlockX + 1, a_BlockY - 1, a_BlockZ); - NeighborChanged(a_World, a_BlockX, a_BlockY - 1, a_BlockZ - 1); - NeighborChanged(a_World, a_BlockX, a_BlockY - 1, a_BlockZ + 1); + a_BlockType = m_BlockType; + a_BlockMeta = FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ); + return true; } + virtual void OnNeighborChanged(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override { - char Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - if(IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ) && Meta != FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ)) + NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + if (IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ) && (Meta != FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ))) + { a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ)); + } } + virtual bool CanBeAt(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override { - if(!g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)]) + if (!g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)]) + { return false; - char Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - switch(Meta) + } + NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + switch (Meta) { case E_RAIL_ASCEND_EAST: { - if(!g_BlockIsSolid[a_World->GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ)]) + if (!g_BlockIsSolid[a_World->GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ)]) + { return false; + } break; } case E_RAIL_ASCEND_WEST: { - if(!g_BlockIsSolid[a_World->GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ)]) + if (!g_BlockIsSolid[a_World->GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ)]) + { return false; + } break; } case E_RAIL_ASCEND_NORTH: { - if(!g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1)]) + if (!g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1)]) + { return false; + } break; } case E_RAIL_ASCEND_SOUTH: { - if(!g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1)]) + if (!g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1)]) + { return false; + } break; } } return true; } - char FindMeta(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) + NIBBLETYPE FindMeta(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) { - char Meta = 0; + NIBBLETYPE Meta = 0; char RailsCnt = 0; bool Neighbors[8]; // 0 - EAST, 1 - WEST, 2 - NORTH, 3 - SOUTH, 4 - EAST UP, 5 - WEST UP, 6 - NORTH UP, 7 - SOUTH UP memset(Neighbors, false, sizeof(Neighbors)); - if(IsUnstable(a_World, a_BlockX + 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST, E_PURE_DOWN)) + Neighbors[0] = (IsUnstable(a_World, a_BlockX + 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST, E_PURE_DOWN)); + Neighbors[1] = (IsUnstable(a_World, a_BlockX - 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST, E_PURE_DOWN)); + Neighbors[2] = (IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_DOWN)); + Neighbors[3] = (IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_DOWN)); + Neighbors[4] = (IsUnstable(a_World, a_BlockX + 1, a_BlockY + 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_EAST, E_PURE_NONE)); + Neighbors[5] = (IsUnstable(a_World, a_BlockX - 1, a_BlockY + 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_WEST, E_PURE_NONE)); + Neighbors[6] = (IsUnstable(a_World, a_BlockX, a_BlockY + 1, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_NONE)); + Neighbors[7] = (IsUnstable(a_World, a_BlockX, a_BlockY + 1, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_NONE)); + if (IsUnstable(a_World, a_BlockX + 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_EAST)) Neighbors[0] = true; - if(IsUnstable(a_World, a_BlockX - 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST, E_PURE_DOWN)) + if (IsUnstable(a_World, a_BlockX - 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_WEST)) Neighbors[1] = true; - if(IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_DOWN)) + if (IsUnstable(a_World, a_BlockX, a_BlockY - 1, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_NORTH)) Neighbors[2] = true; - if(IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_DOWN)) + if (IsUnstable(a_World, a_BlockX, a_BlockY - 1, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_SOUTH)) Neighbors[3] = true; - if(IsUnstable(a_World, a_BlockX + 1, a_BlockY + 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_EAST, E_PURE_NONE)) - Neighbors[4] = true; - if(IsUnstable(a_World, a_BlockX - 1, a_BlockY + 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_WEST, E_PURE_NONE)) - Neighbors[5] = true; - if(IsUnstable(a_World, a_BlockX, a_BlockY + 1, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_NONE)) - Neighbors[6] = true; - if(IsUnstable(a_World, a_BlockX, a_BlockY + 1, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_NONE)) - Neighbors[7] = true; - if(IsUnstable(a_World, a_BlockX + 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_EAST)) - Neighbors[0] = true; - if(IsUnstable(a_World, a_BlockX - 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_WEST)) - Neighbors[1] = true; - if(IsUnstable(a_World, a_BlockX, a_BlockY - 1, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_NORTH)) - Neighbors[2] = true; - if(IsUnstable(a_World, a_BlockX, a_BlockY - 1, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_SOUTH)) - Neighbors[3] = true; - for(int i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) { - if(Neighbors[i]) + if (Neighbors[i]) { RailsCnt++; } } - if(RailsCnt == 1) + if (RailsCnt == 1) { - if(Neighbors[7]) Meta = E_RAIL_ASCEND_SOUTH; - else if(Neighbors[6]) Meta = E_RAIL_ASCEND_NORTH; - else if(Neighbors[5]) Meta = E_RAIL_ASCEND_WEST; - else if(Neighbors[4]) Meta = E_RAIL_ASCEND_EAST; - else if(Neighbors[0] || Neighbors[1]) Meta = E_RAIL_EAST_WEST; - else if(Neighbors[2] || Neighbors[3]) Meta = E_RAIL_NORTH_SOUTH; + if (Neighbors[7]) return E_RAIL_ASCEND_SOUTH; + else if (Neighbors[6]) return E_RAIL_ASCEND_NORTH; + else if (Neighbors[5]) return E_RAIL_ASCEND_WEST; + else if (Neighbors[4]) return E_RAIL_ASCEND_EAST; + else if (Neighbors[0] || Neighbors[1]) return E_RAIL_EAST_WEST; + else if (Neighbors[2] || Neighbors[3]) return E_RAIL_NORTH_SOUTH; + ASSERT(!"Weird neighbor count"); return Meta; } - for(int i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) { - if(Neighbors[i+4]) + if (Neighbors[i + 4]) { Neighbors[i] = true; } } - if(RailsCnt > 1) + if (RailsCnt > 1) { - if(Neighbors[3] && Neighbors[0]) Meta = E_RAIL_CURVED_SOUTH_EAST; - else if(Neighbors[3] && Neighbors[1]) Meta = E_RAIL_CURVED_SOUTH_WEST; - else if(Neighbors[2] && Neighbors[0]) Meta = E_RAIL_CURVED_NORTH_EAST; - else if(Neighbors[2] && Neighbors[1]) Meta = E_RAIL_CURVED_NORTH_WEST; - else if(Neighbors[7] && Neighbors[2]) Meta = E_RAIL_ASCEND_SOUTH; - else if(Neighbors[3] && Neighbors[6]) Meta = E_RAIL_ASCEND_NORTH; - else if(Neighbors[5] && Neighbors[0]) Meta = E_RAIL_ASCEND_WEST; - else if(Neighbors[4] && Neighbors[1]) Meta = E_RAIL_ASCEND_EAST; - else if(Neighbors[0] && Neighbors[1]) Meta = E_RAIL_EAST_WEST; - else if(Neighbors[2] && Neighbors[3]) Meta = E_RAIL_NORTH_SOUTH; + if (Neighbors[3] && Neighbors[0]) return E_RAIL_CURVED_SOUTH_EAST; + else if(Neighbors[3] && Neighbors[1]) return E_RAIL_CURVED_SOUTH_WEST; + else if(Neighbors[2] && Neighbors[0]) return E_RAIL_CURVED_NORTH_EAST; + else if(Neighbors[2] && Neighbors[1]) return E_RAIL_CURVED_NORTH_WEST; + else if(Neighbors[7] && Neighbors[2]) return E_RAIL_ASCEND_SOUTH; + else if(Neighbors[3] && Neighbors[6]) return E_RAIL_ASCEND_NORTH; + else if(Neighbors[5] && Neighbors[0]) return E_RAIL_ASCEND_WEST; + else if(Neighbors[4] && Neighbors[1]) return E_RAIL_ASCEND_EAST; + else if(Neighbors[0] && Neighbors[1]) return E_RAIL_EAST_WEST; + else if(Neighbors[2] && Neighbors[3]) return E_RAIL_NORTH_SOUTH; + ASSERT(!"Weird neighbor count"); } return Meta; } - bool IsUnstable(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) + + bool IsUnstable(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) { - if(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL) return false; - char Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - switch(Meta) + if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL) return false; + NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + switch (Meta) { case E_RAIL_NORTH_SOUTH: { @@ -238,15 +245,16 @@ public: return false; } - bool IsNotConnected(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, char a_Pure = 0) + + bool IsNotConnected(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Pure = 0) { - AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_Direction, false); - char Meta; - if(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL) + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false); + NIBBLETYPE Meta; + if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL) { - if((a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure != E_PURE_UPDOWN)) + if ((a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure != E_PURE_UPDOWN)) { - if((a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure == E_PURE_NONE)) + if ((a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure == E_PURE_NONE)) { return true; } @@ -264,46 +272,65 @@ public: { Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); } - switch(a_Direction) + + switch (a_BlockFace) { case BLOCK_FACE_NORTH: { - if(Meta == E_RAIL_NORTH_SOUTH || - Meta == E_RAIL_ASCEND_NORTH || - Meta == E_RAIL_ASCEND_SOUTH || - Meta == E_RAIL_CURVED_SOUTH_EAST || - Meta == E_RAIL_CURVED_SOUTH_WEST) - return false; + if ( + (Meta == E_RAIL_NORTH_SOUTH) || + (Meta == E_RAIL_ASCEND_NORTH) || + (Meta == E_RAIL_ASCEND_SOUTH) || + (Meta == E_RAIL_CURVED_SOUTH_EAST) || + (Meta == E_RAIL_CURVED_SOUTH_WEST) + ) + { + return false; + } break; } + case BLOCK_FACE_SOUTH: { - if(Meta == E_RAIL_NORTH_SOUTH || - Meta == E_RAIL_ASCEND_NORTH || - Meta == E_RAIL_ASCEND_SOUTH || - Meta == E_RAIL_CURVED_NORTH_EAST || - Meta == E_RAIL_CURVED_NORTH_WEST) - return false; + if ( + (Meta == E_RAIL_NORTH_SOUTH) || + (Meta == E_RAIL_ASCEND_NORTH) || + (Meta == E_RAIL_ASCEND_SOUTH) || + (Meta == E_RAIL_CURVED_NORTH_EAST) || + (Meta == E_RAIL_CURVED_NORTH_WEST) + ) + { + return false; + } break; } + case BLOCK_FACE_EAST: { - if(Meta == E_RAIL_EAST_WEST || - Meta == E_RAIL_ASCEND_EAST || - Meta == E_RAIL_ASCEND_WEST || - Meta == E_RAIL_CURVED_SOUTH_WEST || - Meta == E_RAIL_CURVED_NORTH_WEST) - return false; + if ( + (Meta == E_RAIL_EAST_WEST) || + (Meta == E_RAIL_ASCEND_EAST) || + (Meta == E_RAIL_ASCEND_WEST) || + (Meta == E_RAIL_CURVED_SOUTH_WEST) || + (Meta == E_RAIL_CURVED_NORTH_WEST) + ) + { + return false; + } break; } case BLOCK_FACE_WEST: { - if(Meta == E_RAIL_EAST_WEST || - Meta == E_RAIL_ASCEND_EAST || - Meta == E_RAIL_ASCEND_WEST || - Meta == E_RAIL_CURVED_SOUTH_EAST || - Meta == E_RAIL_CURVED_NORTH_EAST) - return false; + if ( + (Meta == E_RAIL_EAST_WEST) || + (Meta == E_RAIL_ASCEND_EAST) || + (Meta == E_RAIL_ASCEND_WEST) || + (Meta == E_RAIL_CURVED_SOUTH_EAST) || + (Meta == E_RAIL_CURVED_NORTH_EAST) + ) + { + return false; + } break; } } diff --git a/source/Blocks/BlockRedstone.cpp b/source/Blocks/BlockRedstone.cpp index 21a5e1c61..ec54169c0 100644 --- a/source/Blocks/BlockRedstone.cpp +++ b/source/Blocks/BlockRedstone.cpp @@ -18,15 +18,6 @@ cBlockRedstoneHandler::cBlockRedstoneHandler(BLOCKTYPE a_BlockType) -void cBlockRedstoneHandler::OnPlaced(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) -{ - // Nothing needed yet -} - - - - - void cBlockRedstoneHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) { // Nothing needed yet @@ -35,22 +26,3 @@ void cBlockRedstoneHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_Blo - -void cBlockRedstoneHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) -{ - switch(m_BlockType) - { - case E_BLOCK_REDSTONE_TORCH_ON: - case E_BLOCK_REDSTONE_TORCH_OFF: - { - a_BlockMeta = cTorch::DirectionToMetaData(a_Dir); - break; - } - } - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, a_BlockMeta); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); -} - - - - diff --git a/source/Blocks/BlockRedstone.h b/source/Blocks/BlockRedstone.h index 85c993329..ce0ff64d5 100644 --- a/source/Blocks/BlockRedstone.h +++ b/source/Blocks/BlockRedstone.h @@ -13,12 +13,9 @@ class cBlockRedstoneHandler : { public: cBlockRedstoneHandler(BLOCKTYPE a_BlockType); - virtual void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) override; + virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override; - - virtual bool DoesAllowBlockOnTop(void) override { return false; diff --git a/source/Blocks/BlockRedstoneRepeater.cpp b/source/Blocks/BlockRedstoneRepeater.cpp index 84a841fb0..15b736cbc 100644 --- a/source/Blocks/BlockRedstoneRepeater.cpp +++ b/source/Blocks/BlockRedstoneRepeater.cpp @@ -19,15 +19,6 @@ cBlockRedstoneRepeaterHandler::cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockTy -void cBlockRedstoneRepeaterHandler::OnPlaced(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) -{ - // Noting needed yet -} - - - - - void cBlockRedstoneRepeaterHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) { // Nothing needed yet @@ -37,7 +28,7 @@ void cBlockRedstoneRepeaterHandler::OnDestroyed(cWorld *a_World, int a_BlockX, i -void cBlockRedstoneRepeaterHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) +void cBlockRedstoneRepeaterHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) { a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) + 0x04) & 0x0f)); } @@ -48,17 +39,7 @@ void cBlockRedstoneRepeaterHandler::OnUse(cWorld *a_World, cPlayer *a_Player, in void cBlockRedstoneRepeaterHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) { - OnUse(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ); -} - - - - - -void cBlockRedstoneRepeaterHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) -{ - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cRedstoneSimulator::RepeaterRotationToMetaData(a_Player->GetRotation())); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); + OnUse(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NONE, 8, 8, 8); } diff --git a/source/Blocks/BlockRedstoneRepeater.h b/source/Blocks/BlockRedstoneRepeater.h index 8beb4b94a..fbd415160 100644 --- a/source/Blocks/BlockRedstoneRepeater.h +++ b/source/Blocks/BlockRedstoneRepeater.h @@ -13,11 +13,10 @@ class cBlockRedstoneRepeaterHandler : { public: cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType); - virtual void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, int a_Dir) override; virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override @@ -33,9 +32,6 @@ public: } - virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override; - - virtual bool DoesAllowBlockOnTop(void) override { return false; diff --git a/source/Blocks/BlockSign.h b/source/Blocks/BlockSign.h index b6e773afb..23645d0d2 100644 --- a/source/Blocks/BlockSign.h +++ b/source/Blocks/BlockSign.h @@ -20,26 +20,6 @@ public: } - virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override - { - BLOCKTYPE Block; - NIBBLETYPE Meta; - if (a_Dir == BLOCK_FACE_TOP) - { - 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_BlockX, a_BlockY, a_BlockZ, Block, Meta); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); - } - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { a_Pickups.push_back(cItem(E_ITEM_SIGN, 1, 0)); diff --git a/source/Blocks/BlockSlab.h b/source/Blocks/BlockSlab.h index 45488480c..2abcc6364 100644 --- a/source/Blocks/BlockSlab.h +++ b/source/Blocks/BlockSlab.h @@ -24,24 +24,41 @@ public: } - virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override { - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, DirectionToMetaData( a_Dir, a_BlockMeta )); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); + a_BlockType = m_BlockType; + NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage & 0x07); + switch (a_BlockFace) + { + case BLOCK_FACE_TOP: a_BlockMeta = Meta & 0x7; break; // Always bottom half of the slab when placing on top of something + case BLOCK_FACE_BOTTOM: a_BlockMeta = Meta | 0x8; break; // Always top half of the slab when placing on bottom of something + case BLOCK_FACE_EAST: + case BLOCK_FACE_NORTH: + case BLOCK_FACE_SOUTH: + case BLOCK_FACE_WEST: + { + if (a_CursorY > 7) + { + // Cursor at the top half of the face, place a top half of slab + a_BlockMeta = Meta | 0x8; + } + else + { + // Cursor at the bottom half of the face, place a bottom half of slab: + a_BlockMeta = Meta & 0x7; + } + break; + } + } // switch (a_BlockFace) + return true; } - static char DirectionToMetaData( char a_Direction, NIBBLETYPE Meta ) - { - char result = Meta; - if( a_Direction == 0) - { - result |= 0x8; - } - return result; - } - - virtual const char * GetStepSound(void) override { return ((m_BlockType == E_BLOCK_WOODEN_SLAB) || (m_BlockType == E_BLOCK_DOUBLE_WOODEN_SLAB)) ? "step.wood" : "step.stone"; diff --git a/source/Blocks/BlockStairs.h b/source/Blocks/BlockStairs.h index 71df6f00e..6fcbc2cba 100644 --- a/source/Blocks/BlockStairs.h +++ b/source/Blocks/BlockStairs.h @@ -1,22 +1,56 @@ + #pragma once + #include "BlockHandler.h" #include "../Stairs.h" -class cBlockStairsHandler : public cBlockHandler + + + + +class cBlockStairsHandler : + public cBlockHandler { public: - cBlockStairsHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + cBlockStairsHandler(BLOCKTYPE a_BlockType) : + cBlockHandler(a_BlockType) { } - virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override { - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cStairs::RotationToMetaData(a_Player->GetRotation(), a_Dir)); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); + a_BlockType = m_BlockType; + a_BlockMeta = cStairs::RotationToMetaData(a_Player->GetRotation()); + switch (a_BlockFace) + { + case BLOCK_FACE_TOP: break; + case BLOCK_FACE_BOTTOM: a_BlockMeta = a_BlockMeta | 0x4; break; // When placing onto a bottom face, always place an upside-down stairs block + case BLOCK_FACE_EAST: + case BLOCK_FACE_NORTH: + case BLOCK_FACE_SOUTH: + case BLOCK_FACE_WEST: + { + // When placing onto a sideways face, check cursor, if in top half, make it an upside-down stairs block + if (a_CursorY < 8) + { + a_BlockMeta |= 0x4; + } + break; + } + } + return true; } - //TODO: step sound -}; + // TODO: step sound +} ; + + + + diff --git a/source/Blocks/BlockTorch.h b/source/Blocks/BlockTorch.h index e34bbdd18..43c5cdb4c 100644 --- a/source/Blocks/BlockTorch.h +++ b/source/Blocks/BlockTorch.h @@ -19,23 +19,29 @@ public: } - virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override { - if (!TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_Dir)) + // Find proper placement. Use the player-supplied one as the default, but fix if not okay: + if (!TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace)) { - a_Dir = FindSuitableDirection(a_World, a_BlockX, a_BlockY, a_BlockZ); + a_BlockFace = FindSuitableFace(a_World, a_BlockX, a_BlockY, a_BlockZ); - if (a_Dir == BLOCK_FACE_BOTTOM) + if (a_BlockFace == BLOCK_FACE_BOTTOM) { - return; + return false; } } - - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cTorch::DirectionToMetaData(a_Dir)); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); + a_BlockType = m_BlockType; + a_BlockMeta = cTorch::DirectionToMetaData(a_BlockFace); + return true; } - + virtual bool DoesAllowBlockOnTop(void) override { return false; @@ -61,25 +67,25 @@ public: } - static bool TorchCanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) + static bool TorchCanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) { // TODO: If placing a torch from below, check all 4 XZ neighbors, place it on that neighbor instead // How to propagate that change up? // Simon: The easiest way is to calculate the position two times, shouldn´t cost much cpu power :) - if (a_Dir == BLOCK_FACE_BOTTOM) + if (a_BlockFace == BLOCK_FACE_BOTTOM) { return false; } - AddDirection( a_BlockX, a_BlockY, a_BlockZ, a_Dir, true ); + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); - return CanBePlacedOn(a_World->GetBlock( a_BlockX, a_BlockY, a_BlockZ ), a_Dir); + return CanBePlacedOn(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ), a_BlockFace); } - /// Finds a suitable Direction for the Torch. Returns BLOCK_FACE_BOTTOM on failure - static char FindSuitableDirection(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) + /// Finds a suitable Face for the Torch. Returns BLOCK_FACE_BOTTOM on failure + static char FindSuitableFace(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) { for (int i = 1; i <= 5; i++) { @@ -92,19 +98,21 @@ public: } - virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override + virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override { - if(TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_Dir)) + if (TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace)) + { return true; + } - return FindSuitableDirection(a_World, a_BlockX, a_BlockY, a_BlockZ) != BLOCK_FACE_BOTTOM; + return (FindSuitableFace(a_World, a_BlockX, a_BlockY, a_BlockZ) != BLOCK_FACE_BOTTOM); } virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override { - char Dir = cTorch::MetaDataToDirection(a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ)); - return TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Dir); + char Face = cTorch::MetaDataToDirection(a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)); + return TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Face); } diff --git a/source/Blocks/BlockVine.h b/source/Blocks/BlockVine.h index 791b01a79..2f35c11d9 100644 --- a/source/Blocks/BlockVine.h +++ b/source/Blocks/BlockVine.h @@ -18,18 +18,24 @@ public: } - virtual void PlaceBlock(cWorld * a_World, cPlayer * a_Player, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override { - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, cVine::DirectionToMetaData(a_Dir)); - OnPlacedByPlayer(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ, a_Dir); + a_BlockType = m_BlockType; + a_BlockMeta = cVine::DirectionToMetaData(a_BlockFace); + return true; } - virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override + virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override { if ( (a_World->GetBlock( a_BlockX, a_BlockY + 1, a_BlockZ ) == E_BLOCK_VINES) && - (cVine::MetaDataToDirection(a_World->GetBlockMeta( a_BlockX, a_BlockY + 1, a_BlockZ )) == a_Dir) + (cVine::MetaDataToDirection(a_World->GetBlockMeta(a_BlockX, a_BlockY + 1, a_BlockZ)) == a_BlockFace) ) { return true; @@ -38,18 +44,18 @@ public: BLOCKTYPE TopBlock = a_World->GetBlock( a_BlockX, a_BlockY + 1, a_BlockZ); if (g_BlockIsSolid[TopBlock] || (TopBlock == E_BLOCK_LEAVES)) { - AddDirection( a_BlockX, a_BlockY, a_BlockZ, a_Dir, true ); - BLOCKTYPE BaseBlock = a_World->GetBlock( a_BlockX, a_BlockY, a_BlockZ); + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); + BLOCKTYPE BaseBlock = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); if (!g_BlockIsSolid[BaseBlock] && (BaseBlock != E_BLOCK_LEAVES)) { - AddDirection( a_BlockX, a_BlockY, a_BlockZ, a_Dir, false ); - a_World->SetBlock( a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_VINES, 0); + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false); + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_VINES, 0); } return true; } - AddDirection( a_BlockX, a_BlockY, a_BlockZ, a_Dir, true ); - BLOCKTYPE BaseBlock = a_World->GetBlock( a_BlockX, a_BlockY, a_BlockZ); + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); + BLOCKTYPE BaseBlock = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); return (g_BlockIsSolid[BaseBlock] || (BaseBlock == E_BLOCK_LEAVES)); } diff --git a/source/Blocks/BlockWorkbench.h b/source/Blocks/BlockWorkbench.h index c5102326e..ccd1ded9a 100644 --- a/source/Blocks/BlockWorkbench.h +++ b/source/Blocks/BlockWorkbench.h @@ -19,7 +19,7 @@ public: } - virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { cWindow * Window = new cCraftingWindow(a_BlockX, a_BlockY, a_BlockZ); a_Player->OpenWindow(Window); -- cgit v1.2.3