Merge pull request #529 from mc-server/derpstonerefactor
Major refactoring of redstone
This commit is contained in:
commit
273db55bdf
126
src/BlockID.cpp
126
src/BlockID.cpp
@ -20,7 +20,7 @@ bool g_BlockPistonBreakable[256];
|
||||
bool g_BlockIsSnowable[256];
|
||||
bool g_BlockRequiresSpecialTool[256];
|
||||
bool g_BlockIsSolid[256];
|
||||
bool g_BlockIsTorchPlaceable[256];
|
||||
bool g_BlockFullyOccupiesVoxel[256];
|
||||
|
||||
|
||||
|
||||
@ -491,7 +491,7 @@ public:
|
||||
memset(g_BlockTransparent, 0x00, sizeof(g_BlockTransparent));
|
||||
memset(g_BlockOneHitDig, 0x00, sizeof(g_BlockOneHitDig));
|
||||
memset(g_BlockPistonBreakable, 0x00, sizeof(g_BlockPistonBreakable));
|
||||
memset(g_BlockIsTorchPlaceable, 0x00, sizeof(g_BlockIsTorchPlaceable));
|
||||
memset(g_BlockFullyOccupiesVoxel, 0x00, sizeof(g_BlockFullyOccupiesVoxel));
|
||||
|
||||
// Setting bools to true must be done manually, see http://forum.mc-server.org/showthread.php?tid=629&pid=5415#pid5415
|
||||
for (size_t i = 0; i < ARRAYCOUNT(g_BlockIsSnowable); i++)
|
||||
@ -791,67 +791,67 @@ public:
|
||||
g_BlockIsSolid[E_BLOCK_WOODEN_SLAB] = false;
|
||||
|
||||
// Torch placeable blocks:
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_BEDROCK] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_BLOCK_OF_COAL] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_BLOCK_OF_REDSTONE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_BOOKCASE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_BRICK] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_CLAY] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_COAL_ORE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_COBBLESTONE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_COMMAND_BLOCK] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_CRAFTING_TABLE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_DIAMOND_BLOCK] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_DIAMOND_ORE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_DIRT] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_DISPENSER] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_DOUBLE_STONE_SLAB] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_DOUBLE_WOODEN_SLAB] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_DROPPER] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_EMERALD_BLOCK] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_EMERALD_ORE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_END_STONE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_FURNACE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_GLOWSTONE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_GOLD_BLOCK] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_GOLD_ORE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_GRASS] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_GRAVEL] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_HARDENED_CLAY] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_HAY_BALE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_HUGE_BROWN_MUSHROOM] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_HUGE_RED_MUSHROOM] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_IRON_BLOCK] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_IRON_ORE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_JACK_O_LANTERN] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_JUKEBOX] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_LAPIS_BLOCK] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_LAPIS_ORE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_LOG] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_MELON] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_MOSSY_COBBLESTONE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_MYCELIUM] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_NETHERRACK] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_NETHER_BRICK] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_NETHER_QUARTZ_ORE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_NOTE_BLOCK] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_OBSIDIAN] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_PACKED_ICE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_PLANKS] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_PUMPKIN] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_QUARTZ_BLOCK] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_REDSTONE_LAMP_OFF] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_REDSTONE_LAMP_ON] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_REDSTONE_ORE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_REDSTONE_ORE_GLOWING] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_SANDSTONE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_SAND] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_SILVERFISH_EGG] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_SPONGE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_STAINED_CLAY] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_WOOL] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_STONE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_STONE_BRICKS] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_BEDROCK] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_BLOCK_OF_COAL] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_BLOCK_OF_REDSTONE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_BOOKCASE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_BRICK] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_CLAY] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_COAL_ORE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_COBBLESTONE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_COMMAND_BLOCK] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_CRAFTING_TABLE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_DIAMOND_BLOCK] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_DIAMOND_ORE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_DIRT] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_DISPENSER] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_DOUBLE_STONE_SLAB] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_DOUBLE_WOODEN_SLAB] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_DROPPER] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_EMERALD_BLOCK] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_EMERALD_ORE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_END_STONE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_FURNACE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_GLOWSTONE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_GOLD_BLOCK] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_GOLD_ORE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_GRASS] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_GRAVEL] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_HARDENED_CLAY] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_HAY_BALE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_HUGE_BROWN_MUSHROOM] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_HUGE_RED_MUSHROOM] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_IRON_BLOCK] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_IRON_ORE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_JACK_O_LANTERN] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_JUKEBOX] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_LAPIS_BLOCK] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_LAPIS_ORE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_LOG] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_MELON] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_MOSSY_COBBLESTONE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_MYCELIUM] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_NETHERRACK] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_NETHER_BRICK] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_NETHER_QUARTZ_ORE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_NOTE_BLOCK] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_OBSIDIAN] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_PACKED_ICE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_PLANKS] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_PUMPKIN] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_QUARTZ_BLOCK] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_REDSTONE_LAMP_OFF] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_REDSTONE_LAMP_ON] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_REDSTONE_ORE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_REDSTONE_ORE_GLOWING] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_SANDSTONE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_SAND] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_SILVERFISH_EGG] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_SPONGE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_STAINED_CLAY] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_WOOL] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_STONE] = true;
|
||||
g_BlockFullyOccupiesVoxel[E_BLOCK_STONE_BRICKS] = true;
|
||||
}
|
||||
} BlockPropertiesInitializer;
|
||||
|
||||
|
@ -906,7 +906,7 @@ extern bool g_BlockPistonBreakable[256];
|
||||
extern bool g_BlockIsSnowable[256];
|
||||
extern bool g_BlockRequiresSpecialTool[256];
|
||||
extern bool g_BlockIsSolid[256];
|
||||
extern bool g_BlockIsTorchPlaceable[256];
|
||||
extern bool g_BlockFullyOccupiesVoxel[256];
|
||||
|
||||
|
||||
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
|
||||
virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
|
||||
{
|
||||
return ((a_RelY > 0) && g_BlockIsTorchPlaceable[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]);
|
||||
return ((a_RelY > 0) && g_BlockFullyOccupiesVoxel[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]);
|
||||
}
|
||||
|
||||
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
|
||||
static bool CanBePlacedOn(BLOCKTYPE a_BlockType, char a_BlockFace)
|
||||
{
|
||||
if ( !g_BlockIsTorchPlaceable[a_BlockType] )
|
||||
if ( !g_BlockFullyOccupiesVoxel[a_BlockType] )
|
||||
{
|
||||
return (a_BlockFace == BLOCK_FACE_TOP); // Allow placement only when torch upright (for glass, etc.); exceptions won't even be sent by client, no need to handle
|
||||
}
|
||||
@ -127,7 +127,7 @@ public:
|
||||
{
|
||||
return i;
|
||||
}
|
||||
else if ((g_BlockIsTorchPlaceable[BlockInQuestion]) && (i != BLOCK_FACE_BOTTOM))
|
||||
else if ((g_BlockFullyOccupiesVoxel[BlockInQuestion]) && (i != BLOCK_FACE_BOTTOM))
|
||||
{
|
||||
// Otherwise, if block in that direction is torch placeable and we haven't gotten to it via the bottom face, return that face
|
||||
return i;
|
||||
@ -161,7 +161,7 @@ public:
|
||||
// No need to check for upright orientation, it was done when the torch was placed
|
||||
return true;
|
||||
}
|
||||
else if ( !g_BlockIsTorchPlaceable[BlockInQuestion] )
|
||||
else if ( !g_BlockFullyOccupiesVoxel[BlockInQuestion] )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -520,8 +520,10 @@ public:
|
||||
|
||||
// Illegal in C++03: typedef std::list< cCoordWithData<X> > cCoordWithDataList<X>;
|
||||
typedef cCoordWithData<int> cCoordWithInt;
|
||||
typedef cCoordWithData<BLOCKTYPE> cCoordWithBlock;
|
||||
typedef std::list<cCoordWithInt> cCoordWithIntList;
|
||||
typedef std::vector<cCoordWithInt> cCoordWithIntVector;
|
||||
typedef std::vector<cCoordWithBlock> cCoordWithBlockVector;
|
||||
|
||||
|
||||
|
||||
|
@ -41,8 +41,8 @@ extern bool g_BlockRequiresSpecialTool[256];
|
||||
/// Is this block solid (player cannot walk through)?
|
||||
extern bool g_BlockIsSolid[256];
|
||||
|
||||
/// Can torches be placed on this block?
|
||||
extern bool g_BlockIsTorchPlaceable[256];
|
||||
/// Does this block fully occupy it's voxel - is it a 'full' block?
|
||||
extern bool g_BlockFullyOccupiesVoxel[256];
|
||||
|
||||
/// Experience Orb setup
|
||||
enum
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
|
||||
) override
|
||||
{
|
||||
if (!g_BlockIsTorchPlaceable[a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)]) // Some solid blocks, such as cocoa beans, are not suitable for dust
|
||||
if (!g_BlockFullyOccupiesVoxel[a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)]) // Some solid blocks, such as cocoa beans, are not suitable for dust
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ public: // tolua_export
|
||||
/// Notifies the server that a player is being destroyed; the server uses this to adjust the number of players
|
||||
void PlayerDestroying(const cPlayer * a_Player);
|
||||
|
||||
/* Returns base64 encoded favicon data (obtained from favicon.png) */
|
||||
/** Returns base64 encoded favicon data (obtained from favicon.png) */
|
||||
const AString & GetFaviconData(void) const { return m_FaviconData; }
|
||||
|
||||
CryptoPP::RSA::PrivateKey & GetPrivateKey(void) { return m_PrivateKey; }
|
||||
|
@ -44,83 +44,46 @@ void cRedstoneSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChu
|
||||
|
||||
int RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width;
|
||||
int RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width;
|
||||
|
||||
BLOCKTYPE Block;
|
||||
NIBBLETYPE Meta;
|
||||
a_Chunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta);
|
||||
|
||||
if (!IsAllowedBlock(a_Chunk->GetBlock(RelX, a_BlockY, RelZ)))
|
||||
// Every time a block is changed (AddBlock called), we want to go through all lists and check to see if the coordiantes stored within are still valid
|
||||
// Checking only when a block is changed, as opposed to every tick, also improves performance
|
||||
|
||||
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for duplicates:
|
||||
cRedstoneSimulatorChunkData & ChunkData = a_Chunk->GetRedstoneSimulatorData();
|
||||
for (cRedstoneSimulatorChunkData::const_iterator itr = ChunkData.begin(); itr != ChunkData.end(); ++itr)
|
||||
{
|
||||
if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ChunkData.push_back(cCoordWithInt(RelX, a_BlockY, RelZ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
|
||||
{
|
||||
cRedstoneSimulatorChunkData & ChunkData = a_Chunk->GetRedstoneSimulatorData();
|
||||
if (ChunkData.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int BaseX = a_Chunk->GetPosX() * cChunkDef::Width;
|
||||
int BaseZ = a_Chunk->GetPosZ() * cChunkDef::Width;
|
||||
|
||||
// Check to see if PoweredBlocks have invalid items (source is air or unpowered)
|
||||
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end();)
|
||||
{
|
||||
int RelX = itr->a_SourcePos.x - a_ChunkX * cChunkDef::Width;
|
||||
int RelZ = itr->a_SourcePos.z - a_ChunkZ * cChunkDef::Width;
|
||||
int DestRelX = itr->a_BlockPos.x - a_ChunkX * cChunkDef::Width;
|
||||
int DestRelZ = itr->a_BlockPos.z - a_ChunkZ * cChunkDef::Width;
|
||||
|
||||
BLOCKTYPE SourceBlockType;
|
||||
NIBBLETYPE SourceBlockMeta;
|
||||
BLOCKTYPE DestBlockType;
|
||||
if (
|
||||
!a_Chunk->UnboundedRelGetBlock(RelX, itr->a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta) ||
|
||||
!a_Chunk->UnboundedRelGetBlockType(DestRelX, itr->a_BlockPos.y, DestRelZ, DestBlockType)
|
||||
)
|
||||
if (!itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (SourceBlockType != itr->a_SourceBlock)
|
||||
if (!IsPotentialSource(Block))
|
||||
{
|
||||
LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past block type mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
|
||||
itr = m_PoweredBlocks.erase(itr);
|
||||
LOGD("cRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list as it no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
|
||||
m_PoweredBlocks.erase(itr);
|
||||
break;
|
||||
}
|
||||
else if (
|
||||
// Changeable sources
|
||||
((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (SourceBlockMeta == 0)) ||
|
||||
((SourceBlockType == E_BLOCK_LEVER) && !IsLeverOn(SourceBlockMeta)) ||
|
||||
((SourceBlockType == E_BLOCK_DETECTOR_RAIL) && (SourceBlockMeta & 0x08) == 0x08) ||
|
||||
(((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta))) ||
|
||||
(((SourceBlockType == E_BLOCK_STONE_PRESSURE_PLATE) || (SourceBlockType == E_BLOCK_WOODEN_PRESSURE_PLATE)) && (SourceBlockMeta == 0))
|
||||
((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) ||
|
||||
((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) ||
|
||||
((Block == E_BLOCK_DETECTOR_RAIL) && (Meta & 0x08) == 0x08) ||
|
||||
(((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta))) ||
|
||||
(((Block == E_BLOCK_STONE_PRESSURE_PLATE) || (Block == E_BLOCK_WOODEN_PRESSURE_PLATE)) && (Meta == 0))
|
||||
)
|
||||
{
|
||||
LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past metadata mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
|
||||
itr = m_PoweredBlocks.erase(itr);
|
||||
LOGD("cRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
|
||||
m_PoweredBlocks.erase(itr);
|
||||
break;
|
||||
}
|
||||
else if (SourceBlockType == E_BLOCK_DAYLIGHT_SENSOR)
|
||||
else if (Block == E_BLOCK_DAYLIGHT_SENSOR)
|
||||
{
|
||||
if (!a_Chunk->IsLightValid())
|
||||
{
|
||||
m_World.QueueLightChunk(a_ChunkX, a_ChunkZ);
|
||||
++itr;
|
||||
continue;
|
||||
m_World.QueueLightChunk(a_Chunk->GetPosX(), a_Chunk->GetPosZ());
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -130,126 +93,125 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
|
||||
if (a_Chunk->GetTimeAlteredLight(SkyLight) <= 8) // Could use SkyLight - m_World.GetSkyDarkness();
|
||||
{
|
||||
LOGD("cRedstoneSimulator: Erased daylight sensor from powered blocks list due to insufficient light level");
|
||||
itr = m_PoweredBlocks.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
m_PoweredBlocks.erase(itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (DestBlockType == E_BLOCK_REDSTONE_WIRE))
|
||||
}
|
||||
|
||||
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr)
|
||||
{
|
||||
if (itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
|
||||
{
|
||||
// It is simply not allowed that a wire powers another wire, presuming that data here is sane and a dest and source are beside each other
|
||||
LOGD("cRedstoneSimulator: Erased redstone wire from powered blocks list because its source was also wire");
|
||||
itr = m_PoweredBlocks.erase(itr);
|
||||
if (!IsPotentialSource(Block))
|
||||
{
|
||||
LOGD("cRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
|
||||
m_LinkedPoweredBlocks.erase(itr);
|
||||
break;
|
||||
}
|
||||
else if (
|
||||
// Things that can send power through a block but which depends on meta
|
||||
((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) ||
|
||||
((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) ||
|
||||
(((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta)))
|
||||
)
|
||||
{
|
||||
LOGD("cRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
|
||||
m_LinkedPoweredBlocks.erase(itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (itr->a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
|
||||
{
|
||||
++itr;
|
||||
if (!IsViableMiddleBlock(Block))
|
||||
{
|
||||
LOGD("cRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer powered through a valid middle block", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
|
||||
m_LinkedPoweredBlocks.erase(itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if LinkedPoweredBlocks have invalid items: source, block powered through, or power destination block has changed
|
||||
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end();)
|
||||
for (SimulatedPlayerToggleableList::iterator itr = m_SimulatedPlayerToggleableBlocks.begin(); itr != m_SimulatedPlayerToggleableBlocks.end(); ++itr)
|
||||
{
|
||||
int RelX = itr->a_SourcePos.x - a_ChunkX * cChunkDef::Width;
|
||||
int RelZ = itr->a_SourcePos.z - a_ChunkZ * cChunkDef::Width;
|
||||
int MidRelX = itr->a_MiddlePos.x - a_ChunkX * cChunkDef::Width;
|
||||
int MidRelZ = itr->a_MiddlePos.z - a_ChunkZ * cChunkDef::Width;
|
||||
|
||||
BLOCKTYPE SourceBlockType;
|
||||
NIBBLETYPE SourceBlockMeta;
|
||||
BLOCKTYPE MiddleBlockType;
|
||||
if (
|
||||
!a_Chunk->UnboundedRelGetBlock(RelX, itr->a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta) ||
|
||||
!a_Chunk->UnboundedRelGetBlockType(MidRelX, itr->a_MiddlePos.y, MidRelZ, MiddleBlockType)
|
||||
)
|
||||
if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (SourceBlockType != itr->a_SourceBlock)
|
||||
if (!IsAllowedBlock(Block))
|
||||
{
|
||||
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past block type mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
|
||||
itr = m_LinkedPoweredBlocks.erase(itr);
|
||||
}
|
||||
else if (MiddleBlockType != itr->a_MiddleBlock)
|
||||
{
|
||||
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past middle block mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
|
||||
itr = m_LinkedPoweredBlocks.erase(itr);
|
||||
}
|
||||
else if (
|
||||
// Things that can send power through a block but which depends on meta
|
||||
((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (SourceBlockMeta == 0)) ||
|
||||
((SourceBlockType == E_BLOCK_LEVER) && !IsLeverOn(SourceBlockMeta)) ||
|
||||
(((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta)))
|
||||
)
|
||||
{
|
||||
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past metadata mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
|
||||
itr = m_LinkedPoweredBlocks.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itr;
|
||||
LOGD("cRedstoneSimulator: Erased block @ {%i, %i, %i} from toggleable simulated list as it is no longer redstone", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
|
||||
m_SimulatedPlayerToggleableBlocks.erase(itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (SimulatedPlayerToggleableList::iterator itr = m_SimulatedPlayerToggleableBlocks.begin(); itr != m_SimulatedPlayerToggleableBlocks.end();)
|
||||
for (RepeatersDelayList::iterator itr = m_RepeatersDelayList.begin(); itr != m_RepeatersDelayList.end(); ++itr)
|
||||
{
|
||||
int RelX = itr->a_BlockPos.x - a_ChunkX * cChunkDef::Width;
|
||||
int RelZ = itr->a_BlockPos.z - a_ChunkZ * cChunkDef::Width;
|
||||
|
||||
BLOCKTYPE SourceBlockType;
|
||||
if (!a_Chunk->UnboundedRelGetBlockType(RelX, itr->a_BlockPos.y, RelZ, SourceBlockType))
|
||||
if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (!IsAllowedBlock(SourceBlockType))
|
||||
|
||||
if ((Block != E_BLOCK_REDSTONE_REPEATER_ON) && (Block != E_BLOCK_REDSTONE_REPEATER_OFF))
|
||||
{
|
||||
LOGD("cRedstoneSimulator: Erased block %s from toggleable simulated list as block is no longer redstone", ItemToFullString(SourceBlockType).c_str());
|
||||
itr = m_SimulatedPlayerToggleableBlocks.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itr;
|
||||
m_RepeatersDelayList.erase(itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (RepeatersDelayList::iterator itr = m_RepeatersDelayList.begin(); itr != m_RepeatersDelayList.end();)
|
||||
cRedstoneSimulatorChunkData & ChunkData = a_Chunk->GetRedstoneSimulatorData();
|
||||
for (cRedstoneSimulatorChunkData::iterator itr = ChunkData.begin(); itr != ChunkData.end(); ++itr)
|
||||
{
|
||||
int RelX = itr->a_BlockPos.x - a_ChunkX * cChunkDef::Width;
|
||||
int RelZ = itr->a_BlockPos.z - a_ChunkZ * cChunkDef::Width;
|
||||
|
||||
BLOCKTYPE SourceBlockType;
|
||||
if (!a_Chunk->UnboundedRelGetBlockType(RelX, itr->a_BlockPos.y, RelZ, SourceBlockType))
|
||||
if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ)) // We are at an entry matching the current (changed) block
|
||||
{
|
||||
continue;
|
||||
if (!IsAllowedBlock(Block))
|
||||
{
|
||||
ChunkData.erase(itr); // The new blocktype is not redstone; it must be removed from this list
|
||||
}
|
||||
else
|
||||
{
|
||||
itr->Data = Block; // Update block information
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ((SourceBlockType != E_BLOCK_REDSTONE_REPEATER_ON) && (SourceBlockType != E_BLOCK_REDSTONE_REPEATER_OFF))
|
||||
{
|
||||
itr = m_RepeatersDelayList.erase(itr);
|
||||
continue;
|
||||
}
|
||||
|
||||
++itr;
|
||||
}
|
||||
|
||||
for (cRedstoneSimulatorChunkData::iterator dataitr = ChunkData.begin(), end = ChunkData.end(); dataitr != end;)
|
||||
if (!IsAllowedBlock(Block))
|
||||
{
|
||||
BLOCKTYPE BlockType = a_Chunk->GetBlock(dataitr->x, dataitr->y, dataitr->z);
|
||||
if (!IsAllowedBlock(BlockType))
|
||||
{
|
||||
dataitr = ChunkData.erase(dataitr);
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// PoweredBlock and LinkedPoweredBlock list was fine, now to the actual handling
|
||||
ChunkData.push_back(cCoordWithBlock(RelX, a_BlockY, RelZ, Block));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
|
||||
{
|
||||
// We still attempt to simulate all blocks in the chunk every tick, because of outside influence that needs to be taken into account
|
||||
// For example, repeaters need to be ticked, pressure plates checked for entities, daylight sensor checked for light changes, etc.
|
||||
// The easiest way to make this more efficient is probably just to reduce code within the handlers that put too much strain on server, like getting or setting blocks
|
||||
// A marking dirty system might be a TODO for later on, perhaps
|
||||
|
||||
cRedstoneSimulatorChunkData & ChunkData = a_Chunk->GetRedstoneSimulatorData();
|
||||
if (ChunkData.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int BaseX = a_Chunk->GetPosX() * cChunkDef::Width;
|
||||
int BaseZ = a_Chunk->GetPosZ() * cChunkDef::Width;
|
||||
|
||||
for (cRedstoneSimulatorChunkData::const_iterator dataitr = ChunkData.begin(); dataitr != ChunkData.end(); ++dataitr)
|
||||
{
|
||||
int a_X = BaseX + dataitr->x;
|
||||
int a_Z = BaseZ + dataitr->z;
|
||||
switch (BlockType)
|
||||
switch (dataitr->Data)
|
||||
{
|
||||
case E_BLOCK_BLOCK_OF_REDSTONE: HandleRedstoneBlock(a_X, dataitr->y, a_Z); break;
|
||||
case E_BLOCK_LEVER: HandleRedstoneLever(a_X, dataitr->y, a_Z); break;
|
||||
@ -262,19 +224,19 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
|
||||
case E_BLOCK_REDSTONE_TORCH_OFF:
|
||||
case E_BLOCK_REDSTONE_TORCH_ON:
|
||||
{
|
||||
HandleRedstoneTorch(a_X, dataitr->y, a_Z, BlockType);
|
||||
HandleRedstoneTorch(a_X, dataitr->y, a_Z, dataitr->Data);
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_STONE_BUTTON:
|
||||
case E_BLOCK_WOODEN_BUTTON:
|
||||
{
|
||||
HandleRedstoneButton(a_X, dataitr->y, a_Z, BlockType);
|
||||
HandleRedstoneButton(a_X, dataitr->y, a_Z, dataitr->Data);
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||
{
|
||||
HandleRedstoneRepeater(a_X, dataitr->y, a_Z, BlockType);
|
||||
HandleRedstoneRepeater(a_X, dataitr->y, a_Z, dataitr->Data);
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_PISTON:
|
||||
@ -286,7 +248,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
|
||||
case E_BLOCK_REDSTONE_LAMP_OFF:
|
||||
case E_BLOCK_REDSTONE_LAMP_ON:
|
||||
{
|
||||
HandleRedstoneLamp(a_X, dataitr->y, a_Z, BlockType);
|
||||
HandleRedstoneLamp(a_X, dataitr->y, a_Z, dataitr->Data);
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_DISPENSER:
|
||||
@ -305,18 +267,16 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
|
||||
case E_BLOCK_DETECTOR_RAIL:
|
||||
case E_BLOCK_POWERED_RAIL:
|
||||
{
|
||||
HandleRail(a_X, dataitr->y, a_Z, BlockType);
|
||||
HandleRail(a_X, dataitr->y, a_Z, dataitr->Data);
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||
{
|
||||
HandlePressurePlate(a_X, dataitr->y, a_Z, BlockType);
|
||||
HandlePressurePlate(a_X, dataitr->y, a_Z, dataitr->Data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
++dataitr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -487,7 +447,7 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl
|
||||
};
|
||||
|
||||
// Check to see if directly beside a power source
|
||||
if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ))
|
||||
if (IsWirePowered(a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 15); // Maximum power
|
||||
}
|
||||
@ -546,6 +506,7 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl
|
||||
// However, self not directly powered anymore, so source must have been removed,
|
||||
// therefore, self must be set to meta zero
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 0);
|
||||
m_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
|
||||
return; // No need to process block power sets because self not powered
|
||||
}
|
||||
else
|
||||
@ -693,7 +654,7 @@ void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int
|
||||
// Apparently, incrementing ticks only works reliably here, and not in SimChunk;
|
||||
// With a world with lots of redstone, the repeaters simply do not delay
|
||||
// I am confounded to say why. Perhaps optimisation failure.
|
||||
LOGD("Incremented a repeater @ %i %i %i | Elapsed ticks: %i | Target delay: %i", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z, itr->a_ElapsedTicks, itr->a_DelayTicks);
|
||||
LOGD("Incremented a repeater @ {%i %i %i} | Elapsed ticks: %i | Target delay: %i", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z, itr->a_ElapsedTicks, itr->a_DelayTicks);
|
||||
itr->a_ElapsedTicks++;
|
||||
}
|
||||
}
|
||||
@ -781,48 +742,20 @@ void cRedstoneSimulator::HandleTNT(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
|
||||
void cRedstoneSimulator::HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
if ((m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x08) == 0x08)
|
||||
if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
// Block position is located at top half of door
|
||||
// Is Y - 1 both within world boundaries, a door block, and the bottom half of a door?
|
||||
// The bottom half stores the open/closed information
|
||||
if (
|
||||
(a_BlockY - 1 >= 0) &&
|
||||
((m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_WOODEN_DOOR) || (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_IRON_DOOR)) &&
|
||||
(m_World.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ & 0x08) == 0)
|
||||
)
|
||||
if (!AreCoordsSimulated(a_BlockX, a_BlockY, a_BlockZ, true))
|
||||
{
|
||||
if ((m_World.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ) & 0x04) == 0) // Closed door?
|
||||
{
|
||||
if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) // Powered? If so, toggle open
|
||||
{
|
||||
cBlockDoorHandler::ChangeDoor(&m_World, a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
}
|
||||
else // Opened door
|
||||
{
|
||||
if (!AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) // Unpowered? Close if so
|
||||
{
|
||||
cBlockDoorHandler::ChangeDoor(&m_World, a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
}
|
||||
cBlockDoorHandler::ChangeDoor(&m_World, a_BlockX, a_BlockY, a_BlockZ);
|
||||
SetPlayerToggleableBlockAsSimulated(a_BlockX, a_BlockY, a_BlockZ, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x04) == 0) // Closed door?
|
||||
if (!AreCoordsSimulated(a_BlockX, a_BlockY, a_BlockZ, false))
|
||||
{
|
||||
if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) // Powered? If so, toggle open
|
||||
{
|
||||
cBlockDoorHandler::ChangeDoor(&m_World, a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
}
|
||||
else // Opened door
|
||||
{
|
||||
if (!AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) // Unpowered? Close if so
|
||||
{
|
||||
cBlockDoorHandler::ChangeDoor(&m_World, a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
cBlockDoorHandler::ChangeDoor(&m_World, a_BlockX, a_BlockY, a_BlockZ);
|
||||
SetPlayerToggleableBlockAsSimulated(a_BlockX, a_BlockY, a_BlockZ, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1188,6 +1121,33 @@ bool cRedstoneSimulator::IsPistonPowered(int a_BlockX, int a_BlockY, int a_Block
|
||||
|
||||
|
||||
|
||||
bool cRedstoneSimulator::IsWirePowered(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr)
|
||||
{
|
||||
if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
|
||||
|
||||
if (m_World.GetBlock(itr->a_SourcePos) != E_BLOCK_REDSTONE_WIRE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr)
|
||||
{
|
||||
if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
|
||||
|
||||
if (m_World.GetBlock(itr->a_SourcePos) != E_BLOCK_REDSTONE_WIRE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // Source was in front of the piston's front face
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cRedstoneSimulator::AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered)
|
||||
{
|
||||
@ -1333,11 +1293,6 @@ void cRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY, int a_Block
|
||||
// Don't set air, fixes some bugs (wires powering themselves)
|
||||
return;
|
||||
}
|
||||
if ((Block == E_BLOCK_REDSTONE_WIRE) && (a_SourceBlock == E_BLOCK_REDSTONE_WIRE))
|
||||
{
|
||||
// Wires cannot power themselves normally, instead, the wire handler will manually set meta
|
||||
return;
|
||||
}
|
||||
|
||||
for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list
|
||||
{
|
||||
@ -1354,7 +1309,6 @@ void cRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY, int a_Block
|
||||
sPoweredBlocks RC;
|
||||
RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
|
||||
RC.a_SourcePos = Vector3i(a_SourceX, a_SourceY, a_SourceZ);
|
||||
RC.a_SourceBlock = a_SourceBlock;
|
||||
m_PoweredBlocks.push_back(RC);
|
||||
}
|
||||
|
||||
@ -1379,11 +1333,6 @@ void cRedstoneSimulator::SetBlockLinkedPowered(
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ((a_SourceBlock == E_BLOCK_REDSTONE_WIRE) && (DestBlock == E_BLOCK_REDSTONE_WIRE))
|
||||
{
|
||||
// Wires cannot power another wire through a block
|
||||
return;
|
||||
}
|
||||
|
||||
for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) // Check linked powered list
|
||||
{
|
||||
@ -1402,8 +1351,6 @@ void cRedstoneSimulator::SetBlockLinkedPowered(
|
||||
RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
|
||||
RC.a_MiddlePos = Vector3i(a_MiddleX, a_MiddleY, a_MiddleZ);
|
||||
RC.a_SourcePos = Vector3i(a_SourceX, a_SourceY, a_SourceZ);
|
||||
RC.a_SourceBlock = a_SourceBlock;
|
||||
RC.a_MiddleBlock = a_MiddleBlock;
|
||||
m_LinkedPoweredBlocks.push_back(RC);
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "Simulator.h"
|
||||
|
||||
/// Per-chunk data for the simulator, specified individual chunks to simulate; 'Data' is not used
|
||||
typedef cCoordWithIntList cRedstoneSimulatorChunkData;
|
||||
typedef cCoordWithBlockVector cRedstoneSimulatorChunkData;
|
||||
|
||||
|
||||
|
||||
@ -39,7 +39,6 @@ private:
|
||||
{
|
||||
Vector3i a_BlockPos; // Position of powered block
|
||||
Vector3i a_SourcePos; // Position of source powering the block at a_BlockPos
|
||||
BLOCKTYPE a_SourceBlock; // The source block type (for pistons pushing away sources and replacing with non source etc.)
|
||||
};
|
||||
|
||||
struct sLinkedPoweredBlocks // Define structure of the indirectly powered blocks list (i.e. repeaters powering through a block to the block at the other side)
|
||||
@ -47,8 +46,6 @@ private:
|
||||
Vector3i a_BlockPos;
|
||||
Vector3i a_MiddlePos;
|
||||
Vector3i a_SourcePos;
|
||||
BLOCKTYPE a_SourceBlock;
|
||||
BLOCKTYPE a_MiddleBlock;
|
||||
};
|
||||
|
||||
struct sSimulatedPlayerToggleableList
|
||||
@ -81,102 +78,89 @@ private:
|
||||
// In addition to being non-performant, it would stop the player from actually breaking said device
|
||||
|
||||
/* ====== SOURCES ====== */
|
||||
/// <summary>Handles the redstone torch</summary>
|
||||
/** Handles the redstone torch */
|
||||
void HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
|
||||
/// <summary>Handles the redstone block</summary>
|
||||
/** Handles the redstone block */
|
||||
void HandleRedstoneBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/// <summary>Handles levers</summary>
|
||||
/** Handles levers */
|
||||
void HandleRedstoneLever(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/// <summary>Handles buttons</summary>
|
||||
/** Handles buttons */
|
||||
void HandleRedstoneButton(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType);
|
||||
/// <summary>Handles daylight sensors</summary>
|
||||
/** Handles daylight sensors */
|
||||
void HandleDaylightSensor(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/// <summary>Handles pressure plates</summary>
|
||||
/** Handles pressure plates */
|
||||
void HandlePressurePlate(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType);
|
||||
/* ==================== */
|
||||
|
||||
/* ====== CARRIERS ====== */
|
||||
/// <summary>Handles redstone wire</summary>
|
||||
/** Handles redstone wire */
|
||||
void HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/// <summary>Handles repeaters</summary>
|
||||
/** Handles repeaters */
|
||||
void HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
|
||||
/* ====================== */
|
||||
|
||||
/* ====== DEVICES ====== */
|
||||
/// <summary>Handles pistons</summary>
|
||||
/** Handles pistons */
|
||||
void HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/// <summary>Handles dispensers and droppers</summary>
|
||||
/** Handles dispensers and droppers */
|
||||
void HandleDropSpenser(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/// <summary>Handles TNT (exploding)</summary>
|
||||
/** Handles TNT (exploding) */
|
||||
void HandleTNT(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/// <summary>Handles redstone lamps</summary>
|
||||
/** Handles redstone lamps */
|
||||
void HandleRedstoneLamp(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
|
||||
/// <summary>Handles doords</summary>
|
||||
/** Handles doords */
|
||||
void HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/// <summary>Handles activator, detector, and powered rails</summary>
|
||||
/** Handles activator, detector, and powered rails */
|
||||
void HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType);
|
||||
/// <summary>Handles trapdoors</summary>
|
||||
/** Handles trapdoors */
|
||||
void HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/// <summary>Handles noteblocks</summary>
|
||||
/** Handles noteblocks */
|
||||
void HandleNoteBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/* ===================== */
|
||||
|
||||
/* ====== Helper functions ====== */
|
||||
/// <summary>Marks a block as powered</summary>
|
||||
/** Marks a block as powered */
|
||||
void SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock);
|
||||
/// <summary>Marks a block as being powered through another block</summary>
|
||||
/** Marks a block as being powered through another block */
|
||||
void SetBlockLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_MiddleX, int a_MiddleY, int a_MiddleZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddeBlock);
|
||||
/// <summary>Marks a block as simulated, who should not be simulated further unless their power state changes, to accomodate a player manually toggling the block without triggering the simulator toggling it back</summary>
|
||||
/** Marks a block as simulated, who should not be simulated further unless their power state changes, to accomodate a player manually toggling the block without triggering the simulator toggling it back */
|
||||
void SetPlayerToggleableBlockAsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool WasLastStatePowered);
|
||||
/// <summary>Marks the second block in a direction as linked powered</summary>
|
||||
/** Marks the second block in a direction as linked powered */
|
||||
void SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceBlock);
|
||||
/// <summary>Marks all blocks immediately surrounding a coordinate as powered</summary>
|
||||
/** Marks all blocks immediately surrounding a coordinate as powered */
|
||||
void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock);
|
||||
/// <summary>Queues a repeater to be powered or unpowered</summary>
|
||||
/** Queues a repeater to be powered or unpowered */
|
||||
void QueueRepeaterPowerChange(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta, short a_ElapsedTicks, bool ShouldPowerOn);
|
||||
|
||||
/// <summary>Returns if a coordinate is powered or linked powered</summary>
|
||||
/** Returns if a coordinate is powered or linked powered */
|
||||
bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ) { return AreCoordsDirectlyPowered(a_BlockX, a_BlockY, a_BlockZ) || AreCoordsLinkedPowered(a_BlockX, a_BlockY, a_BlockZ); }
|
||||
/// <summary>Returns if a coordinate is in the directly powered blocks list</summary>
|
||||
/** Returns if a coordinate is in the directly powered blocks list */
|
||||
bool AreCoordsDirectlyPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/// <summary>Returns if a coordinate is in the indirectly powered blocks list</summary>
|
||||
/** Returns if a coordinate is in the indirectly powered blocks list */
|
||||
bool AreCoordsLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/// <summary>Returns if a coordinate was marked as simulated (for blocks toggleable by players)</summary>
|
||||
/** Returns if a coordinate was marked as simulated (for blocks toggleable by players) */
|
||||
bool AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered);
|
||||
/// <summary>Returns if a repeater is powered</summary>
|
||||
/** Returns if a repeater is powered */
|
||||
bool IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
|
||||
/// <summary>Returns if a piston is powered</summary>
|
||||
/** Returns if a piston is powered */
|
||||
bool IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
|
||||
/** Returns if a wire is powered
|
||||
The only diffence between this and a normal AreCoordsPowered is that this function checks for a wire powering another wire
|
||||
*/
|
||||
bool IsWirePowered(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
|
||||
/// <summary>Returns if lever metadata marks it as emitting power</summary>
|
||||
|
||||
/** Returns if lever metadata marks it as emitting power */
|
||||
bool IsLeverOn(NIBBLETYPE a_BlockMeta);
|
||||
/// <summary>Returns if button metadata marks it as emitting power</summary>
|
||||
/** Returns if button metadata marks it as emitting power */
|
||||
bool IsButtonOn(NIBBLETYPE a_BlockMeta);
|
||||
/* ============================== */
|
||||
|
||||
/* ====== Misc Functions ====== */
|
||||
/// <summary>Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation</summary>
|
||||
inline static bool IsViableMiddleBlock(BLOCKTYPE Block)
|
||||
{
|
||||
if (!g_BlockIsSolid[Block]) { return false; }
|
||||
/** Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation */
|
||||
inline static bool IsViableMiddleBlock(BLOCKTYPE Block) { return g_BlockFullyOccupiesVoxel[Block]; }
|
||||
|
||||
switch (Block)
|
||||
{
|
||||
// Add SOLID but not viable middle blocks here
|
||||
case E_BLOCK_PISTON:
|
||||
case E_BLOCK_PISTON_EXTENSION:
|
||||
case E_BLOCK_STICKY_PISTON:
|
||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
||||
case E_BLOCK_DAYLIGHT_SENSOR:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Returns if a block is a mechanism (something that accepts power and does something)</summary>
|
||||
/** Returns if a block is a mechanism (something that accepts power and does something) */
|
||||
inline static bool IsMechanism(BLOCKTYPE Block)
|
||||
{
|
||||
switch (Block)
|
||||
@ -205,16 +189,16 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Returns if a block has the potential to output power</summary>
|
||||
/** Returns if a block has the potential to output power */
|
||||
inline static bool IsPotentialSource(BLOCKTYPE Block)
|
||||
{
|
||||
switch (Block)
|
||||
{
|
||||
case E_BLOCK_DETECTOR_RAIL:
|
||||
case E_BLOCK_DAYLIGHT_SENSOR:
|
||||
case E_BLOCK_WOODEN_BUTTON:
|
||||
case E_BLOCK_STONE_BUTTON:
|
||||
case E_BLOCK_REDSTONE_WIRE:
|
||||
case E_BLOCK_REDSTONE_TORCH_OFF:
|
||||
case E_BLOCK_REDSTONE_TORCH_ON:
|
||||
case E_BLOCK_LEVER:
|
||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||
@ -227,7 +211,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Returns if a block is any sort of redstone device</summary>
|
||||
/** Returns if a block is any sort of redstone device */
|
||||
inline static bool IsRedstone(BLOCKTYPE Block)
|
||||
{
|
||||
switch (Block)
|
||||
@ -248,6 +232,7 @@ private:
|
||||
case E_BLOCK_LEVER:
|
||||
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
|
||||
case E_BLOCK_NOTE_BLOCK:
|
||||
case E_BLOCK_POWERED_RAIL:
|
||||
case E_BLOCK_REDSTONE_LAMP_OFF:
|
||||
case E_BLOCK_REDSTONE_LAMP_ON:
|
||||
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
||||
|
Loading…
Reference in New Issue
Block a user