summaryrefslogtreecommitdiffstats
path: root/source/Items
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-09-29 15:59:32 +0200
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-09-29 15:59:32 +0200
commit4df23d19b7be2f274974e3dfe91e716e6296f11c (patch)
tree144451e77d8363c4c4d15c4f634c30bdf0728131 /source/Items
parentExtended the cFile interface with Printf() (diff)
downloadcuberite-4df23d19b7be2f274974e3dfe91e716e6296f11c.tar
cuberite-4df23d19b7be2f274974e3dfe91e716e6296f11c.tar.gz
cuberite-4df23d19b7be2f274974e3dfe91e716e6296f11c.tar.bz2
cuberite-4df23d19b7be2f274974e3dfe91e716e6296f11c.tar.lz
cuberite-4df23d19b7be2f274974e3dfe91e716e6296f11c.tar.xz
cuberite-4df23d19b7be2f274974e3dfe91e716e6296f11c.tar.zst
cuberite-4df23d19b7be2f274974e3dfe91e716e6296f11c.zip
Diffstat (limited to 'source/Items')
-rw-r--r--source/Items/ItemBed.h25
-rw-r--r--source/Items/ItemBucket.h94
-rw-r--r--source/Items/ItemCloth.h23
-rw-r--r--source/Items/ItemDoor.h26
-rw-r--r--source/Items/ItemDye.h35
-rw-r--r--source/Items/ItemFood.h56
-rw-r--r--source/Items/ItemHandler.cpp422
-rw-r--r--source/Items/ItemHandler.h83
-rw-r--r--source/Items/ItemHoe.h31
-rw-r--r--source/Items/ItemLeaves.h27
-rw-r--r--source/Items/ItemLighter.h27
-rw-r--r--source/Items/ItemPickaxe.h75
-rw-r--r--source/Items/ItemRedstoneDust.h36
-rw-r--r--source/Items/ItemRedstoneRepeater.h36
-rw-r--r--source/Items/ItemSapling.h28
-rw-r--r--source/Items/ItemSeeds.h59
-rw-r--r--source/Items/ItemShears.h42
-rw-r--r--source/Items/ItemShovel.h41
-rw-r--r--source/Items/ItemSign.h26
-rw-r--r--source/Items/ItemSlab.h45
-rw-r--r--source/Items/ItemSugarcane.h39
-rw-r--r--source/Items/ItemSword.h21
-rw-r--r--source/Items/ItemWood.h22
23 files changed, 1319 insertions, 0 deletions
diff --git a/source/Items/ItemBed.h b/source/Items/ItemBed.h
new file mode 100644
index 000000000..b49df65a3
--- /dev/null
+++ b/source/Items/ItemBed.h
@@ -0,0 +1,25 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../World.h"
+
+class cItemBedHandler : public cItemHandler
+{
+public:
+ cItemBedHandler(int a_ItemID)
+ : cItemHandler(a_ItemID)
+ {
+
+ }
+
+ virtual bool IsPlaceable() override
+ {
+ return true;
+ }
+
+ virtual BLOCKTYPE GetBlockType() override
+ {
+ return E_BLOCK_BED;
+ }
+}; \ No newline at end of file
diff --git a/source/Items/ItemBucket.h b/source/Items/ItemBucket.h
new file mode 100644
index 000000000..736112960
--- /dev/null
+++ b/source/Items/ItemBucket.h
@@ -0,0 +1,94 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../World.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) override
+ {
+ switch(m_ItemID)
+ {
+ case E_ITEM_BUCKET:
+ {
+ if (a_Dir >= 0)
+ {
+ 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;
+ }
+ }
+ cItem Item(a_Item->m_ItemID, 1);
+ if (
+ (NewItem != E_ITEM_EMPTY) &&
+ (
+ ((a_Player->GetGameMode() == 1) ||
+ a_Player->GetInventory().RemoveItem(Item))
+ )
+ )
+ {
+ // Give New Bucket
+ cItem Item(NewItem, 1);
+ a_Player->GetInventory().AddItem(Item);
+ // Remove water / lava 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;
+ if (a_Dir >= 0)
+ {
+ AddDirection(a_X, a_Y, a_Z, a_Dir);
+ }
+ if(a_World->GetBlock(a_X, a_Y, a_Z) == E_BLOCK_AIR)
+ {
+ cItem Item(a_Item->m_ItemID, 1);
+ if ((a_Player->GetGameMode() == 1) || (a_Player->GetInventory().RemoveItem(Item)))
+ {
+ a_World->SetBlock(a_X, a_Y, a_Z, NewBlock, 0);
+
+ if (a_Player->GetGameMode() == 1)
+ {
+ break; //No new Bucket for creative players
+ }
+ cItem Item(E_ITEM_BUCKET, 1);
+ a_Player->GetInventory().AddItem(Item);
+ 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..5de064397
--- /dev/null
+++ b/source/Items/ItemCloth.h
@@ -0,0 +1,23 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+
+
+
+
+
+class cItemClothHandler :
+ public cItemHandler
+{
+public:
+ cItemClothHandler(int a_ItemID)
+ : cItemHandler(a_ItemID)
+ {
+
+ }
+} ;
+
+
+
+
diff --git a/source/Items/ItemDoor.h b/source/Items/ItemDoor.h
new file mode 100644
index 000000000..6e841333f
--- /dev/null
+++ b/source/Items/ItemDoor.h
@@ -0,0 +1,26 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../World.h"
+
+class cItemDoorHandler : public cItemHandler
+{
+public:
+ cItemDoorHandler(int a_ItemID)
+ : cItemHandler(a_ItemID)
+ {
+
+ }
+
+ virtual bool IsPlaceable() override
+ {
+ return true;
+ }
+
+ virtual BLOCKTYPE GetBlockType() override
+ {
+ 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..5b21a501c
--- /dev/null
+++ b/source/Items/ItemDye.h
@@ -0,0 +1,35 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../World.h"
+#include "../Player.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) override
+ {
+ // 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)
+ {
+ cItem Item(a_Item->m_ItemID, 1, a_Item->m_ItemHealth);
+ a_Player->GetInventory().RemoveItem(Item);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}; \ No newline at end of file
diff --git a/source/Items/ItemFood.h b/source/Items/ItemFood.h
new file mode 100644
index 000000000..6e5a27d5d
--- /dev/null
+++ b/source/Items/ItemFood.h
@@ -0,0 +1,56 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+
+
+class cItemFoodHandler : public cItemHandler
+{
+public:
+ cItemFoodHandler(int a_ItemID)
+ : cItemHandler(a_ItemID)
+ {
+ }
+
+ virtual bool IsFood() override
+ {
+ return true;
+ }
+
+ virtual FoodInfo GetFoodInfo() override
+ {
+ switch(m_ItemID)
+ {
+ case E_ITEM_BREAD:
+ return FoodInfo(5, 6.f);
+ case E_ITEM_COOKIE:
+ return FoodInfo(2, 0.4f);
+ case E_ITEM_MELON_SLICE:
+ return FoodInfo(2, 1.2f);
+ case E_ITEM_RAW_CHICKEN:
+ return FoodInfo(2, 1.2f, 30);
+ case E_ITEM_COOKED_CHICKEN:
+ return FoodInfo(6, 7.2f);
+ case E_ITEM_RAW_BEEF:
+ case E_ITEM_RAW_MEAT:
+ return FoodInfo(3, 1.8f);
+ case E_ITEM_STEAK:
+ case E_ITEM_COOKED_MEAT:
+ return FoodInfo(8, 12.8f);
+ case E_ITEM_RAW_FISH:
+ return FoodInfo(2, 1.2f);
+ case E_ITEM_COOKED_FISH:
+ return FoodInfo(5, 6.f);
+ case E_ITEM_RED_APPLE:
+ return FoodInfo(4, 2.4f);
+ case E_ITEM_GOLDEN_APPLE:
+ return FoodInfo(4, 9.6f);
+ case E_ITEM_ROTTEN_FLESH:
+ return FoodInfo(4, 0.8f, 80);
+ case E_ITEM_SPIDER_EYE:
+ return FoodInfo(2, 3.2f, 100);
+ }
+ return FoodInfo(0, 0.f);
+ }
+
+}; \ No newline at end of file
diff --git a/source/Items/ItemHandler.cpp b/source/Items/ItemHandler.cpp
new file mode 100644
index 000000000..49ed865e7
--- /dev/null
+++ b/source/Items/ItemHandler.cpp
@@ -0,0 +1,422 @@
+
+#include "Globals.h"
+#include "ItemHandler.h"
+#include "../Item.h"
+#include "../World.h"
+#include "../Player.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 "ItemRedstoneRepeater.h"
+#include "ItemSeeds.h"
+#include "ItemDye.h"
+#include "ItemSugarcane.h"
+#include "ItemPickaxe.h"
+#include "ItemShovel.h"
+#include "ItemSword.h"
+#include "ItemDoor.h"
+#include "ItemFood.h"
+#include "ItemSign.h"
+#include "ItemBed.h"
+
+#include "../Blocks/BlockHandler.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)
+ {
+ default: return new cItemHandler(a_ItemID);
+
+ // Single item per handler:
+ 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_DYE: return new cItemDyeHandler(a_ItemID);
+ case E_ITEM_SUGARCANE: return new cItemSugarcaneHandler(a_ItemID);
+ case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemID);
+ case E_ITEM_REDSTONE_DUST: return new cItemRedstoneDustHandler(a_ItemID);
+ case E_ITEM_REDSTONE_REPEATER: return new cItemRedstoneRepeaterHandler(a_ItemID);
+ case E_ITEM_WOOL: return new cItemClothHandler(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_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_STONE_SLAB:
+ case E_ITEM_WOODEN_SLAB:
+ {
+ return new cItemSlabHandler(a_ItemID);
+ }
+
+ case E_ITEM_LOG:
+ case E_ITEM_PLANKS:
+ {
+ return new cItemWoodHandler(a_ItemID);
+ }
+
+ case E_ITEM_BUCKET:
+ case E_ITEM_WATER_BUCKET:
+ case E_ITEM_LAVA_BUCKET:
+ {
+ return new cItemBucketHandler(a_ItemID);
+ }
+
+ case E_ITEM_PUMPKIN_SEEDS:
+ case E_ITEM_MELON_SEEDS:
+ case E_ITEM_SEEDS:
+ {
+ return new cItemSeedsHandler(a_ItemID);
+ }
+
+ case E_ITEM_IRON_DOOR:
+ case E_ITEM_WOODEN_DOOR:
+ {
+ return new cItemDoorHandler(a_ItemID);
+ }
+
+ // Food:
+ case E_ITEM_BREAD:
+ case E_ITEM_COOKIE:
+ case E_ITEM_MELON_SLICE:
+ case E_ITEM_RAW_CHICKEN:
+ case E_ITEM_COOKED_CHICKEN:
+ case E_ITEM_RAW_BEEF:
+ case E_ITEM_RAW_MEAT:
+ case E_ITEM_STEAK:
+ case E_ITEM_COOKED_MEAT:
+ case E_ITEM_RAW_FISH:
+ case E_ITEM_COOKED_FISH:
+ case E_ITEM_RED_APPLE:
+ case E_ITEM_GOLDEN_APPLE:
+ case E_ITEM_ROTTEN_FLESH:
+ case E_ITEM_SPIDER_EYE:
+ {
+ return new cItemFoodHandler(a_ItemID);
+ }
+
+ case E_ITEM_SIGN:
+ return new cItemSignHandler(a_ItemID);
+
+ case E_ITEM_BED:
+ return new cItemBedHandler(a_ItemID);
+ }
+}
+
+
+
+
+
+void cItemHandler::Deinit()
+{
+ for(int i = 0; i < 2266; i++)
+ {
+ delete m_ItemHandler[i];
+ }
+ m_HandlerInitialized = false;
+}
+
+
+
+
+
+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)
+{
+
+}
+
+
+
+
+
+char cItemHandler::GetMaxStackSize(void)
+{
+ if (m_ItemID < 256)
+ {
+ // All blocks can stack up to 64
+ return 64;
+ }
+
+ switch (m_ItemID)
+ {
+ case E_ITEM_APPLE: return 64;
+ case E_ITEM_ARROW: return 64;
+ case E_ITEM_BLAZE_POWDER: return 64;
+ case E_ITEM_BLAZE_ROD: return 64;
+ case E_ITEM_BONE: return 64;
+ case E_ITEM_BOOK: return 64;
+ case E_ITEM_BOWL: return 64;
+ case E_ITEM_BREAD: return 64;
+ case E_ITEM_BROWN_MUSHROOM: return 64;
+ case E_ITEM_BUCKET: return 1; // TODO: change this to 16 when turning compatibility to 1.3
+ case E_ITEM_COAL: return 64;
+ case E_ITEM_COOKED_CHICKEN: return 64;
+ case E_ITEM_COOKED_FISH: return 64;
+ case E_ITEM_COOKED_PORKCHOP: return 64;
+ case E_ITEM_DIAMOND: return 64;
+ case E_ITEM_FEATHER: return 64;
+ case E_ITEM_FLINT: return 64;
+ case E_ITEM_GOLD: return 64;
+ case E_ITEM_GUNPOWDER: return 64;
+ case E_ITEM_IRON: return 64;
+ case E_ITEM_RAW_PORKCHOP: return 64;
+ case E_ITEM_SEEDS: return 64;
+ case E_ITEM_STICK: return 64;
+ case E_ITEM_STRING: return 64;
+ case E_ITEM_WHEAT: return 64;
+ }
+ // By default items don't stack:
+ return 1;
+}
+
+
+
+
+
+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()
+{
+ ASSERT(m_ItemID < 256); // Items with IDs above 255 should all be handled by specific handlers
+
+ #ifdef _DEBUG
+ if (m_ItemID > 256)
+ {
+ LOGERROR("Item %d has no valid block!", m_ItemID);
+ }
+ #endif // _DEBUG
+
+ return (BLOCKTYPE) m_ItemID;
+}
+
+
+
+
+
+NIBBLETYPE cItemHandler::GetBlockMeta(short a_ItemDamage)
+{
+ return (NIBBLETYPE)a_ItemDamage & 0x0f; // 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)
+ {
+ cItem Item(a_Item->m_ItemID, 1);
+ a_Player->GetInventory().RemoveItem(Item);
+ }
+}
+
+
+
+
+
+bool cItemHandler::EatItem(cPlayer *a_Player, cItem *a_Item)
+{
+ FoodInfo Info = GetFoodInfo();
+
+ if(Info.FoodLevel > 0 || Info.Saturation > 0.f)
+ {
+ bool Success = a_Player->Feed(Info.FoodLevel, Info.Saturation);
+ if(Success && Info.PoisionChance > 0)
+ {
+ MTRand r1;
+ if((r1.randInt(100) - Info.PoisionChance) <= 0)
+ { //Unlucky guy :D
+ //TODO: Make player ill
+ }
+ }
+
+ return Success;
+ }
+
+ return false;
+}
+
+
+
+
+
+cItemHandler::FoodInfo cItemHandler::GetFoodInfo()
+{
+ return FoodInfo(0, 0.f);
+}
+
+
+
+
diff --git a/source/Items/ItemHandler.h b/source/Items/ItemHandler.h
new file mode 100644
index 000000000..67935ecb4
--- /dev/null
+++ b/source/Items/ItemHandler.h
@@ -0,0 +1,83 @@
+
+#pragma once
+#include "../Defines.h"
+
+
+
+
+
+// fwd:
+class cWorld;
+class cPlayer;
+
+
+
+
+
+class cItemHandler
+{
+public:
+ cItemHandler(int a_ItemID);
+ // Called when the player tries to use the item. Return false to make the item unusable. DEFAULT: False
+ 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
+ // Called while the player diggs a block using this item
+ virtual bool OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, cItem * a_HeldItem, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace);
+ // Called when the player destroys a block using this item. This also calls the drop function for the destroyed block
+ virtual void OnBlockDestroyed(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z);
+ // Called after the player has eaten this item.
+ virtual void OnFoodEaten(cWorld *a_World, cPlayer *a_Player, cItem *a_Item);
+
+ /// Returns the maximum stack size for a given item
+ virtual char GetMaxStackSize(void);
+
+ struct FoodInfo
+ {
+ FoodInfo(short a_FoodLevel, float a_Saturation, char a_PoisionChance = 0)
+ {
+ FoodLevel = a_FoodLevel;
+ Saturation = a_Saturation;
+ PoisionChance = a_PoisionChance;
+ }
+ short FoodLevel;
+ float Saturation;
+ char PoisionChance; //0 - 100
+ };
+
+ // Returns the FoodInfo for this item. (FoodRecovery, Saturation and PoisionChance)
+ virtual FoodInfo GetFoodInfo();
+
+ // Lets the player eat a selected item. Returns true if the player ate the item
+ virtual bool EatItem(cPlayer *a_Player, cItem *a_Item);
+
+ // Places the current block and removes the item from the player inventory
+ virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir);
+
+ // Indicates if this item is a tool
+ virtual bool IsTool();
+ // Indicates if this item is food
+ virtual bool IsFood();
+ //Blocks simply get placed
+ virtual bool IsPlaceable();
+
+ // Returns the block type on placement
+ virtual BLOCKTYPE GetBlockType();
+ //Returns the block meta on placement
+ virtual NIBBLETYPE GetBlockMeta(short a_ItemDamage);
+ // Returns whether this tool/item can harvest a specific block (e.g. wooden pickaxe can harvest stone, but wood canīt) DEFAULT: False
+ 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/ItemHoe.h b/source/Items/ItemHoe.h
new file mode 100644
index 000000000..e7ea9135c
--- /dev/null
+++ b/source/Items/ItemHoe.h
@@ -0,0 +1,31 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../World.h"
+#include "../Player.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) override
+ {
+ 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..f96adb0b8
--- /dev/null
+++ b/source/Items/ItemLeaves.h
@@ -0,0 +1,27 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+
+
+
+
+
+class cItemLeavesHandler :
+ public cItemHandler
+{
+public:
+ cItemLeavesHandler(int a_ItemID)
+ : cItemHandler(a_ItemID)
+ {
+ }
+
+ virtual NIBBLETYPE GetBlockMeta(short a_ItemDamage) override
+ {
+ return (NIBBLETYPE)(a_ItemDamage & 0x0f) | 0x4; //0x4 bit set means this is a player-placed leaves block, not to be decayed
+ }
+} ;
+
+
+
+
diff --git a/source/Items/ItemLighter.h b/source/Items/ItemLighter.h
new file mode 100644
index 000000000..92279aafa
--- /dev/null
+++ b/source/Items/ItemLighter.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "ItemHandler.h"
+#include "../World.h"
+#include "../Player.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) override
+ {
+ 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..158aca44f
--- /dev/null
+++ b/source/Items/ItemPickaxe.h
@@ -0,0 +1,75 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../World.h"
+#include "../Player.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) override
+ {
+ 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;
+ }
+ return false;
+ }
+}; \ No newline at end of file
diff --git a/source/Items/ItemRedstoneDust.h b/source/Items/ItemRedstoneDust.h
new file mode 100644
index 000000000..1ce316d9e
--- /dev/null
+++ b/source/Items/ItemRedstoneDust.h
@@ -0,0 +1,36 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+
+
+
+
+
+class cItemRedstoneDustHandler : public cItemHandler
+{
+public:
+ cItemRedstoneDustHandler(int a_ItemID)
+ : cItemHandler(a_ItemID)
+ {
+ }
+
+ virtual bool IsPlaceable() override
+ {
+ return true;
+ }
+
+ virtual BLOCKTYPE GetBlockType() override
+ {
+ return E_BLOCK_REDSTONE_WIRE;
+ }
+
+ virtual NIBBLETYPE GetBlockMeta(short a_ItemDamage) override
+ {
+ return 0;
+ }
+} ;
+
+
+
+
diff --git a/source/Items/ItemRedstoneRepeater.h b/source/Items/ItemRedstoneRepeater.h
new file mode 100644
index 000000000..c31c2af53
--- /dev/null
+++ b/source/Items/ItemRedstoneRepeater.h
@@ -0,0 +1,36 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+
+
+
+
+
+class cItemRedstoneRepeaterHandler : public cItemHandler
+{
+public:
+ cItemRedstoneRepeaterHandler(int a_ItemID)
+ : cItemHandler(a_ItemID)
+ {
+ }
+
+ virtual bool IsPlaceable() override
+ {
+ return true;
+ }
+
+ virtual BLOCKTYPE GetBlockType() override
+ {
+ return ::E_BLOCK_REDSTONE_REPEATER_OFF;
+ }
+
+ virtual NIBBLETYPE GetBlockMeta(short a_ItemMeta) override
+ {
+ return 0;
+ }
+} ;
+
+
+
+
diff --git a/source/Items/ItemSapling.h b/source/Items/ItemSapling.h
new file mode 100644
index 000000000..b0c223f29
--- /dev/null
+++ b/source/Items/ItemSapling.h
@@ -0,0 +1,28 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+
+
+
+
+
+class cItemSaplingHandler : public cItemHandler
+{
+public:
+ cItemSaplingHandler(int a_ItemID)
+ : cItemHandler(a_ItemID)
+ {
+
+ }
+
+ virtual NIBBLETYPE GetBlockMeta(short a_ItemDamage) override
+ {
+ // Only the lowest 3 bits are important
+ return (NIBBLETYPE)(a_ItemDamage & 0x07);
+ }
+} ;
+
+
+
+
diff --git a/source/Items/ItemSeeds.h b/source/Items/ItemSeeds.h
new file mode 100644
index 000000000..3eb9d6e86
--- /dev/null
+++ b/source/Items/ItemSeeds.h
@@ -0,0 +1,59 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../World.h"
+
+
+
+
+
+class cItemSeedsHandler :
+ public cItemHandler
+{
+public:
+ cItemSeedsHandler(int a_ItemID)
+ : cItemHandler(a_ItemID)
+ {
+
+ }
+
+ virtual bool IsPlaceable() override
+ {
+ return true;
+ }
+
+ virtual BLOCKTYPE GetBlockType() override
+ {
+ switch(m_ItemID)
+ {
+ case E_ITEM_SEEDS: return E_BLOCK_CROPS;
+ case E_ITEM_MELON_SEEDS: return E_BLOCK_MELON_STEM;
+ case E_ITEM_PUMPKIN_SEEDS: return E_BLOCK_PUMPKIN_STEM;
+ default: return E_BLOCK_AIR;
+ }
+ }
+
+ virtual NIBBLETYPE GetBlockMeta(short a_ItemDamage) override
+ {
+ 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) override
+ {
+ 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);
+ }
+} ;
+
+
+
+
diff --git a/source/Items/ItemShears.h b/source/Items/ItemShears.h
new file mode 100644
index 000000000..2f3476735
--- /dev/null
+++ b/source/Items/ItemShears.h
@@ -0,0 +1,42 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../World.h"
+#include "../Player.h"
+
+class cItemShearsHandler : public cItemHandler
+{
+public:
+ cItemShearsHandler(int a_ItemID)
+ : cItemHandler(a_ItemID)
+ {
+
+ }
+ virtual bool IsTool() override
+ {
+ 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) override
+ {
+ 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..f5a65795a
--- /dev/null
+++ b/source/Items/ItemShovel.h
@@ -0,0 +1,41 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../World.h"
+#include "../Player.h"
+
+#include "../Blocks/BlockHandler.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) override
+ {
+ return a_BlockID == E_BLOCK_SNOW;
+ }
+}; \ No newline at end of file
diff --git a/source/Items/ItemSign.h b/source/Items/ItemSign.h
new file mode 100644
index 000000000..a0c6aaa9c
--- /dev/null
+++ b/source/Items/ItemSign.h
@@ -0,0 +1,26 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../World.h"
+
+class cItemSignHandler : public cItemHandler
+{
+public:
+ cItemSignHandler(int a_ItemID)
+ : cItemHandler(a_ItemID)
+ {
+
+ }
+
+ virtual bool IsPlaceable() override
+ {
+ return true;
+ }
+
+ virtual BLOCKTYPE GetBlockType() override
+ {
+ return E_BLOCK_SIGN_POST;
+ }
+
+}; \ No newline at end of file
diff --git a/source/Items/ItemSlab.h b/source/Items/ItemSlab.h
new file mode 100644
index 000000000..0bab038a2
--- /dev/null
+++ b/source/Items/ItemSlab.h
@@ -0,0 +1,45 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../World.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) override
+ {
+ 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
+ {
+ cItem Item(a_Item->m_ItemID, 1);
+ if (a_Player->GetInventory().RemoveItem(Item))
+ {
+ 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;
+ }
+} ;
+
+
+
+
diff --git a/source/Items/ItemSugarcane.h b/source/Items/ItemSugarcane.h
new file mode 100644
index 000000000..4fdf43428
--- /dev/null
+++ b/source/Items/ItemSugarcane.h
@@ -0,0 +1,39 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../World.h"
+
+
+
+
+
+class cItemSugarcaneHandler :
+ public cItemHandler
+{
+public:
+ cItemSugarcaneHandler(int a_ItemID)
+ : cItemHandler(a_ItemID)
+ {
+
+ }
+
+ virtual bool IsPlaceable() override
+ {
+ return true;
+ }
+
+ virtual BLOCKTYPE GetBlockType() override
+ {
+ return E_BLOCK_SUGARCANE;
+ }
+
+ virtual NIBBLETYPE GetBlockMeta(short a_ItemDamage) override
+ {
+ return 0; //Not grown yet
+ }
+} ;
+
+
+
+
diff --git a/source/Items/ItemSword.h b/source/Items/ItemSword.h
new file mode 100644
index 000000000..eb4aa0ef9
--- /dev/null
+++ b/source/Items/ItemSword.h
@@ -0,0 +1,21 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../World.h"
+#include "../Player.h"
+
+class cItemSwordHandler : public cItemHandler
+{
+public:
+ cItemSwordHandler(int a_ItemID)
+ : cItemHandler(a_ItemID)
+ {
+
+ }
+
+ virtual bool CanHarvestBlock(BLOCKTYPE a_BlockID) override
+ {
+ 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..d6f66d1c5
--- /dev/null
+++ b/source/Items/ItemWood.h
@@ -0,0 +1,22 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+
+
+
+
+
+class cItemWoodHandler :
+ public cItemHandler
+{
+public:
+ cItemWoodHandler(int a_ItemID)
+ : cItemHandler(a_ItemID)
+ {
+ }
+} ;
+
+
+
+