diff options
Diffstat (limited to 'src/Items')
-rw-r--r-- | src/Items/ItemBucket.h | 8 | ||||
-rw-r--r-- | src/Items/ItemCake.h | 41 | ||||
-rw-r--r-- | src/Items/ItemHandler.cpp | 7 | ||||
-rw-r--r-- | src/Items/ItemItemFrame.h | 6 | ||||
-rw-r--r-- | src/Items/ItemLighter.h | 24 | ||||
-rw-r--r-- | src/Items/ItemLilypad.h | 109 | ||||
-rw-r--r-- | src/Items/ItemMinecart.h | 6 | ||||
-rw-r--r-- | src/Items/ItemShears.h | 5 |
8 files changed, 196 insertions, 10 deletions
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; diff --git a/src/Items/ItemCake.h b/src/Items/ItemCake.h new file mode 100644 index 000000000..48e23ed59 --- /dev/null +++ b/src/Items/ItemCake.h @@ -0,0 +1,41 @@ + +#pragma once + +#include "ItemHandler.h" + + + + + +class cItemCakeHandler : + public cItemHandler +{ +public: + cItemCakeHandler(int a_ItemType) : + cItemHandler(a_ItemType) + { + } + + + virtual bool IsPlaceable(void) override + { + return true; + } + + + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, 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 + { + a_BlockType = E_BLOCK_CAKE; + a_BlockMeta = 0; + return true; + } +} ; + + + + diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 1d357fcf1..337b3a83c 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -13,6 +13,7 @@ #include "ItemBow.h" #include "ItemBrewingStand.h" #include "ItemBucket.h" +#include "ItemCake.h" #include "ItemCauldron.h" #include "ItemCloth.h" #include "ItemComparator.h" @@ -26,6 +27,7 @@ #include "ItemHoe.h" #include "ItemLeaves.h" #include "ItemLighter.h" +#include "ItemLilypad.h" #include "ItemMap.h" #include "ItemMinecart.h" #include "ItemNetherWart.h" @@ -94,6 +96,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) // Single item per handler, alphabetically sorted: case E_BLOCK_LEAVES: return new cItemLeavesHandler(a_ItemType); + case E_BLOCK_NEW_LEAVES: return new cItemLeavesHandler(a_ItemType); case E_BLOCK_SAPLING: return new cItemSaplingHandler(a_ItemType); case E_BLOCK_WOOL: return new cItemClothHandler(a_ItemType); case E_ITEM_BED: return new cItemBedHandler(a_ItemType); @@ -101,16 +104,19 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_BOTTLE_O_ENCHANTING: return new cItemBottleOEnchantingHandler(); case E_ITEM_BOW: return new cItemBowHandler; case E_ITEM_BREWING_STAND: return new cItemBrewingStandHandler(a_ItemType); + case E_ITEM_CAKE: return new cItemCakeHandler(a_ItemType); case E_ITEM_CAULDRON: return new cItemCauldronHandler(a_ItemType); case E_ITEM_COMPARATOR: return new cItemComparatorHandler(a_ItemType); case E_ITEM_DYE: return new cItemDyeHandler(a_ItemType); case E_ITEM_EGG: return new cItemEggHandler(); case E_ITEM_EMPTY_MAP: return new cItemEmptyMapHandler(); case E_ITEM_ENDER_PEARL: return new cItemEnderPearlHandler(); + case E_ITEM_FIRE_CHARGE: return new cItemLighterHandler(a_ItemType); case E_ITEM_FIREWORK_ROCKET: return new cItemFireworkHandler(); 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); @@ -337,6 +343,7 @@ char cItemHandler::GetMaxStackSize(void) case E_ITEM_BREWING_STAND: return 64; case E_ITEM_BUCKET: return 16; case E_ITEM_CARROT: return 64; + case E_ITEM_CAKE: return 1; case E_ITEM_CAULDRON: return 64; case E_ITEM_CLAY: return 64; case E_ITEM_CLAY_BRICK: return 64; diff --git a/src/Items/ItemItemFrame.h b/src/Items/ItemItemFrame.h index 74e987445..27e7dba35 100644 --- a/src/Items/ItemItemFrame.h +++ b/src/Items/ItemItemFrame.h @@ -34,7 +34,11 @@ public: if (Block == E_BLOCK_AIR) { cItemFrame * ItemFrame = new cItemFrame(a_Dir, a_BlockX, a_BlockY, a_BlockZ); - ItemFrame->Initialize(a_World); + if (!ItemFrame->Initialize(a_World)) + { + delete ItemFrame; + return false; + } if (!a_Player->IsGameModeCreative()) { diff --git a/src/Items/ItemLighter.h b/src/Items/ItemLighter.h index 18873e911..32f49cab6 100644 --- a/src/Items/ItemLighter.h +++ b/src/Items/ItemLighter.h @@ -26,7 +26,26 @@ public: return false; } - a_Player->UseEquippedItem(); + if (!a_Player->IsGameModeCreative()) + { + switch (m_ItemType) + { + case E_ITEM_FLINT_AND_STEEL: + { + a_Player->UseEquippedItem(); + break; + } + case E_ITEM_FIRE_CHARGE: + { + a_Player->GetInventory().RemoveOneEquippedItem(); + break; + } + default: + { + ASSERT(!"Unknown Lighter Item!"); + } + } + } switch (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ)) { @@ -34,8 +53,8 @@ public: { // Activate the TNT: a_World->BroadcastSoundEffect("game.tnt.primed", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 1.0f, 1.0f); - a_World->SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5); // 80 ticks to boom a_World->SetBlock(a_BlockX,a_BlockY,a_BlockZ, E_BLOCK_AIR, 0); + a_World->SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5); // 80 ticks to boom break; } default: @@ -49,6 +68,7 @@ public: if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_AIR) { a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FIRE, 0); + a_World->BroadcastSoundEffect("fire.ignite", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 1.0F, 1.04F); break; } } diff --git a/src/Items/ItemLilypad.h b/src/Items/ItemLilypad.h new file mode 100644 index 000000000..5a29abe94 --- /dev/null +++ b/src/Items/ItemLilypad.h @@ -0,0 +1,109 @@ +#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; + } +}; + + + + diff --git a/src/Items/ItemMinecart.h b/src/Items/ItemMinecart.h index bcaa5635a..25500aeb9 100644 --- a/src/Items/ItemMinecart.h +++ b/src/Items/ItemMinecart.h @@ -1,4 +1,3 @@ - // ItemMinecart.h // Declares the various minecart ItemHandlers @@ -72,6 +71,11 @@ public: } } // switch (m_ItemType) Minecart->Initialize(a_World); + + if (!a_Player->IsGameModeCreative()) + { + a_Player->GetInventory().RemoveOneEquippedItem(); + } return true; } diff --git a/src/Items/ItemShears.h b/src/Items/ItemShears.h index b8f75f5ba..39d2776fa 100644 --- a/src/Items/ItemShears.h +++ b/src/Items/ItemShears.h @@ -28,10 +28,10 @@ public: virtual bool OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) override { BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); - if (Block == E_BLOCK_LEAVES) + if ((Block == E_BLOCK_LEAVES) || (Block == E_BLOCK_NEW_LEAVES)) { cItems Drops; - Drops.push_back(cItem(E_BLOCK_LEAVES, 1, a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x03)); + Drops.push_back(cItem(Block, 1, a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x03)); a_World->SpawnItemPickups(Drops, a_BlockX, a_BlockY, a_BlockZ); a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); @@ -49,6 +49,7 @@ public: case E_BLOCK_COBWEB: case E_BLOCK_VINES: case E_BLOCK_LEAVES: + case E_BLOCK_NEW_LEAVES: { return true; } |