summaryrefslogblamecommitdiffstats
path: root/source/Items/ItemHandler.cpp
blob: 021794f8468656ad75034bed74485849d9fda578 (plain) (tree)
1
2
3
4
5
6
 
                     



                         











                              
                                  






                           
                      
                      
                     
                          
 
                                    
 



 
                                                 




                                                  
 
                                                           
  
                                           





                                                                 



                                                                   

  



 
                                                              
  
                           
          
                                                                                    
                 
                                                                   











                                                                                                    






                                         
                                                                







                                             
                                                                    







                                            
                                                                   







                                           
                                                                  




                                         
                                                                 




                                    
                                                                 





                                          
                                                                   





                                           
                                                                  




                                         
                                                                 


















                                            
                                                                 
                  


          



 





                                         
                                      

  



 
                                           
  
                                 

  



 
                                                                                                                                         



                      



 
                                                                                                                                              



                      



 















                                                                                                                  



 




                                                                                  



 

                                         
                              




                                                 
                            
          
























                                                                                                                     
          







                                         


                            







                                                            

  



 


                            








                                                             

  



 

                                 
                                                     


  


 
                                                          



                      



 

                                       
                                                                                                          

                      
                              
          
                                                                     
          

                          
                                       

  




                                                          
  
                                                                                                                        

  



 
                                                                                                                                       


                                                                        
                                                                                                                         
                                                          
          
                                                   

                                                           

  



 





















                                                                                



 


                                                   




  

#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 "ItemSpawnEgg.h"

#include "../Blocks/BlockHandler.h"





bool cItemHandler::m_HandlerInitialized = false;
cItemHandler * cItemHandler::m_ItemHandler[2266];





cItemHandler *cItemHandler::GetItemHandler(int a_ItemType)
{
	if(a_ItemType < 0) a_ItemType = 0;

	if(!m_HandlerInitialized)
	{	//We have to initialize
		memset(m_ItemHandler, 0, sizeof(m_ItemHandler));
		m_HandlerInitialized = true;
	}
	if(m_ItemHandler[a_ItemType])
		return m_ItemHandler[a_ItemType];
	m_ItemHandler[a_ItemType] = CreateItemHandler(a_ItemType);
	return m_ItemHandler[a_ItemType];
}





cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
{
	switch(a_ItemType)
	{
		default:                       return new cItemHandler(a_ItemType);
		
		// Single item per handler, alphabetically sorted:
		case E_ITEM_BED:               return new cItemBedHandler(a_ItemType);
		case E_ITEM_DYE:               return new cItemDyeHandler(a_ItemType);
		case E_ITEM_FLINT_AND_STEEL:   return new cItemLighterHandler(a_ItemType);
		case E_ITEM_LEAVES:            return new cItemLeavesHandler(a_ItemType);
		case E_ITEM_REDSTONE_DUST:     return new cItemRedstoneDustHandler(a_ItemType);
		case E_ITEM_REDSTONE_REPEATER: return new cItemRedstoneRepeaterHandler(a_ItemType);
		case E_ITEM_SAPLING:           return new cItemSaplingHandler(a_ItemType);
		case E_ITEM_SHEARS:            return new cItemShearsHandler(a_ItemType);
		case E_ITEM_SIGN:              return new cItemSignHandler(a_ItemType);
		case E_ITEM_SPAWN_EGG:         return new cItemSpawnEggHandler(a_ItemType);
		case E_ITEM_SUGARCANE:         return new cItemSugarcaneHandler(a_ItemType);
		case E_ITEM_WOOL:              return new cItemClothHandler(a_ItemType);
		
		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_ItemType);
		}
		
		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_ItemType);
		}
		
		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_ItemType);
		}
		
		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_ItemType);
		}
		
		case E_ITEM_STONE_SLAB:
		case E_ITEM_WOODEN_SLAB:
		{
			return new cItemSlabHandler(a_ItemType);
		}
		
		case E_ITEM_LOG:
		case E_ITEM_PLANKS:
		{
			return new cItemWoodHandler(a_ItemType);
		}
		
		case E_ITEM_BUCKET:
		case E_ITEM_WATER_BUCKET:
		case E_ITEM_LAVA_BUCKET:
		{
			return new cItemBucketHandler(a_ItemType);
		}
		
		case E_ITEM_PUMPKIN_SEEDS:
		case E_ITEM_MELON_SEEDS:
		case E_ITEM_SEEDS:
		{
			return new cItemSeedsHandler(a_ItemType);
		}
		
		case E_ITEM_IRON_DOOR:
		case E_ITEM_WOODEN_DOOR:
		{
			return new cItemDoorHandler(a_ItemType);
		}
		
		// 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_ItemType);
		}
	}
}





void cItemHandler::Deinit()
{
	for(int i = 0; i < 2266; i++)
	{
		delete m_ItemHandler[i];
	}
	m_HandlerInitialized = false;
}





cItemHandler::cItemHandler(int a_ItemType)
{
	m_ItemType = a_ItemType;
}





bool cItemHandler::OnItemUse(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir)
{
	return false;
}





bool cItemHandler::OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, 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_ItemType < 256)
	{
		// All blocks can stack up to 64
		return 64;
	}
	
	switch (m_ItemType)
	{
		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_ItemType >= 256 && m_ItemType <= 259)
		|| (m_ItemType == 261)
		|| (m_ItemType >= 267 && m_ItemType <= 279)
		|| (m_ItemType >= 283 && m_ItemType <= 286)
		|| (m_ItemType >= 290 && m_ItemType <= 294)
		|| (m_ItemType >= 256 && m_ItemType <= 259)
		|| (m_ItemType == 325)
		|| (m_ItemType == 346);
}





bool cItemHandler::IsFood()
{
	return 
		   (m_ItemType == 260)
		|| (m_ItemType == 282)
		|| (m_ItemType == 297)
		|| (m_ItemType >= 319 && m_ItemType <= 320)
		|| (m_ItemType == 335)
		|| (m_ItemType >= 349 && m_ItemType <= 350)
		|| (m_ItemType == 357)
		|| (m_ItemType == 360)
		|| (m_ItemType >= 363 && m_ItemType <= 366);
}





bool cItemHandler::IsPlaceable()
{
	return m_ItemType >= 1 && m_ItemType <= 136;
}





bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType)
{
	return false;
}





BLOCKTYPE cItemHandler::GetBlockType()
{
	ASSERT(m_ItemType < 256);  // Items with IDs above 255 should all be handled by specific handlers
	
	#ifdef _DEBUG
	if (m_ItemType > 256)
	{
		LOGERROR("Item %d has no valid block!", m_ItemType);
	}
	#endif  // _DEBUG
	
	return (BLOCKTYPE) m_ItemType;
}





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_BlockX, int a_BlockY, int a_BlockZ, char a_Dir)
{
	BLOCKTYPE Block = GetBlockType();
	cBlockHandler *Handler = cBlockHandler::GetBlockHandler(Block);
	Handler->PlaceBlock(a_World, a_Player, GetBlockMeta(a_Item->m_ItemHealth), a_BlockX, a_BlockY, a_BlockZ, a_Dir);
	if(a_Player->GetGameMode() == eGameMode_Survival)
	{
		cItem Item(a_Item->m_ItemType, 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);
}