From 283a66bcae5f26d2b5038ba0959314a687c4d8b6 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 28 Mar 2014 22:51:30 +0000 Subject: Some fixes to lilypads * Fixed placement on lava * Fixed placement on side of blocks * Fixed placement through blocks + Added washing-away of pads + Added ice as a block that fully occupies its voxel --- src/Items/ItemHandler.cpp | 2 + src/Items/ItemLilypad.h | 106 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 src/Items/ItemLilypad.h (limited to 'src/Items') diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 454fabdd7..337b3a83c 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -27,6 +27,7 @@ #include "ItemHoe.h" #include "ItemLeaves.h" #include "ItemLighter.h" +#include "ItemLilypad.h" #include "ItemMap.h" #include "ItemMinecart.h" #include "ItemNetherWart.h" @@ -115,6 +116,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_FISHING_ROD: return new cItemFishingRodHandler(a_ItemType); case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType); case E_ITEM_FLOWER_POT: return new cItemFlowerPotHandler(a_ItemType); + case E_BLOCK_LILY_PAD: return new cItemLilypadHandler(a_ItemType); case E_ITEM_MAP: return new cItemMapHandler(); case E_ITEM_ITEM_FRAME: return new cItemItemFrameHandler(a_ItemType); case E_ITEM_NETHER_WART: return new cItemNetherWartHandler(a_ItemType); diff --git a/src/Items/ItemLilypad.h b/src/Items/ItemLilypad.h new file mode 100644 index 000000000..8496b9f31 --- /dev/null +++ b/src/Items/ItemLilypad.h @@ -0,0 +1,106 @@ + +#pragma once + +#include "ItemHandler.h" +#include "../Entities/Player.h" +#include "Vector3.h" +#include "../LineBlockTracer.h" +#include "BlockInfo.h" + + + + + +class cItemLilypadHandler : + public cItemHandler +{ + typedef cItemHandler super; + +public: + cItemLilypadHandler(BLOCKTYPE a_BlockType) + : cItemHandler(a_BlockType) + { + + } + + virtual bool IsPlaceable(void) override + { + return false; // Set as not placeable so OnItemUse is called + } + + virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override + { + if (a_BlockFace > BLOCK_FACE_NONE) + { + // Clicked on the side of a submerged block; vanilla allows placement, so should we + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LILY_PAD, 0); + if (!a_Player->IsGameModeCreative()) + a_Player->GetInventory().RemoveOneEquippedItem(); + return true; + } + + class cCallbacks : + public cBlockTracer::cCallbacks + { + public: + cCallbacks(cWorld * a_World) : + m_HasHitFluid(false), + m_World(a_World) + { + } + + 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)) + { + if ((a_BlockMeta != 0) || (a_EntryFace == BLOCK_FACE_NONE)) // The hit block should be a source. The FACE_NONE check is clicking whilst submerged + { + return false; + } + a_EntryFace = BLOCK_FACE_YP; // Always place pad at top of water block + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, (eBlockFace)a_EntryFace); + BLOCKTYPE Block = m_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); + if ( + !IsBlockWater(Block) && + cBlockInfo::FullyOccupiesVoxel(Block) + ) + { + // Can't place lilypad on air/in another block! + return true; + } + m_HasHitFluid = true; + m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ); + return true; + } + return false; + } + + Vector3i m_Pos; + bool m_HasHitFluid; + cWorld * m_World; + + }; + + cCallbacks Callbacks(a_World); + 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_World->SetBlock(Callbacks.m_Pos.x, Callbacks.m_Pos.y, Callbacks.m_Pos.z, E_BLOCK_LILY_PAD, 0); + if (!a_Player->IsGameModeCreative()) + a_Player->GetInventory().RemoveOneEquippedItem(); + return true; + } + + return false; + } +}; + + + + -- cgit v1.2.3