summaryrefslogtreecommitdiffstats
path: root/source/Blocks
diff options
context:
space:
mode:
Diffstat (limited to 'source/Blocks')
-rw-r--r--source/Blocks/BlockBed.cpp2
-rw-r--r--source/Blocks/BlockBed.h6
-rw-r--r--source/Blocks/BlockCactus.h6
-rw-r--r--source/Blocks/BlockCrops.h6
-rw-r--r--source/Blocks/BlockDeadBush.h12
-rw-r--r--source/Blocks/BlockDoor.cpp7
-rw-r--r--source/Blocks/BlockDoor.h86
-rw-r--r--source/Blocks/BlockFenceGate.h34
-rw-r--r--source/Blocks/BlockFlower.h12
-rw-r--r--source/Blocks/BlockHandler.cpp23
-rw-r--r--source/Blocks/BlockHandler.h8
-rw-r--r--source/Blocks/BlockLever.h6
-rw-r--r--source/Blocks/BlockMushroom.h12
-rw-r--r--source/Blocks/BlockMycelium.h5
-rw-r--r--source/Blocks/BlockPumpkin.h60
-rw-r--r--source/Blocks/BlockRedstone.h11
-rw-r--r--source/Blocks/BlockRedstoneRepeater.h12
-rw-r--r--source/Blocks/BlockSapling.h12
-rw-r--r--source/Blocks/BlockSign.h6
-rw-r--r--source/Blocks/BlockSugarcane.h6
-rw-r--r--source/Blocks/BlockTorch.h103
21 files changed, 254 insertions, 181 deletions
diff --git a/source/Blocks/BlockBed.cpp b/source/Blocks/BlockBed.cpp
index f5e9db88d..66eb9130c 100644
--- a/source/Blocks/BlockBed.cpp
+++ b/source/Blocks/BlockBed.cpp
@@ -56,7 +56,7 @@ void cBlockBedHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, i
if (a_World->GetDimension() != dimOverworld)
{
Vector3i Coords(a_BlockX, a_BlockY, a_BlockZ);
- a_World->DoExplosiontAt(5, a_BlockX, a_BlockY, a_BlockZ, true, esBed, &Coords);
+ a_World->DoExplosionAt(5, a_BlockX, a_BlockY, a_BlockZ, true, esBed, &Coords);
}
else
{
diff --git a/source/Blocks/BlockBed.h b/source/Blocks/BlockBed.h
index 0bf1cfc0f..8a289b22c 100644
--- a/source/Blocks/BlockBed.h
+++ b/source/Blocks/BlockBed.h
@@ -37,12 +37,6 @@ public:
}
- virtual bool DoesAllowBlockOnTop() override
- {
- return false;
- }
-
-
// Bed specific helper functions
static NIBBLETYPE RotationToMetaData(double a_Rotation)
{
diff --git a/source/Blocks/BlockCactus.h b/source/Blocks/BlockCactus.h
index 1d123bc0a..4147ad473 100644
--- a/source/Blocks/BlockCactus.h
+++ b/source/Blocks/BlockCactus.h
@@ -63,12 +63,6 @@ public:
return true;
}
-
-
- virtual bool CanBePlacedOnSide(void) override
- {
- return false;
- }
void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
diff --git a/source/Blocks/BlockCrops.h b/source/Blocks/BlockCrops.h
index 4bc76fd50..9e19b14ec 100644
--- a/source/Blocks/BlockCrops.h
+++ b/source/Blocks/BlockCrops.h
@@ -20,12 +20,6 @@ public:
}
- virtual bool DoesAllowBlockOnTop() override
- {
- return false;
- }
-
-
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_Meta) override
{
MTRand rand;
diff --git a/source/Blocks/BlockDeadBush.h b/source/Blocks/BlockDeadBush.h
index 379e8e5df..14617d006 100644
--- a/source/Blocks/BlockDeadBush.h
+++ b/source/Blocks/BlockDeadBush.h
@@ -28,18 +28,6 @@ public:
{
return (a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_SAND);
}
-
-
- virtual bool DoesAllowBlockOnTop(void) override
- {
- return false;
- }
-
-
- virtual bool CanBePlacedOnSide() override
- {
- return false;
- }
} ;
diff --git a/source/Blocks/BlockDoor.cpp b/source/Blocks/BlockDoor.cpp
index 02cbd28e2..e71ccd368 100644
--- a/source/Blocks/BlockDoor.cpp
+++ b/source/Blocks/BlockDoor.cpp
@@ -3,7 +3,6 @@
#include "BlockDoor.h"
#include "../Item.h"
#include "../World.h"
-#include "../Doors.h"
#include "../Entities/Player.h"
@@ -26,7 +25,7 @@ void cBlockDoorHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY
if (OldMeta & 8)
{
// Was upper part of door
- if (cDoors::IsDoor(a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)))
+ if (IsDoor(a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)))
{
a_World->FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
}
@@ -34,7 +33,7 @@ void cBlockDoorHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY
else
{
// Was lower part
- if (cDoors::IsDoor(a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)))
+ if (IsDoor(a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)))
{
a_World->FastSetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, E_BLOCK_AIR, 0);
}
@@ -49,7 +48,7 @@ void cBlockDoorHandler::OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX
{
if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_WOODEN_DOOR)
{
- cDoors::ChangeDoor(a_World, a_BlockX, a_BlockY, a_BlockZ);
+ ChangeDoor(a_World, a_BlockX, a_BlockY, a_BlockZ);
}
}
diff --git a/source/Blocks/BlockDoor.h b/source/Blocks/BlockDoor.h
index 4978fee38..03a79d47d 100644
--- a/source/Blocks/BlockDoor.h
+++ b/source/Blocks/BlockDoor.h
@@ -3,7 +3,6 @@
#include "BlockHandler.h"
#include "../World.h"
-#include "../Doors.h"
#include "../Entities/Player.h"
@@ -43,7 +42,7 @@ public:
}
a_BlockType = m_BlockType;
- a_BlockMeta = cDoors::RotationToMetaData(a_Player->GetRotation());
+ a_BlockMeta = PlayerYawToMetaData(a_Player->GetRotation());
return true;
}
@@ -68,12 +67,6 @@ public:
}
- virtual bool CanBePlacedOnSide(void) override
- {
- return false;
- }
-
-
virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR));
@@ -98,6 +91,83 @@ public:
}
return false;
}
+
+
+ /// Converts the player's yaw to placed door's blockmeta
+ inline static NIBBLETYPE PlayerYawToMetaData(double a_Yaw)
+ {
+ ASSERT((a_Yaw >= -180) && (a_Yaw < 180));
+
+ a_Yaw += 90 + 45;
+ if (a_Yaw > 360)
+ {
+ a_Yaw -= 360;
+ }
+ if ((a_Yaw >= 0) && (a_Yaw < 90))
+ {
+ return 0x0;
+ }
+ else if ((a_Yaw >= 180) && (a_Yaw < 270))
+ {
+ return 0x2;
+ }
+ else if ((a_Yaw >= 90) && (a_Yaw < 180))
+ {
+ return 0x1;
+ }
+ else
+ {
+ return 0x3;
+ }
+ }
+
+
+ /// Returns true if the specified blocktype is any kind of door
+ inline static bool IsDoor(BLOCKTYPE a_Block)
+ {
+ return (a_Block == E_BLOCK_WOODEN_DOOR) || (a_Block == E_BLOCK_IRON_DOOR);
+ }
+
+
+ /// Returns the metadata for the opposite door state (open vs closed)
+ static NIBBLETYPE ChangeStateMetaData(NIBBLETYPE a_MetaData)
+ {
+ return a_MetaData ^ 4;
+ }
+
+
+ /// Changes the door at the specified coords from open to close or vice versa
+ static void ChangeDoor(cWorld * a_World, int a_X, int a_Y, int a_Z)
+ {
+ NIBBLETYPE OldMetaData = a_World->GetBlockMeta(a_X, a_Y, a_Z);
+
+ a_World->SetBlockMeta(a_X, a_Y, a_Z, ChangeStateMetaData(OldMetaData));
+
+ if (OldMetaData & 8)
+ {
+ // Current block is top of the door
+ BLOCKTYPE BottomBlock = a_World->GetBlock(a_X, a_Y - 1, a_Z);
+ NIBBLETYPE BottomMeta = a_World->GetBlockMeta(a_X, a_Y - 1, a_Z);
+
+ if (IsDoor(BottomBlock) && !(BottomMeta & 8))
+ {
+ a_World->SetBlockMeta(a_X, a_Y - 1, a_Z, ChangeStateMetaData(BottomMeta));
+ }
+ }
+ else
+ {
+ // Current block is bottom of the door
+ BLOCKTYPE TopBlock = a_World->GetBlock(a_X, a_Y + 1, a_Z);
+ NIBBLETYPE TopMeta = a_World->GetBlockMeta(a_X, a_Y + 1, a_Z);
+
+ if (IsDoor(TopBlock) && (TopMeta & 8))
+ {
+ a_World->SetBlockMeta(a_X, a_Y + 1, a_Z, ChangeStateMetaData(TopMeta));
+ }
+ }
+ }
+
+
} ;
diff --git a/source/Blocks/BlockFenceGate.h b/source/Blocks/BlockFenceGate.h
index d6f8aa85f..6423a7cb0 100644
--- a/source/Blocks/BlockFenceGate.h
+++ b/source/Blocks/BlockFenceGate.h
@@ -2,7 +2,6 @@
#pragma once
#include "BlockHandler.h"
-#include "../Doors.h"
@@ -26,7 +25,7 @@ public:
) override
{
a_BlockType = m_BlockType;
- a_BlockMeta = cDoors::RotationToMetaData(a_Player->GetRotation() + 270);
+ a_BlockMeta = PlayerYawToMetaData(a_Player->GetRotation());
return true;
}
@@ -34,7 +33,7 @@ public:
virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
{
NIBBLETYPE OldMetaData = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
- NIBBLETYPE NewMetaData = cDoors::RotationToMetaData(a_Player->GetRotation() + 270);
+ NIBBLETYPE NewMetaData = PlayerYawToMetaData(a_Player->GetRotation());
OldMetaData ^= 4; // Toggle the gate
if ((OldMetaData & 1) == (NewMetaData & 1))
{
@@ -53,6 +52,35 @@ public:
{
return true;
}
+
+
+ /// Converts the player's yaw to placed gate's blockmeta
+ inline static NIBBLETYPE PlayerYawToMetaData(double a_Yaw)
+ {
+ ASSERT((a_Yaw >= -180) && (a_Yaw < 180));
+
+ a_Yaw += 360 + 45;
+ if (a_Yaw > 360)
+ {
+ a_Yaw -= 360;
+ }
+ if ((a_Yaw >= 0) && (a_Yaw < 90))
+ {
+ return 0x0;
+ }
+ else if ((a_Yaw >= 180) && (a_Yaw < 270))
+ {
+ return 0x2;
+ }
+ else if ((a_Yaw >= 90) && (a_Yaw < 180))
+ {
+ return 0x1;
+ }
+ else
+ {
+ return 0x3;
+ }
+ }
} ;
diff --git a/source/Blocks/BlockFlower.h b/source/Blocks/BlockFlower.h
index 952901ba5..421e2d5d8 100644
--- a/source/Blocks/BlockFlower.h
+++ b/source/Blocks/BlockFlower.h
@@ -30,18 +30,6 @@ public:
}
- virtual bool DoesAllowBlockOnTop(void) override
- {
- return true;
- }
-
-
- virtual bool CanBePlacedOnSide(void) override
- {
- return false;
- }
-
-
virtual const char * GetStepSound(void) override
{
return "step.grass";
diff --git a/source/Blocks/BlockHandler.cpp b/source/Blocks/BlockHandler.cpp
index 2627ac6b4..3e97d1e9d 100644
--- a/source/Blocks/BlockHandler.cpp
+++ b/source/Blocks/BlockHandler.cpp
@@ -41,6 +41,7 @@
#include "BlockNote.h"
#include "BlockOre.h"
#include "BlockPiston.h"
+#include "BlockPumpkin.h"
#include "BlockRail.h"
#include "BlockRedstone.h"
#include "BlockRedstoneRepeater.h"
@@ -153,8 +154,10 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_PISTON: return new cBlockPistonHandler (a_BlockType);
case E_BLOCK_PISTON_EXTENSION: return new cBlockPistonHeadHandler ();
case E_BLOCK_PLANKS: return new cBlockWoodHandler (a_BlockType);
+ case E_BLOCK_PUMPKIN: return new cBlockPumpkinHandler (a_BlockType);
+ case E_BLOCK_JACK_O_LANTERN: return new cBlockPumpkinHandler (a_BlockType);
case E_BLOCK_PUMPKIN_STEM: return new cBlockStemsHandler (a_BlockType);
- case E_BLOCK_QUARTZ_STAIR: return new cBlockStairsHandler (a_BlockType);
+ case E_BLOCK_QUARTZ_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_RAIL: return new cBlockRailHandler (a_BlockType);
case E_BLOCK_POTATOES: return new cBlockCropsHandler (a_BlockType);
case E_BLOCK_POWERED_RAIL: return new cBlockRailHandler (a_BlockType);
@@ -412,24 +415,6 @@ bool cBlockHandler::DoesIgnoreBuildCollision(void)
-bool cBlockHandler::DoesAllowBlockOnTop(void)
-{
- return true;
-}
-
-
-
-
-
-bool cBlockHandler::CanBePlacedOnSide(void)
-{
- return true;
-}
-
-
-
-
-
bool cBlockHandler::DoesDropOnUnsuitable(void)
{
return true;
diff --git a/source/Blocks/BlockHandler.h b/source/Blocks/BlockHandler.h
index 228ce174b..0487505ee 100644
--- a/source/Blocks/BlockHandler.h
+++ b/source/Blocks/BlockHandler.h
@@ -83,10 +83,7 @@ public:
NOTE: This call doesn't actually place the block
*/
// virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir);
-
- /// Called when the player tries to place a block on top of this block (Only if he aims directly on this block); return false to disallow
- virtual bool DoesAllowBlockOnTop(void);
-
+
/// Called to check whether this block supports a rclk action. If it returns true, OnUse() is called
virtual bool IsUseable(void);
@@ -99,9 +96,6 @@ public:
For example blocks placed "on" snow will be placed at the same position. So: Snow ignores Build collision
*/
virtual bool DoesIgnoreBuildCollision(void);
-
- /// Indicates this block can be placed on the side of other blocks. Default: true
- virtual bool CanBePlacedOnSide(void);
/// Does this block drop if it gets destroyed by an unsuitable situation? Default: true
virtual bool DoesDropOnUnsuitable(void);
diff --git a/source/Blocks/BlockLever.h b/source/Blocks/BlockLever.h
index 362cf563e..ddf48297c 100644
--- a/source/Blocks/BlockLever.h
+++ b/source/Blocks/BlockLever.h
@@ -42,12 +42,6 @@ public:
a_BlockMeta = cRedstoneSimulator::LeverDirectionToMetaData(a_BlockFace);
return true;
}
-
-
- virtual bool DoesAllowBlockOnTop(void) override
- {
- return false;
- }
virtual const char * GetStepSound(void) override
diff --git a/source/Blocks/BlockMushroom.h b/source/Blocks/BlockMushroom.h
index b3b23e2ba..2846a6317 100644
--- a/source/Blocks/BlockMushroom.h
+++ b/source/Blocks/BlockMushroom.h
@@ -46,18 +46,6 @@ public:
}
return true;
}
-
-
- virtual bool DoesAllowBlockOnTop(void) override
- {
- return false;
- }
-
-
- virtual bool CanBePlacedOnSide(void) override
- {
- return false;
- }
virtual const char * GetStepSound(void) override
diff --git a/source/Blocks/BlockMycelium.h b/source/Blocks/BlockMycelium.h
index 0ed7162ac..7f897c72a 100644
--- a/source/Blocks/BlockMycelium.h
+++ b/source/Blocks/BlockMycelium.h
@@ -20,6 +20,11 @@ public:
{
a_Pickups.push_back(cItem(E_BLOCK_DIRT, 1, 0));
}
+
+ virtual const char * GetStepSound(void) override
+ {
+ return "step.gravel";
+ }
} ;
diff --git a/source/Blocks/BlockPumpkin.h b/source/Blocks/BlockPumpkin.h
new file mode 100644
index 000000000..76abc6818
--- /dev/null
+++ b/source/Blocks/BlockPumpkin.h
@@ -0,0 +1,60 @@
+#pragma once
+
+#include "BlockHandler.h"
+
+
+
+
+class cBlockPumpkinHandler :
+ public cBlockHandler
+{
+public:
+ cBlockPumpkinHandler(BLOCKTYPE a_BlockType)
+ : cBlockHandler(a_BlockType)
+ {
+ }
+
+ virtual bool GetPlacementBlockTypeMeta(
+ cWorld * a_World, cPlayer * a_Player,
+ int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ int a_CursorX, int a_CursorY, int a_CursorZ,
+ BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
+ ) override
+ {
+ a_BlockType = m_BlockType;
+ a_BlockMeta = PlayerYawToMetaData(a_Player->GetRotation());
+ return true;
+ }
+
+ inline static NIBBLETYPE PlayerYawToMetaData(double a_Yaw)
+ {
+ ASSERT((a_Yaw >= -180) && (a_Yaw < 180));
+
+ a_Yaw += 180 + 45;
+ if (a_Yaw > 360)
+ {
+ a_Yaw -= 360;
+ }
+ if ((a_Yaw >= 0) && (a_Yaw < 90))
+ {
+ return 0x0;
+ }
+ else if ((a_Yaw >= 180) && (a_Yaw < 270))
+ {
+ return 0x2;
+ }
+ else if ((a_Yaw >= 90) && (a_Yaw < 180))
+ {
+ return 0x1;
+ }
+ else
+ {
+ return 0x3;
+ }
+ }
+
+} ;
+
+
+
+
diff --git a/source/Blocks/BlockRedstone.h b/source/Blocks/BlockRedstone.h
index ae0466937..f28f3f2d6 100644
--- a/source/Blocks/BlockRedstone.h
+++ b/source/Blocks/BlockRedstone.h
@@ -16,11 +16,6 @@ public:
virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override;
- virtual bool DoesAllowBlockOnTop(void) override
- {
- return false;
- }
-
virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
@@ -33,12 +28,6 @@ public:
// Reset meta to 0
a_Pickups.push_back(cItem(E_ITEM_REDSTONE_DUST, 1));
}
-
-
- virtual bool CanBePlacedOnSide(void) override
- {
- return false;
- }
} ;
diff --git a/source/Blocks/BlockRedstoneRepeater.h b/source/Blocks/BlockRedstoneRepeater.h
index f3e250963..24250ab86 100644
--- a/source/Blocks/BlockRedstoneRepeater.h
+++ b/source/Blocks/BlockRedstoneRepeater.h
@@ -32,23 +32,11 @@ public:
}
- virtual bool DoesAllowBlockOnTop(void) override
- {
- return false;
- }
-
-
virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR));
}
-
- virtual bool CanBePlacedOnSide(void) override
- {
- return false;
- }
-
virtual const char * GetStepSound(void) override
{
return "step.wood";
diff --git a/source/Blocks/BlockSapling.h b/source/Blocks/BlockSapling.h
index 17ef4984f..fff2fa88b 100644
--- a/source/Blocks/BlockSapling.h
+++ b/source/Blocks/BlockSapling.h
@@ -29,12 +29,6 @@ public:
{
return (a_RelY > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ));
}
-
-
- virtual bool DoesAllowBlockOnTop(void) override
- {
- return false;
- }
void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
@@ -50,12 +44,6 @@ public:
a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x08);
}
}
-
-
- virtual bool CanBePlacedOnSide() override
- {
- return false;
- }
virtual const char * GetStepSound(void) override
diff --git a/source/Blocks/BlockSign.h b/source/Blocks/BlockSign.h
index e6426180f..7fbe61893 100644
--- a/source/Blocks/BlockSign.h
+++ b/source/Blocks/BlockSign.h
@@ -23,12 +23,6 @@ public:
{
a_Pickups.push_back(cItem(E_ITEM_SIGN, 1, 0));
}
-
-
- virtual bool DoesAllowBlockOnTop(void) override
- {
- return false;
- }
virtual const char * GetStepSound(void) override
diff --git a/source/Blocks/BlockSugarcane.h b/source/Blocks/BlockSugarcane.h
index 9d66d6be6..28a60df80 100644
--- a/source/Blocks/BlockSugarcane.h
+++ b/source/Blocks/BlockSugarcane.h
@@ -77,12 +77,6 @@ public:
{
a_World->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, 1);
}
-
-
- virtual bool CanBePlacedOnSide() override
- {
- return false;
- }
virtual const char * GetStepSound(void) override
diff --git a/source/Blocks/BlockTorch.h b/source/Blocks/BlockTorch.h
index 3a50cab77..b9e0dbf27 100644
--- a/source/Blocks/BlockTorch.h
+++ b/source/Blocks/BlockTorch.h
@@ -24,16 +24,31 @@ public:
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
- // Find proper placement. Use the player-supplied one as the default, but fix if not okay:
- if (!TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace))
+ // Find proper placement of torch
+
+ if ((a_BlockFace == BLOCK_FACE_TOP) || (a_BlockFace == BLOCK_FACE_BOTTOM))
{
- a_BlockFace = FindSuitableFace(a_World, a_BlockX, a_BlockY, a_BlockZ);
-
- if (a_BlockFace == BLOCK_FACE_BOTTOM)
+ a_BlockFace = FindSuitableFace(a_World, a_BlockX, a_BlockY, a_BlockZ); // Top or bottom faces clicked, find a suitable face
+ if (a_BlockFace == BLOCK_FACE_NONE)
{
+ // Client wouldn't have sent anything anyway, but whatever
return false;
}
}
+ else
+ {
+ // Not top or bottom faces, try to preserve whatever face was clicked
+ if (!TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace))
+ {
+ // Torch couldn't be placed on whatever face was clicked, last ditch resort - find another face
+ a_BlockFace = FindSuitableFace(a_World, a_BlockX, a_BlockY, a_BlockZ);
+ if (a_BlockFace == BLOCK_FACE_NONE)
+ {
+ return false;
+ }
+ }
+ }
+
a_BlockType = m_BlockType;
a_BlockMeta = DirectionToMetaData(a_BlockFace);
return true;
@@ -100,51 +115,58 @@ public:
}
- virtual bool DoesAllowBlockOnTop(void) override
- {
- return true;
- }
-
-
- static bool CanBePlacedOn(BLOCKTYPE a_BlockType, char a_Direction)
+ static bool CanBePlacedOn(BLOCKTYPE a_BlockType, char a_BlockFace)
{
- if ( g_BlockIsSolid[a_BlockType] ) {
- return (a_Direction == 0x1); // allow only direction "standing on floor"
+ if ( !g_BlockIsTorchPlaceable[a_BlockType] )
+ {
+ return (a_BlockFace == BLOCK_FACE_TOP); // Allow placement only when torch upright
}
- else {
- return g_BlockIsSolid[a_BlockType];
+ else
+ {
+ return true;
}
}
static bool TorchCanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace)
{
- // TODO: If placing a torch from below, check all 4 XZ neighbors, place it on that neighbor instead
- // How to propagate that change up?
- // Simon: The easiest way is to calculate the position two times, shouldn�t cost much cpu power :)
-
- if (a_BlockFace == BLOCK_FACE_BOTTOM)
- {
- return false;
- }
-
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true);
-
return CanBePlacedOn(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ), a_BlockFace);
}
- /// Finds a suitable Face for the Torch. Returns BLOCK_FACE_BOTTOM on failure
+ /// Finds a suitable face to place the torch, returning BLOCK_FACE_NONE on failure
static char FindSuitableFace(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
{
- for (int i = 1; i <= 5; i++)
+ // 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 :)
+
+ for (int i = 0; i <= 5; i++)
{
- if (TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, i))
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, i, true);
+ BLOCKTYPE BlockInQuestion = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
+
+ if (
+ ((BlockInQuestion == E_BLOCK_GLASS) ||
+ (BlockInQuestion == E_BLOCK_FENCE) ||
+ (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) ||
+ (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL)) &&
+ (i = 1)
+ )
+ {
+ return i;
+ }
+ else if ( g_BlockIsTorchPlaceable[BlockInQuestion] )
{
return i;
}
+ else
+ {
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, i, false);
+ }
}
- return BLOCK_FACE_BOTTOM;
+ return BLOCK_FACE_NONE;
}
@@ -163,11 +185,28 @@ public:
virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
- // TODO: Use AdjustCoordsByMeta(), then cChunk::UnboundedRelGetBlock() and finally some comparison
char Face = MetaDataToDirection(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
- return TorchCanBePlacedAt(a_Chunk.GetWorld(), BlockX, a_RelY, BlockZ, Face);
+
+ AddFaceDirection(a_RelX, a_RelY, a_RelZ, Face, true);
+ BLOCKTYPE BlockInQuestion;
+ a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockInQuestion);
+
+ if ((BlockInQuestion == E_BLOCK_GLASS) || (BlockInQuestion == E_BLOCK_FENCE) || (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE))
+ {
+ // Torches can be placed on tops of glass and fences, despite them being 'untorcheable'
+ // No need to check for upright orientation, it was done when the torch was placed
+ return true;
+ }
+ else if ( !g_BlockIsTorchPlaceable[BlockInQuestion] )
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
}