1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
#pragma once
#include "ItemHandler.h"
#include "../World.h"
#include "../Blocks/BlockDoor.h"
class cItemDoorHandler :
public cItemHandler
{
public:
cItemDoorHandler(int a_ItemType) :
cItemHandler(a_ItemType)
{
}
virtual bool GetBlocksToPlace(
cWorld & a_World, cPlayer & a_Player, const cItem & a_EquippedItem,
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
sSetBlockVector & a_BlocksToSet
) override
{
// Vanilla only allows door placement while clicking on the top face of the block below the door:
if (a_BlockFace != BLOCK_FACE_TOP)
{
return false;
}
// Door (bottom block) can be placed in Y range of [1, 254]:
if ((a_BlockY < 1) || (a_BlockY >= cChunkDef::Height - 2))
{
return false;
}
// The door needs a compatible block below it:
if (!cBlockDoorHandler::CanBeOn(a_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ), a_World.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ)))
{
return false;
}
// Get the block type of the door to place:
BLOCKTYPE BlockType;
switch (m_ItemType)
{
case E_ITEM_WOODEN_DOOR: BlockType = E_BLOCK_OAK_DOOR; break;
case E_ITEM_IRON_DOOR: BlockType = E_BLOCK_IRON_DOOR; break;
case E_ITEM_SPRUCE_DOOR: BlockType = E_BLOCK_SPRUCE_DOOR; break;
case E_ITEM_BIRCH_DOOR: BlockType = E_BLOCK_BIRCH_DOOR; break;
case E_ITEM_JUNGLE_DOOR: BlockType = E_BLOCK_JUNGLE_DOOR; break;
case E_ITEM_DARK_OAK_DOOR: BlockType = E_BLOCK_DARK_OAK_DOOR; break;
case E_ITEM_ACACIA_DOOR: BlockType = E_BLOCK_ACACIA_DOOR; break;
default:
{
ASSERT(!"Unhandled door type");
return false;
}
}
// Check the two blocks that will get replaced by the door:
BLOCKTYPE LowerBlockType = a_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ);
BLOCKTYPE UpperBlockType = a_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ);
if (
!cBlockDoorHandler::CanReplaceBlock(LowerBlockType) ||
!cBlockDoorHandler::CanReplaceBlock(UpperBlockType))
{
return false;
}
// Get the coords of the neighboring blocks:
NIBBLETYPE LowerBlockMeta = cBlockDoorHandler::PlayerYawToMetaData(a_Player.GetYaw());
Vector3i RelDirToOutside = cBlockDoorHandler::GetRelativeDirectionToOutside(LowerBlockMeta);
Vector3i LeftNeighborPos = RelDirToOutside;
LeftNeighborPos.TurnCW();
LeftNeighborPos.Move(a_BlockX, a_BlockY, a_BlockZ);
Vector3i RightNeighborPos = RelDirToOutside;
RightNeighborPos.TurnCCW();
RightNeighborPos.Move(a_BlockX, a_BlockY, a_BlockZ);
// Decide whether the hinge is on the left (default) or on the right:
NIBBLETYPE UpperBlockMeta = 0x08;
BLOCKTYPE LeftNeighborBlock = a_World.GetBlock(LeftNeighborPos);
BLOCKTYPE RightNeighborBlock = a_World.GetBlock(RightNeighborPos);
/*
// DEBUG:
LOGD("Door being placed at {%d, %d, %d}", a_BlockX, a_BlockY, a_BlockZ);
LOGD("RelDirToOutside: {%d, %d, %d}", RelDirToOutside.x, RelDirToOutside.y, RelDirToOutside.z);
LOGD("Left neighbor at {%d, %d, %d}: %d (%s)", LeftNeighborPos.x, LeftNeighborPos.y, LeftNeighborPos.z, LeftNeighborBlock, ItemTypeToString(LeftNeighborBlock).c_str());
LOGD("Right neighbor at {%d, %d, %d}: %d (%s)", RightNeighborPos.x, RightNeighborPos.y, RightNeighborPos.z, RightNeighborBlock, ItemTypeToString(RightNeighborBlock).c_str());
*/
if (
cBlockDoorHandler::IsDoorBlockType(LeftNeighborBlock) || // The block to the left is a door block
(
!cBlockInfo::IsSolid(LeftNeighborBlock) && // Prioritize hinge on the left side
cBlockInfo::IsSolid(RightNeighborBlock) && // The block to the right is solid...
!cBlockDoorHandler::IsDoorBlockType(RightNeighborBlock) // ... but not a door
)
)
{
// DEBUG: LOGD("Setting hinge to right side");
UpperBlockMeta = 0x09; // Upper block | hinge on right
}
// Set the blocks:
a_BlocksToSet.emplace_back(a_BlockX, a_BlockY, a_BlockZ, BlockType, LowerBlockMeta);
a_BlocksToSet.emplace_back(a_BlockX, a_BlockY + 1, a_BlockZ, BlockType, UpperBlockMeta);
return true;
}
virtual bool IsPlaceable(void) override
{
return true;
}
} ;
|