1
0

Merge pull request #748 from xdot/master

cBlockInfo now manages the respective cBlockHandler
This commit is contained in:
Mattes D 2014-03-02 22:03:44 +01:00
commit d25e4d4179
11 changed files with 67 additions and 73 deletions

View File

@ -2,6 +2,7 @@
#include "Globals.h" #include "Globals.h"
#include "BlockInfo.h" #include "BlockInfo.h"
#include "Blocks/BlockHandler.h"
@ -23,12 +24,22 @@ cBlockInfo::cBlockInfo()
, m_RequiresSpecialTool(false) , m_RequiresSpecialTool(false)
, m_IsSolid(true) , m_IsSolid(true)
, m_FullyOccupiesVoxel(false) , m_FullyOccupiesVoxel(false)
, m_Handler(NULL)
{} {}
cBlockInfo::~cBlockInfo()
{
delete m_Handler;
}
cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type) cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type)
{ {
ASSERT(a_Type < 256); ASSERT(a_Type < 256);
@ -42,6 +53,14 @@ cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type)
void cBlockInfo::Initialize(void) 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 // Emissive blocks
ms_Info[E_BLOCK_FIRE ].m_LightValue = 15; ms_Info[E_BLOCK_FIRE ].m_LightValue = 15;
ms_Info[E_BLOCK_GLOWSTONE ].m_LightValue = 15; ms_Info[E_BLOCK_GLOWSTONE ].m_LightValue = 15;

View File

@ -5,6 +5,13 @@
// fwd:
class cBlockHandler;
// tolua_begin // tolua_begin
class cBlockInfo class cBlockInfo
{ {
@ -13,6 +20,8 @@ public:
cBlockInfo(); cBlockInfo();
~cBlockInfo();
/** (Re-)Initializes the internal BlockInfo structures. */ /** (Re-)Initializes the internal BlockInfo structures. */
static void Initialize(void); static void Initialize(void);
@ -49,6 +58,12 @@ public:
/** Does this block fully occupy its voxel - is it a 'full' block? */ /** Does this block fully occupy its voxel - is it a 'full' block? */
bool m_FullyOccupiesVoxel; 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 GetLightValue (BLOCKTYPE a_Type) { return Get(a_Type).m_LightValue; }
inline static NIBBLETYPE GetSpreadLightFalloff(BLOCKTYPE a_Type) { return Get(a_Type).m_SpreadLightFalloff; } inline static NIBBLETYPE GetSpreadLightFalloff(BLOCKTYPE a_Type) { return Get(a_Type).m_SpreadLightFalloff; }
@ -62,6 +77,8 @@ public:
// tolua_end // tolua_end
inline static cBlockHandler * GetHandler (BLOCKTYPE a_Type) { return Get(a_Type).m_Handler; }
protected: 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) cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
{ {
switch(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_REPEATER_ON: return new cBlockRedstoneRepeaterHandler(a_BlockType);
case E_BLOCK_REDSTONE_TORCH_OFF: return new cBlockRedstoneTorchHandler (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_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_MUSHROOM: return new cBlockMushroomHandler (a_BlockType);
case E_BLOCK_RED_ROSE: return new cBlockFlowerHandler (a_BlockType); case E_BLOCK_RED_ROSE: return new cBlockFlowerHandler (a_BlockType);
case E_BLOCK_SAND: return new cBlockSandHandler (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) cBlockHandler::cBlockHandler(BLOCKTYPE a_BlockType)
{ {
m_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)) 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> /// <returns>Block meta following mirroring</returns>
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) { return a_Meta; } 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: protected:
BLOCKTYPE m_BlockType; BLOCKTYPE m_BlockType;
// Creates a new blockhandler for the given block type. For internal use only, use ::GetBlockHandler() instead. // Creates a new blockhandler for the given block type. For internal use only, use ::GetBlockHandler() instead.
static cBlockHandler *CreateBlockHandler(BLOCKTYPE a_BlockType); static cBlockHandler * CreateBlockHandler(BLOCKTYPE a_BlockType);
static cBlockHandler *m_BlockHandler[256];
static bool m_HandlerInitialized; //used to detect if the blockhandlers are initialized 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) 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); Handler->OnDestroyed(*this, a_WorldInterface, a_X, a_Y, a_Z);
return m_ChunkMap->DigBlock(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(); cWorld * World = m_Player->GetWorld();
cChunkInterface ChunkInterface(World->GetChunkMap()); 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); Handler->OnDigging(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ);
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem()); 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; int pZ = a_BlockZ;
AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false) 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()) if (Handler->IsClickedThrough())
{ {
@ -963,7 +963,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
BLOCKTYPE BlockType; BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta; NIBBLETYPE BlockMeta;
World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, 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()) 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); UNUSED(a_Item);
BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); 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()) 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); 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) 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()); cChunkInterface ChunkInterface(m_World->GetChunkMap());
cBlockInServerPluginInterface PluginInterface(*m_World); cBlockInServerPluginInterface PluginInterface(*m_World);
Handler->DropBlock(ChunkInterface, *m_World, PluginInterface, this, m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); 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; delete m_PluginManager; m_PluginManager = NULL;
cItemHandler::Deinit(); cItemHandler::Deinit();
cBlockHandler::Deinit();
LOG("Cleaning up..."); LOG("Cleaning up...");
delete m_Server; m_Server = NULL; delete m_Server; m_Server = NULL;

View File

@ -312,12 +312,18 @@ bool cScoreboard::RemoveObjective(const AString & a_Name)
return false; return false;
} }
m_Objectives.erase(it);
ASSERT(m_World != NULL); ASSERT(m_World != NULL);
m_World->BroadcastScoreboardObjective(it->second.GetName(), it->second.GetDisplayName(), 1); 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; 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) 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()); cChunkInterface ChunkInterface(GetChunkMap());
Handler->OnDestroyed(ChunkInterface, *this, a_X, a_Y, a_Z); Handler->OnDestroyed(ChunkInterface, *this, a_X, a_Y, a_Z);
return m_ChunkMap->DigBlock(a_X, a_Y, a_Z); return m_ChunkMap->DigBlock(a_X, a_Y, a_Z);