From f622f4317c76aa287649da965456562a32bce41b Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 23 Mar 2014 22:32:45 +0000 Subject: Implemented lilypad placement --- src/Blocks/BlockHandler.cpp | 2 ++ src/Blocks/BlockLilypad.h | 84 +++++++++++++++++++++++++++++++++++++++++++++ src/ClientHandle.cpp | 12 ++++--- src/Items/ItemBucket.h | 8 ++--- 4 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 src/Blocks/BlockLilypad.h (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 4f74e2f45..7fd8c183c 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -41,6 +41,7 @@ #include "BlockIce.h" #include "BlockLadder.h" #include "BlockLeaves.h" +#include "BlockLilypad.h" #include "BlockNewLeaves.h" #include "BlockLever.h" #include "BlockMelon.h" @@ -142,6 +143,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_LAPIS_ORE: return new cBlockOreHandler (a_BlockType); case E_BLOCK_LAVA: return new cBlockLavaHandler (a_BlockType); case E_BLOCK_LEAVES: return new cBlockLeavesHandler (a_BlockType); + case E_BLOCK_LILY_PAD: return new cBlockLilypadHandler (a_BlockType); case E_BLOCK_LIT_FURNACE: return new cBlockFurnaceHandler (a_BlockType); case E_BLOCK_LOG: return new cBlockSidewaysHandler (a_BlockType); case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType); diff --git a/src/Blocks/BlockLilypad.h b/src/Blocks/BlockLilypad.h new file mode 100644 index 000000000..3db280d80 --- /dev/null +++ b/src/Blocks/BlockLilypad.h @@ -0,0 +1,84 @@ + +#pragma once + +#include "BlockHandler.h" +#include "../Entities/Player.h" +#include "Vector3.h" +#include "../LineBlockTracer.h" + + + + + +class cBlockLilypadHandler : + public cBlockHandler +{ + typedef cBlockHandler super; + +public: + cBlockLilypadHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + + } + + virtual bool GetPlacementBlockTypeMeta( + cChunkInterface & a_ChunkInterface, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + if (a_BlockFace > 0) + { + return false; + } + + class cCallbacks : + public cBlockTracer::cCallbacks + { + public: + cCallbacks(void) : + m_HasHitFluid(false) + { + } + + virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override + { + if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType)) + { + if ((a_BlockMeta != 0) || (a_EntryFace == BLOCK_FACE_NONE)) // The hit block should be a source. The FACE_NONE check is for AddFaceDir below + { + return false; + } + m_HasHitFluid = true; + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, (eBlockFace)a_EntryFace); + m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ); + return true; + } + return false; + } + + Vector3i m_Pos; + bool m_HasHitFluid; + + } Callbacks; + + cLineBlockTracer Tracer(*a_Player->GetWorld(), Callbacks); + Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector()); + Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5); + + Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z); + + if (Callbacks.m_HasHitFluid) + { + a_Player->GetWorld()->SetBlock(Callbacks.m_Pos.x, Callbacks.m_Pos.y, Callbacks.m_Pos.z, E_BLOCK_LILY_PAD, 0); + } + + return false; + } +}; + + + + diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 46c10ae82..2c47faa65 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -988,7 +988,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemType); - if (ItemHandler->IsPlaceable() && (a_BlockFace > -1)) + if (ItemHandler->IsPlaceable() && ((a_BlockFace > -1) || (Equipped.m_ItemType == E_BLOCK_LILY_PAD))) { HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler); } @@ -1026,7 +1026,8 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e 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) { - if (a_BlockFace < 0) + BLOCKTYPE EquippedBlock = (BLOCKTYPE)(m_Player->GetEquippedItem().m_ItemType); + if ((a_BlockFace < 0) && (EquippedBlock != E_BLOCK_LILY_PAD)) { // Clicked in air return; @@ -1036,7 +1037,6 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e BLOCKTYPE ClickedBlock; NIBBLETYPE ClickedBlockMeta; - BLOCKTYPE EquippedBlock = (BLOCKTYPE)(m_Player->GetEquippedItem().m_ItemType); NIBBLETYPE EquippedBlockDamage = (NIBBLETYPE)(m_Player->GetEquippedItem().m_ItemDamage); if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) @@ -1085,7 +1085,10 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e } else { - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + if (EquippedBlock != E_BLOCK_LILY_PAD) + { + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + } if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) { @@ -1106,6 +1109,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e else { if ( + (EquippedBlock != E_BLOCK_LILY_PAD) && !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision() && !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision(m_Player, PlaceMeta) ) diff --git a/src/Items/ItemBucket.h b/src/Items/ItemBucket.h index 72cb8fa0a..68c89dd85 100644 --- a/src/Items/ItemBucket.h +++ b/src/Items/ItemBucket.h @@ -172,12 +172,12 @@ public: virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override { - if (a_BlockMeta != 0) // Even if it was a water block it would not be a source. - { - return false; - } if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType)) { + if (a_BlockMeta != 0) // GetBlockFromTrace is called for scooping up fluids; the hit block should be a source + { + return false; + } m_HasHitFluid = true; m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ); return true; -- cgit v1.2.3