| 1027 | |
| 1028 | |
| 1029 | void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler) |
| 1030 | { |
| 1031 | BLOCKTYPE EquippedBlock = (BLOCKTYPE)(m_Player->GetEquippedItem().m_ItemType); |
| 1032 | if (a_BlockFace < 0) |
| 1033 | { |
| 1034 | // Clicked in air |
| 1035 | return; |
| 1036 | } |
| 1037 | |
| 1038 | cWorld * World = m_Player->GetWorld(); |
| 1039 | |
| 1040 | BLOCKTYPE ClickedBlock; |
| 1041 | NIBBLETYPE ClickedBlockMeta; |
| 1042 | NIBBLETYPE EquippedBlockDamage = (NIBBLETYPE)(m_Player->GetEquippedItem().m_ItemDamage); |
| 1043 | |
| 1044 | if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) |
| 1045 | { |
| 1046 | // The block is being placed outside the world, ignore this packet altogether (#128) |
| 1047 | return; |
| 1048 | } |
| 1049 | |
| 1050 | World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedBlockMeta); |
| 1051 | |
| 1052 | // Special slab handling - placing a slab onto another slab produces a dblslab instead: |
| 1053 | if ( |
| 1054 | cBlockSlabHandler::IsAnySlabType(ClickedBlock) && // Is there a slab already? |
| 1055 | cBlockSlabHandler::IsAnySlabType(EquippedBlock) && // Is the player placing another slab? |
| 1056 | ((ClickedBlockMeta & 0x07) == EquippedBlockDamage) && // Is it the same slab type? |
| 1057 | ( |
| 1058 | (a_BlockFace == BLOCK_FACE_TOP) || // Clicking the top of a bottom slab |
| 1059 | (a_BlockFace == BLOCK_FACE_BOTTOM) // Clicking the bottom of a top slab |
| 1060 | ) |
| 1061 | ) |
| 1062 | { |
| 1063 | // Coordinates at clicked block, which was an eligible slab, and either top or bottom faces were clicked |
| 1064 | // If clicked top face and slab occupies the top voxel, we want a slab to be placed above it (therefore increment Y) |
| 1065 | // Else if clicked bottom face and slab occupies the bottom voxel, decrement Y for the same reason |
| 1066 | // Don't touch coordinates if anything else because a dblslab opportunity is present |
| 1067 | if ((ClickedBlockMeta & 0x08) && (a_BlockFace == BLOCK_FACE_TOP)) |
| 1068 | { |
| 1069 | ++a_BlockY; |
| 1070 | } |
| 1071 | else if (!(ClickedBlockMeta & 0x08) && (a_BlockFace == BLOCK_FACE_BOTTOM)) |
| 1072 | { |
| 1073 | --a_BlockY; |
| 1074 | } |
| 1075 | World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedBlockMeta); |
| 1076 | } |
| 1077 | else |
| 1078 | { |
| 1079 | // Check if the block ignores build collision (water, grass etc.): |
| 1080 | if ( |
| 1081 | BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision() || |
| 1082 | BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision(m_Player, ClickedBlockMeta) |
| 1083 | ) |
| 1084 | { |
| 1085 | cChunkInterface ChunkInterface(World->GetChunkMap()); |
| 1086 | BlockHandler(ClickedBlock)->OnDestroyedByPlayer(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ); |
nothing calls this directly
no test coverage detected