From 14dce238450b419a5df2aa171ee91981910463b0 Mon Sep 17 00:00:00 2001 From: "lapayo94@gmail.com" Date: Sun, 15 Jul 2012 20:36:34 +0000 Subject: A new Block handling system :o It was really a lot of work :D Took me the complete weekend :D Would really like to here your opinion on this =) The aim of this is to put all the actions for one block in one place so it is not spread around the source. (ToPickup, Action in cWorld, Action in cChunk, Action here, action there :D) git-svn-id: http://mc-server.googlecode.com/svn/trunk@671 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/items/Item.cpp | 224 ++++++++++++++++++++++++++++++++++++++++ source/items/Item.h | 45 ++++++++ source/items/ItemBucket.h | 75 ++++++++++++++ source/items/ItemCloth.h | 18 ++++ source/items/ItemDoor.h | 25 +++++ source/items/ItemDye.h | 32 ++++++ source/items/ItemHoe.h | 29 ++++++ source/items/ItemLeaves.h | 17 +++ source/items/ItemLighter.h | 27 +++++ source/items/ItemPickaxe.h | 72 +++++++++++++ source/items/ItemRedstoneDust.h | 27 +++++ source/items/ItemSapling.h | 20 ++++ source/items/ItemSeeds.h | 58 +++++++++++ source/items/ItemShears.h | 41 ++++++++ source/items/ItemShovel.h | 35 +++++++ source/items/ItemSlab.h | 39 +++++++ source/items/ItemSugarcane.h | 34 ++++++ source/items/ItemSword.h | 19 ++++ source/items/ItemWood.h | 17 +++ 19 files changed, 854 insertions(+) create mode 100644 source/items/Item.cpp create mode 100644 source/items/Item.h create mode 100644 source/items/ItemBucket.h create mode 100644 source/items/ItemCloth.h create mode 100644 source/items/ItemDoor.h create mode 100644 source/items/ItemDye.h create mode 100644 source/items/ItemHoe.h create mode 100644 source/items/ItemLeaves.h create mode 100644 source/items/ItemLighter.h create mode 100644 source/items/ItemPickaxe.h create mode 100644 source/items/ItemRedstoneDust.h create mode 100644 source/items/ItemSapling.h create mode 100644 source/items/ItemSeeds.h create mode 100644 source/items/ItemShears.h create mode 100644 source/items/ItemShovel.h create mode 100644 source/items/ItemSlab.h create mode 100644 source/items/ItemSugarcane.h create mode 100644 source/items/ItemSword.h create mode 100644 source/items/ItemWood.h (limited to 'source/items') diff --git a/source/items/Item.cpp b/source/items/Item.cpp new file mode 100644 index 000000000..b3a525c6b --- /dev/null +++ b/source/items/Item.cpp @@ -0,0 +1,224 @@ +#include "Globals.h" +#include "Item.h" +#include "../cItem.h" +#include "../cWorld.h" +#include "../cPlayer.h" + +//Handler +#include "ItemCloth.h" +#include "ItemHoe.h" +#include "ItemSlab.h" +#include "ItemWood.h" +#include "ItemShears.h" +#include "ItemLeaves.h" +#include "ItemSapling.h" +#include "ItemBucket.h" +#include "ItemLighter.h" +#include "ItemRedstoneDust.h" +#include "ItemSeeds.h" +#include "ItemDye.h" +#include "ItemSugarcane.h" +#include "ItemPickaxe.h" +#include "ItemShovel.h" +#include "ItemSword.h" +#include "ItemDoor.h" + +#include "../blocks/Block.h" + +bool cItemHandler::m_HandlerInitialized = false; +cItemHandler *cItemHandler::m_ItemHandler[2266]; + +cItemHandler *cItemHandler::GetItemHandler(int a_ItemID) +{ + if(a_ItemID < 0) a_ItemID = 0; + + if(!m_HandlerInitialized) + { //We have to initialize + memset(m_ItemHandler, 0, sizeof(m_ItemHandler)); + m_HandlerInitialized = true; + } + if(m_ItemHandler[a_ItemID]) + return m_ItemHandler[a_ItemID]; + m_ItemHandler[a_ItemID] = CreateItemHandler(a_ItemID); + return m_ItemHandler[a_ItemID]; +} + +cItemHandler *cItemHandler::CreateItemHandler(int a_ItemID) +{ + switch(a_ItemID) + { + case E_ITEM_WOODEN_HOE: + case E_ITEM_STONE_HOE: + case E_ITEM_IRON_HOE: + case E_ITEM_GOLD_HOE: + case E_ITEM_DIAMOND_HOE: + return new cItemHoeHandler(a_ItemID); + case E_ITEM_WHITE_CLOTH: + return new cItemClothHandler(a_ItemID); + case E_ITEM_STONE_SLAB: + case E_ITEM_WOODEN_SLAB: + return new cItemSlabHandler(a_ItemID); + case E_ITEM_LOG: + case E_ITEM_WOOD: + return new cItemWoodHandler(a_ItemID); + case E_ITEM_SHEARS: + return new cItemShearsHandler(a_ItemID); + case E_ITEM_LEAVES: + return new cItemLeavesHandler(a_ItemID); + case E_ITEM_SAPLING: + return new cItemSaplingHandler(a_ItemID); + case E_ITEM_REDSTONE_DUST: + return new cItemRedstoneDustHandler(a_ItemID); + case E_ITEM_BUCKET: + case E_ITEM_WATER_BUCKET: + case E_ITEM_LAVA_BUCKET: + return new cItemBucketHandler(a_ItemID); + case E_ITEM_FLINT_AND_STEEL: + return new cItemLighterHandler(a_ItemID); + case E_ITEM_PUMPKIN_SEEDS: + case E_ITEM_MELON_SEEDS: + case E_ITEM_SEEDS: + return new cItemSeedsHandler(a_ItemID); + case E_ITEM_DYE: + return new cItemDyeHandler(a_ItemID); + case E_ITEM_SUGARCANE: + return new cItemSugarcaneHandler(a_ItemID); + case E_ITEM_WOODEN_PICKAXE: + case E_ITEM_STONE_PICKAXE: + case E_ITEM_IRON_PICKAXE: + case E_ITEM_GOLD_PICKAXE: + case E_ITEM_DIAMOND_PICKAXE: + return new cItemPickaxeHandler(a_ItemID); + case E_ITEM_WOODEN_SHOVEL: + case E_ITEM_STONE_SHOVEL: + case E_ITEM_IRON_SHOVEL: + case E_ITEM_GOLD_SHOVEL: + case E_ITEM_DIAMOND_SHOVEL: + return new cItemShovelHandler(a_ItemID); + case E_ITEM_WOODEN_SWORD: + case E_ITEM_STONE_SWORD: + case E_ITEM_IRON_SWORD: + case E_ITEM_GOLD_SWORD: + case E_ITEM_DIAMOND_SWORD: + return new cItemSwordHandler(a_ItemID); + + case E_ITEM_IRON_DOOR: + case E_ITEM_WOODEN_DOOR: + return new cItemDoorHandler(a_ItemID); + + default: + return new cItemHandler(a_ItemID); + break; + } +} + +void cItemHandler::Deinit() +{ + for(int i = 0; i < 2266; i++) + { + delete m_ItemHandler[i]; + } +} + +cItemHandler::cItemHandler(int a_ItemID) +{ + m_ItemID = a_ItemID; +} + +bool cItemHandler::OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir) +{ + return false; +} + +bool cItemHandler::OnDiggingBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir) +{ + return false; +} + +void cItemHandler::OnBlockDestroyed(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z) +{ + char Block = a_World->GetBlock(a_X, a_Y, a_Z); + cBlockHandler *Handler = cBlockHandler::GetBlockHandler(Block); + + if(a_Player->GetGameMode() == eGameMode_Survival) + { + if(!BlockRequiresSpecialTool(Block) || CanHarvestBlock(Block)) + { + Handler->DropBlock(a_World, a_X, a_Y, a_Z); + } + } + + a_Player->UseEquippedItem(); +} + +void cItemHandler::OnFoodEaten(cWorld *a_World, cPlayer *a_Player, cItem *a_Item) +{ + +} + +int cItemHandler::GetMaxStackSize() +{ + return 64; +} + +int cItemHandler::GetMaxDamage() +{ + return 0; +} + +bool cItemHandler::IsTool() +{ + return + (m_ItemID >= 256 && m_ItemID <= 259) + || (m_ItemID == 261) + || (m_ItemID >= 267 && m_ItemID <= 279) + || (m_ItemID >= 283 && m_ItemID <= 286) + || (m_ItemID >= 290 && m_ItemID <= 294) + || (m_ItemID >= 256 && m_ItemID <= 259) + || (m_ItemID == 325) + || (m_ItemID == 346); +} + +bool cItemHandler::IsFood() +{ + return + (m_ItemID == 260) + || (m_ItemID == 282) + || (m_ItemID == 297) + || (m_ItemID >= 319 && m_ItemID <= 320) + || (m_ItemID == 335) + || (m_ItemID >= 349 && m_ItemID <= 350) + || (m_ItemID == 357) + || (m_ItemID == 360) + || (m_ItemID >= 363 && m_ItemID <= 366); +} + +bool cItemHandler::IsPlaceable() +{ + return m_ItemID >= 1 && m_ItemID <= 136; +} + + +bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockID) +{ + return false; +} + +BLOCKTYPE cItemHandler::GetBlockType() +{ + return m_ItemID; +} + +char cItemHandler::GetBlockMeta(char a_ItemMeta) +{ + return a_ItemMeta; //This keeps most textures. The few other items have to override this +} + +void cItemHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir) +{ + BLOCKTYPE Block = GetBlockType(); + cBlockHandler *Handler = cBlockHandler::GetBlockHandler(Block); + Handler->PlaceBlock(a_World, a_Player, GetBlockMeta(a_Item->m_ItemHealth), a_X, a_Y, a_Z, a_Dir); + if(a_Player->GetGameMode() == eGameMode_Survival) + a_Player->GetInventory().RemoveItem(cItem(a_Item->m_ItemID, 1)); +} \ No newline at end of file diff --git a/source/items/Item.h b/source/items/Item.h new file mode 100644 index 000000000..e63ec2fc4 --- /dev/null +++ b/source/items/Item.h @@ -0,0 +1,45 @@ +#pragma once +#include "../Defines.h" + +class cWorld; +class cPlayer; + + +class cItemHandler +{ +public: + cItemHandler(int a_ItemID); + virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir); //eg for fishing or hoes + virtual bool OnDiggingBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir); + virtual void OnBlockDestroyed(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z); + virtual void OnFoodEaten(cWorld *a_World, cPlayer *a_Player, cItem *a_Item); + virtual int GetMaxStackSize(); + virtual int GetMaxDamage(); + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir); + + virtual bool IsTool(); + virtual bool IsFood(); + //Blocks simply get placed + virtual bool IsPlaceable(); + + virtual BLOCKTYPE GetBlockType(); + virtual char GetBlockMeta(char a_ItemMeta); + + virtual bool CanHarvestBlock(BLOCKTYPE a_BlockID); + + static cItemHandler *GetItemHandler(int a_ItemID); + + static void Deinit(); + + +protected: + int m_ItemID; + static cItemHandler *CreateItemHandler(int m_ItemID); + + static cItemHandler *m_ItemHandler[2266]; + static bool m_HandlerInitialized; //used to detect if the itemhandlers are initialized +}; + +//Short function +inline cItemHandler *ItemHandler(int a_ItemID) { return cItemHandler::GetItemHandler(a_ItemID); } \ No newline at end of file diff --git a/source/items/ItemBucket.h b/source/items/ItemBucket.h new file mode 100644 index 000000000..e223d47f1 --- /dev/null +++ b/source/items/ItemBucket.h @@ -0,0 +1,75 @@ +#pragma once + +#include "Item.h" +#include "../cWorld.h" + +class cItemBucketHandler : public cItemHandler +{ +public: + cItemBucketHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + + } + + virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir) + { + switch(m_ItemID) + { + case E_ITEM_BUCKET: + { + AddDirection(a_X, a_Y, a_Z, a_Dir); + BLOCKTYPE ClickedBlock = a_World->GetBlock(a_X, a_Y, a_Z); + LOG("Bucket Clicked BlockID: %d", ClickedBlock); + ENUM_ITEM_ID NewItem = E_ITEM_EMPTY; + switch (ClickedBlock) + { + case E_BLOCK_WATER: + case E_BLOCK_STATIONARY_WATER: + NewItem = E_ITEM_WATER_BUCKET; + break; + case E_BLOCK_LAVA: + case E_BLOCK_STATIONARY_LAVA: + NewItem = E_ITEM_LAVA_BUCKET; + break; + } + if (NewItem != E_ITEM_EMPTY + && (a_Player->GetGameMode() == 1 || (a_Player->GetInventory().RemoveItem(cItem(a_Item->m_ItemID, 1))))) + { + //Give New Bucket + a_Player->GetInventory().AddItem(cItem(NewItem, 1)); + //remove water block + a_Player->GetWorld()->SetBlock(a_X, a_Y, a_Z, E_BLOCK_AIR, 0); + return true; + } + } + break; + case E_ITEM_WATER_BUCKET: + case E_ITEM_LAVA_BUCKET: + { + BLOCKTYPE NewBlock = (m_ItemID == E_ITEM_LAVA_BUCKET) ? E_BLOCK_LAVA : E_BLOCK_WATER; + + AddDirection(a_X, a_Y, a_Z, a_Dir); + if(a_World->GetBlock(a_X, a_Y, a_Z) == E_BLOCK_AIR) + { + if ((a_Player->GetGameMode() == 1) || (a_Player->GetInventory().RemoveItem(cItem(a_Item->m_ItemID, 1)))) + { + a_World->SetBlock(a_X, a_Y, a_Z, NewBlock, 0); + + if (a_Player->GetGameMode() == 1) + { + break; //No new Bucket for creative players + } + + a_Player->GetInventory().AddItem(cItem(E_ITEM_BUCKET, 1)); + return true; + } + } + } + break; + } + + return false; + } + +}; \ No newline at end of file diff --git a/source/items/ItemCloth.h b/source/items/ItemCloth.h new file mode 100644 index 000000000..805e90cb4 --- /dev/null +++ b/source/items/ItemCloth.h @@ -0,0 +1,18 @@ +#pragma once + +#include "Item.h" + + +class cItemClothHandler : public cItemHandler +{ +public: + cItemClothHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + + } + virtual char GetBlockMeta(char a_ItemMeta) + { + return a_ItemMeta; + } +}; \ No newline at end of file diff --git a/source/items/ItemDoor.h b/source/items/ItemDoor.h new file mode 100644 index 000000000..5b656ce17 --- /dev/null +++ b/source/items/ItemDoor.h @@ -0,0 +1,25 @@ +#pragma once + +#include "Item.h" +#include "../cWorld.h" + +class cItemDoorHandler : public cItemHandler +{ +public: + cItemDoorHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + + } + + virtual bool IsPlaceable() + { + return true; + } + + virtual BLOCKTYPE GetBlockType() + { + return (m_ItemID == E_ITEM_WOODEN_DOOR) ? E_BLOCK_WOODEN_DOOR : E_BLOCK_IRON_DOOR; + } + +}; \ No newline at end of file diff --git a/source/items/ItemDye.h b/source/items/ItemDye.h new file mode 100644 index 000000000..60a1ed289 --- /dev/null +++ b/source/items/ItemDye.h @@ -0,0 +1,32 @@ +#pragma once +#include "Item.h" +#include "../cWorld.h" +#include "../cPlayer.h" + +class cItemDyeHandler : public cItemHandler +{ +public: + cItemDyeHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + + } + + virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir) + { + // TODO: Handle coloring the sheep, too (OnItemUseOnEntity maybe) + // Handle growing the plants: + if (a_Item->m_ItemHealth == E_META_DYE_WHITE) + { + if(a_World->GrowPlant(a_X, a_Y, a_Z, true)) + { + if (a_Player->GetGameMode() == eGameMode_Survival) + { + a_Player->GetInventory().RemoveItem(cItem(a_Item->m_ItemID, 1, a_Item->m_ItemHealth)); + return true; + } + } + } + return false; + } +}; \ No newline at end of file diff --git a/source/items/ItemHoe.h b/source/items/ItemHoe.h new file mode 100644 index 000000000..dd73f4ac9 --- /dev/null +++ b/source/items/ItemHoe.h @@ -0,0 +1,29 @@ +#pragma once +#include "Item.h" +#include "../cWorld.h" +#include "../cPlayer.h" + +class cItemHoeHandler : public cItemHandler +{ +public: + cItemHoeHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + + } + + virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir) + { + BLOCKTYPE Block = a_World->GetBlock(a_X, a_Y, a_Z); + + if(Block == E_BLOCK_DIRT || Block == E_BLOCK_GRASS) + { + a_World->FastSetBlock(a_X, a_Y, a_Z, E_BLOCK_FARMLAND, 0); + + a_Player->UseEquippedItem(); + return true; + + } + return false; + } +}; \ No newline at end of file diff --git a/source/items/ItemLeaves.h b/source/items/ItemLeaves.h new file mode 100644 index 000000000..d328858fd --- /dev/null +++ b/source/items/ItemLeaves.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Item.h" + + +class cItemLeavesHandler : public cItemHandler +{ +public: + cItemLeavesHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + } + virtual char GetBlockMeta(char a_ItemMeta) + { + return a_ItemMeta | 0x4; //0x4 bit set means this is a player places leave + } +}; \ No newline at end of file diff --git a/source/items/ItemLighter.h b/source/items/ItemLighter.h new file mode 100644 index 000000000..287a7742f --- /dev/null +++ b/source/items/ItemLighter.h @@ -0,0 +1,27 @@ +#pragma once + +#include "Item.h" +#include "../cWorld.h" +#include "../cPlayer.h" + +class cItemLighterHandler : public cItemHandler +{ +public: + cItemLighterHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + + } + + virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir) + { + a_Player->UseEquippedItem(); + + AddDirection(a_X, a_Y, a_Z, a_Dir); + + a_World->SetBlock(a_X, a_Y, a_Z, E_BLOCK_FIRE, 0); //0 -> new fire TODO: Make Firesimulator use this + + return false; + } + +}; \ No newline at end of file diff --git a/source/items/ItemPickaxe.h b/source/items/ItemPickaxe.h new file mode 100644 index 000000000..1be3745de --- /dev/null +++ b/source/items/ItemPickaxe.h @@ -0,0 +1,72 @@ +#pragma once +#include "Item.h" +#include "../cWorld.h" +#include "../cPlayer.h" + +class cItemPickaxeHandler : public cItemHandler +{ +public: + cItemPickaxeHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + + } + + char PickaxeLevel() + { + switch(m_ItemID) + { + case E_ITEM_WOODEN_PICKAXE: + case E_ITEM_GOLD_PICKAXE: + return 1; + case E_ITEM_STONE_PICKAXE: + return 2; + case E_ITEM_IRON_PICKAXE: + return 3; + case E_ITEM_DIAMOND_PICKAXE: + return 4; + default: + return 0; + } + } + + virtual bool CanHarvestBlock(BLOCKTYPE a_BlockID) + { + switch(a_BlockID) + { + case E_BLOCK_OBSIDIAN: + return PickaxeLevel() >= 4; + case E_BLOCK_DIAMOND_BLOCK: + case E_BLOCK_DIAMOND_ORE: + case E_BLOCK_GOLD_BLOCK: + case E_BLOCK_GOLD_ORE: + case E_BLOCK_REDSTONE_ORE: + case E_BLOCK_REDSTONE_ORE_GLOWING: + case E_BLOCK_EMERALD_ORE: + return PickaxeLevel() >= 3; + case E_BLOCK_IRON_BLOCK: + case E_BLOCK_IRON_ORE: + case E_BLOCK_LAPIS_ORE: + case E_BLOCK_LAPIS_BLOCK: + return PickaxeLevel() >= 2; + case E_BLOCK_COAL_ORE: + case E_BLOCK_STONE: + case E_BLOCK_COBBLESTONE: + case E_BLOCK_END_STONE: + case E_BLOCK_MOSSY_COBBLESTONE: + case E_BLOCK_SANDSTONE_STAIRS: + case E_BLOCK_SANDSTONE: + case E_BLOCK_STONE_BRICKS: + case E_BLOCK_NETHER_BRICK: + case E_BLOCK_NETHERRACK: + case E_BLOCK_STONE_SLAB: + case E_BLOCK_DOUBLE_STONE_SLAB: + case E_BLOCK_STONE_PRESSURE_PLATE: + case E_BLOCK_BRICK: + case E_BLOCK_COBBLESTONE_STAIRS: + case E_BLOCK_STONE_BRICK_STAIRS: + case E_BLOCK_NETHER_BRICK_STAIRS: + return PickaxeLevel() >= 1; + } + } +}; \ No newline at end of file diff --git a/source/items/ItemRedstoneDust.h b/source/items/ItemRedstoneDust.h new file mode 100644 index 000000000..99529a4e8 --- /dev/null +++ b/source/items/ItemRedstoneDust.h @@ -0,0 +1,27 @@ +#pragma once +#include "Item.h" + + +class cItemRedstoneDustHandler : public cItemHandler +{ +public: + cItemRedstoneDustHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + } + + virtual bool IsPlaceable() + { + return true; + } + + virtual BLOCKTYPE GetBlockType() + { + return E_BLOCK_REDSTONE_WIRE; + } + + virtual char GetBlockMeta(char a_ItemMeta) + { + return 0; + } +}; \ No newline at end of file diff --git a/source/items/ItemSapling.h b/source/items/ItemSapling.h new file mode 100644 index 000000000..29c14abee --- /dev/null +++ b/source/items/ItemSapling.h @@ -0,0 +1,20 @@ +#pragma once + +#include "Item.h" + + +class cItemSaplingHandler : public cItemHandler +{ +public: + cItemSaplingHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + + } + + virtual char GetBlockMeta(char a_ItemMeta) + { + //Only the first 2 bits are important + return a_ItemMeta & 3; + } +}; \ No newline at end of file diff --git a/source/items/ItemSeeds.h b/source/items/ItemSeeds.h new file mode 100644 index 000000000..d5f9244b2 --- /dev/null +++ b/source/items/ItemSeeds.h @@ -0,0 +1,58 @@ +#pragma once + +#include "Item.h" +#include "../cWorld.h" + +class cItemSeedsHandler : public cItemHandler +{ +public: + cItemSeedsHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + + } + + virtual bool IsPlaceable() + { + return true; + } + + virtual bool AllowBlockOnTop() + { + return false; + } + + virtual BLOCKTYPE GetBlockType() + { + switch(m_ItemID) + { + case E_ITEM_SEEDS: + return E_BLOCK_CROPS; + case E_ITEM_MELON_SEEDS: + E_BLOCK_MELON_STEM; + case E_ITEM_PUMPKIN_SEEDS: + E_BLOCK_PUMPKIN_STEM; + default: + return E_BLOCK_AIR; + } + } + + virtual char GetBlockMeta(char a_ItemMeta) + { + return 0; //Not grown yet + } + + virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir) + { + int X = a_X, + Y = a_Y, + Z = a_Z; + + AddDirection(X, Y, Z, a_Dir, true); + + if(a_World->GetBlock(X, Y, Z) != E_BLOCK_FARMLAND) + return; + + return cItemHandler::PlaceBlock(a_World, a_Player, a_Item, a_X, a_Y, a_Z, a_Dir); + } +}; \ No newline at end of file diff --git a/source/items/ItemShears.h b/source/items/ItemShears.h new file mode 100644 index 000000000..786ea5f5e --- /dev/null +++ b/source/items/ItemShears.h @@ -0,0 +1,41 @@ +#pragma once + +#include "Item.h" +#include "../cWorld.h" +#include "../cPlayer.h" + +class cItemShearsHandler : public cItemHandler +{ +public: + cItemShearsHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + + } + virtual bool IsTool() + { + return true; + } + virtual bool OnDiggingBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir) override + { + BLOCKTYPE Block = a_World->GetBlock(a_X, a_Y, a_Z); + if(Block == E_BLOCK_LEAVES) + { + cItems Drops; + Drops.push_back(cItem(E_ITEM_LEAVES, 1, a_World->GetBlockMeta(a_X, a_Y, a_Z))); + a_World->SpawnItemPickups(Drops, a_X, a_Y, a_Z); + + a_World->SetBlock(a_X, a_Y, a_Z, E_BLOCK_AIR, 0); + a_Player->UseEquippedItem(); + return true; + } + return false; + } + + + virtual bool CanHarvestBlock(BLOCKTYPE a_BlockID) + { + return a_BlockID == E_BLOCK_COBWEB + || a_BlockID == E_BLOCK_VINES; + } +}; \ No newline at end of file diff --git a/source/items/ItemShovel.h b/source/items/ItemShovel.h new file mode 100644 index 000000000..5fd21cc26 --- /dev/null +++ b/source/items/ItemShovel.h @@ -0,0 +1,35 @@ +#pragma once +#include "Item.h" +#include "../cWorld.h" +#include "../cPlayer.h" + +#include "../blocks/Block.h" + +class cItemShovelHandler : public cItemHandler +{ +public: + cItemShovelHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + + } + + virtual bool OnDiggingBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir) override + { + BLOCKTYPE Block = a_World->GetBlock(a_X, a_Y, a_Z); + if(Block == E_BLOCK_SNOW) + { + BlockHandler(Block)->DropBlock(a_World, a_X, a_Y, a_Z); + + a_World->SetBlock(a_X, a_Y, a_Z, E_BLOCK_AIR, 0); + a_Player->UseEquippedItem(); + return true; + } + return false; + } + + virtual bool CanHarvestBlock(BLOCKTYPE a_BlockID) + { + return a_BlockID == E_BLOCK_SNOW; + } +}; \ No newline at end of file diff --git a/source/items/ItemSlab.h b/source/items/ItemSlab.h new file mode 100644 index 000000000..3cb4afeb0 --- /dev/null +++ b/source/items/ItemSlab.h @@ -0,0 +1,39 @@ +#pragma once + +#include "Item.h" +#include "../cWorld.h" + +class cItemSlabHandler : public cItemHandler +{ +public: + cItemSlabHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + + } + + virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir) + { + BLOCKTYPE Block; + NIBBLETYPE Meta; + a_World->GetBlockTypeMeta(a_X, a_Y, a_Z, Block, Meta); + + if( (a_Dir == 0 || a_Dir == 1) //Only when clicking on top or on bottom of the block + && (Block == E_BLOCK_WOODEN_SLAB || Block == E_BLOCK_STONE_SLAB) //It is a slab + && (Block == a_Item->m_ItemID) //Same slab + && ((Meta & 0x7) == (a_Item->m_ItemHealth & 0x7))) //Same Texture + { + if(a_Player->GetInventory().RemoveItem(cItem(a_Item->m_ItemID, 1))) + { + a_World->SetBlock(a_X, a_Y, a_Z, Block - 1, Meta); //Block - 1 simple hack to save one if statement + return true; + } + } + return false; + } + + virtual char GetBlockMeta(char a_ItemMeta) + { + return a_ItemMeta; + } +}; \ No newline at end of file diff --git a/source/items/ItemSugarcane.h b/source/items/ItemSugarcane.h new file mode 100644 index 000000000..515f94014 --- /dev/null +++ b/source/items/ItemSugarcane.h @@ -0,0 +1,34 @@ +#pragma once + +#include "Item.h" +#include "../cWorld.h" + +class cItemSugarcaneHandler : public cItemHandler +{ +public: + cItemSugarcaneHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + + } + + virtual bool IsPlaceable() + { + return true; + } + + virtual bool AllowBlockOnTop() + { + return false; + } + + virtual BLOCKTYPE GetBlockType() + { + return E_BLOCK_SUGARCANE; + } + + virtual char GetBlockMeta(char a_ItemMeta) + { + return 0; //Not grown yet + } +}; \ No newline at end of file diff --git a/source/items/ItemSword.h b/source/items/ItemSword.h new file mode 100644 index 000000000..f49436d51 --- /dev/null +++ b/source/items/ItemSword.h @@ -0,0 +1,19 @@ +#pragma once +#include "Item.h" +#include "../cWorld.h" +#include "../cPlayer.h" + +class cItemSwordHandler : public cItemHandler +{ +public: + cItemSwordHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + + } + + virtual bool CanHarvestBlock(BLOCKTYPE a_BlockID) + { + return a_BlockID == E_BLOCK_COBWEB; + } +}; \ No newline at end of file diff --git a/source/items/ItemWood.h b/source/items/ItemWood.h new file mode 100644 index 000000000..91eaa7675 --- /dev/null +++ b/source/items/ItemWood.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Item.h" + + +class cItemWoodHandler : public cItemHandler +{ +public: + cItemWoodHandler(int a_ItemID) + : cItemHandler(a_ItemID) + { + } + virtual char GetBlockMeta(char a_ItemMeta) + { + return a_ItemMeta; + } +}; \ No newline at end of file -- cgit v1.2.3