1
0

cBlockInfo now manages the respective cBlockHandler

This commit is contained in:
andrew 2014-03-02 21:25:05 +02:00
parent 7fb354e8f0
commit 070d483236
11 changed files with 70 additions and 73 deletions

View File

@ -2,6 +2,7 @@
#include "Globals.h"
#include "BlockInfo.h"
#include "Blocks/BlockHandler.h"
@ -23,12 +24,25 @@ cBlockInfo::cBlockInfo()
, m_RequiresSpecialTool(false)
, m_IsSolid(true)
, m_FullyOccupiesVoxel(false)
, m_Handler(NULL)
{}
cBlockInfo::~cBlockInfo()
{
if (m_Handler != NULL)
{
delete m_Handler;
}
}
cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type)
{
ASSERT(a_Type < 256);
@ -42,6 +56,14 @@ cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type)
void cBlockInfo::Initialize(void)
{
for (unsigned int i = 0; i < 256; ++i)
{
if (ms_Info[i].m_Handler == NULL)
{
ms_Info[i].m_Handler = cBlockHandler::CreateBlockHandler((BLOCKTYPE) i);
}
}
// Emissive blocks
ms_Info[E_BLOCK_FIRE ].m_LightValue = 15;
ms_Info[E_BLOCK_GLOWSTONE ].m_LightValue = 15;

View File

@ -5,6 +5,13 @@
// fwd:
class cBlockHandler;
// tolua_begin
class cBlockInfo
{
@ -13,6 +20,8 @@ public:
cBlockInfo();
~cBlockInfo();
/** (Re-)Initializes the internal BlockInfo structures. */
static void Initialize(void);
@ -49,6 +58,12 @@ public:
/** Does this block fully occupy its voxel - is it a 'full' block? */
bool m_FullyOccupiesVoxel;
// tolua_end
/** Associated block handler. */
cBlockHandler * m_Handler;
// tolua_begin
inline static NIBBLETYPE GetLightValue (BLOCKTYPE a_Type) { return Get(a_Type).m_LightValue; }
inline static NIBBLETYPE GetSpreadLightFalloff(BLOCKTYPE a_Type) { return Get(a_Type).m_SpreadLightFalloff; }
@ -62,6 +77,8 @@ public:
// tolua_end
inline static cBlockHandler * GetHandler (BLOCKTYPE a_Type) { return Get(a_Type).m_Handler; }
protected:
@ -74,3 +91,13 @@ protected:
// Shortcut to get the blockhandler for a specific block
inline cBlockHandler * BlockHandler(BLOCKTYPE a_BlockType)
{
return cBlockInfo::Get(a_BlockType).m_Handler;
}

View File

@ -77,33 +77,6 @@
bool cBlockHandler::m_HandlerInitialized = false;
cBlockHandler * cBlockHandler::m_BlockHandler[256];
cBlockHandler * cBlockHandler::GetBlockHandler(BLOCKTYPE a_BlockType)
{
if (!m_HandlerInitialized)
{
// We have to initialize
memset(m_BlockHandler, 0, sizeof(m_BlockHandler));
m_HandlerInitialized = true;
}
if (m_BlockHandler[a_BlockType] != NULL)
{
return m_BlockHandler[a_BlockType];
}
return m_BlockHandler[a_BlockType] = CreateBlockHandler(a_BlockType);
}
cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
{
switch(a_BlockType)
@ -192,7 +165,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_REDSTONE_REPEATER_ON: return new cBlockRedstoneRepeaterHandler(a_BlockType);
case E_BLOCK_REDSTONE_TORCH_OFF: return new cBlockRedstoneTorchHandler (a_BlockType);
case E_BLOCK_REDSTONE_TORCH_ON: return new cBlockRedstoneTorchHandler (a_BlockType);
case E_BLOCK_REDSTONE_WIRE: return new cBlockRedstoneHandler (a_BlockType);
case E_BLOCK_REDSTONE_WIRE: return new cBlockRedstoneHandler (a_BlockType);
case E_BLOCK_RED_MUSHROOM: return new cBlockMushroomHandler (a_BlockType);
case E_BLOCK_RED_ROSE: return new cBlockFlowerHandler (a_BlockType);
case E_BLOCK_SAND: return new cBlockSandHandler (a_BlockType);
@ -231,20 +204,6 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
void cBlockHandler::Deinit()
{
for (int i = 0; i < 256; i++)
{
delete m_BlockHandler[i];
}
memset(m_BlockHandler, 0, sizeof(m_BlockHandler)); // Don't leave any dangling pointers around, just in case
m_HandlerInitialized = false;
}
cBlockHandler::cBlockHandler(BLOCKTYPE a_BlockType)
{
m_BlockType = a_BlockType;
@ -329,7 +288,7 @@ void cBlockHandler::NeighborChanged(cChunkInterface & a_ChunkInterface, int a_Bl
{
if ((a_BlockY >= 0) && (a_BlockY < cChunkDef::Height))
{
GetBlockHandler(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnNeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
cBlockInfo::GetHandler(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnNeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
}
}

View File

@ -136,31 +136,15 @@ public:
/// <returns>Block meta following mirroring</returns>
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) { return a_Meta; }
/// <summary>Get the blockhandler for a specific block id</summary>
static cBlockHandler * GetBlockHandler(BLOCKTYPE a_BlockType);
/// <summary>Deletes all initialised block handlers</summary>
static void Deinit();
protected:
BLOCKTYPE m_BlockType;
// Creates a new blockhandler for the given block type. For internal use only, use ::GetBlockHandler() instead.
static cBlockHandler *CreateBlockHandler(BLOCKTYPE a_BlockType);
static cBlockHandler *m_BlockHandler[256];
static bool m_HandlerInitialized; //used to detect if the blockhandlers are initialized
static cBlockHandler * CreateBlockHandler(BLOCKTYPE a_BlockType);
friend class cBlockInfo;
};
// Shortcut to get the blockhandler for a specific block
inline cBlockHandler * BlockHandler(BLOCKTYPE a_BlockType)
{
return cBlockHandler::GetBlockHandler(a_BlockType);
}

View File

@ -6,7 +6,7 @@
bool cChunkInterface::DigBlock(cWorldInterface & a_WorldInterface, int a_X, int a_Y, int a_Z)
{
cBlockHandler *Handler = cBlockHandler::GetBlockHandler(GetBlock(a_X, a_Y, a_Z));
cBlockHandler * Handler = cBlockInfo::GetHandler(GetBlock(a_X, a_Y, a_Z));
Handler->OnDestroyed(*this, a_WorldInterface, a_X, a_Y, a_Z);
return m_ChunkMap->DigBlock(a_X, a_Y, a_Z);
}

View File

@ -838,7 +838,7 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
cWorld * World = m_Player->GetWorld();
cChunkInterface ChunkInterface(World->GetChunkMap());
cBlockHandler * Handler = cBlockHandler::GetBlockHandler(a_OldBlock);
cBlockHandler * Handler = cBlockInfo::GetHandler(a_OldBlock);
Handler->OnDigging(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ);
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
@ -852,7 +852,7 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
int pZ = a_BlockZ;
AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false)
Handler = cBlockHandler::GetBlockHandler(World->GetBlock(pX, pY, pZ));
Handler = cBlockInfo::GetHandler(World->GetBlock(pX, pY, pZ));
if (Handler->IsClickedThrough())
{
@ -963,7 +963,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta);
cBlockHandler * BlockHandler = cBlockHandler::GetBlockHandler(BlockType);
cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType);
if (BlockHandler->IsUseable() && !m_Player->IsCrouched())
{

View File

@ -285,7 +285,7 @@ void cItemHandler::OnBlockDestroyed(cWorld * a_World, cPlayer * a_Player, const
UNUSED(a_Item);
BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
cBlockHandler * Handler = cBlockHandler::GetBlockHandler(Block);
cBlockHandler * Handler = cBlockInfo::GetHandler(Block);
if (a_Player->IsGameModeSurvival())
{

View File

@ -150,7 +150,7 @@ void cVillager::HandleFarmerTryHarvestCrops()
BLOCKTYPE CropBlock = m_World->GetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z);
if (IsBlockFarmable(CropBlock) && m_World->GetBlockMeta(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z) == 0x7)
{
cBlockHandler * Handler = cBlockHandler::GetBlockHandler(CropBlock);
cBlockHandler * Handler = cBlockInfo::GetHandler(CropBlock);
cChunkInterface ChunkInterface(m_World->GetChunkMap());
cBlockInServerPluginInterface PluginInterface(*m_World);
Handler->DropBlock(ChunkInterface, *m_World, PluginInterface, this, m_CropsPos.x, m_CropsPos.y, m_CropsPos.z);

View File

@ -245,7 +245,6 @@ void cRoot::Start(void)
delete m_PluginManager; m_PluginManager = NULL;
cItemHandler::Deinit();
cBlockHandler::Deinit();
LOG("Cleaning up...");
delete m_Server; m_Server = NULL;

View File

@ -312,12 +312,18 @@ bool cScoreboard::RemoveObjective(const AString & a_Name)
return false;
}
m_Objectives.erase(it);
ASSERT(m_World != NULL);
m_World->BroadcastScoreboardObjective(it->second.GetName(), it->second.GetDisplayName(), 1);
// TODO 2014-03-01 xdot: Remove objective from display slot
for (unsigned int i = 0; i < (unsigned int) dsCount; ++i)
{
if (m_Display[i] == &it->second)
{
SetDisplay(NULL, (eDisplaySlot) i);
}
}
m_Objectives.erase(it);
return true;
}

View File

@ -1723,7 +1723,7 @@ bool cWorld::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure)
bool cWorld::DigBlock(int a_X, int a_Y, int a_Z)
{
cBlockHandler *Handler = cBlockHandler::GetBlockHandler(GetBlock(a_X, a_Y, a_Z));
cBlockHandler * Handler = cBlockInfo::GetHandler(GetBlock(a_X, a_Y, a_Z));
cChunkInterface ChunkInterface(GetChunkMap());
Handler->OnDestroyed(ChunkInterface, *this, a_X, a_Y, a_Z);
return m_ChunkMap->DigBlock(a_X, a_Y, a_Z);