Merge pull request #1154 from mc-server/trappedchests
Implemented trapped chests & others
This commit is contained in:
commit
5f72cdac38
@ -28,24 +28,26 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE
|
|||||||
switch (a_BlockType)
|
switch (a_BlockType)
|
||||||
{
|
{
|
||||||
case E_BLOCK_BEACON: return new cBeaconEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_BEACON: return new cBeaconEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
case E_BLOCK_CHEST: return new cChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_CHEST: return new cChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World, a_BlockType);
|
||||||
case E_BLOCK_COMMAND_BLOCK: return new cCommandBlockEntity(a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_COMMAND_BLOCK: return new cCommandBlockEntity(a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
case E_BLOCK_DISPENSER: return new cDispenserEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_DISPENSER: return new cDispenserEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
case E_BLOCK_DROPPER: return new cDropperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_DROPPER: return new cDropperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
case E_BLOCK_ENDER_CHEST: return new cEnderChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_ENDER_CHEST: return new cEnderChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
case E_BLOCK_FLOWER_POT: return new cFlowerPotEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_FLOWER_POT: return new cFlowerPotEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
case E_BLOCK_HEAD: return new cMobHeadEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
|
||||||
case E_BLOCK_LIT_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
|
|
||||||
case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
|
case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
|
||||||
|
case E_BLOCK_HEAD: return new cMobHeadEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
case E_BLOCK_HOPPER: return new cHopperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_HOPPER: return new cHopperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
|
case E_BLOCK_JUKEBOX: return new cJukeboxEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
|
case E_BLOCK_LIT_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
|
||||||
case E_BLOCK_SIGN_POST: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_SIGN_POST: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
|
case E_BLOCK_TRAPPED_CHEST: return new cChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World, a_BlockType);
|
||||||
case E_BLOCK_WALLSIGN: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_WALLSIGN: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
case E_BLOCK_NOTE_BLOCK: return new cNoteEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_NOTE_BLOCK: return new cNoteEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
case E_BLOCK_JUKEBOX: return new cJukeboxEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
|
||||||
}
|
}
|
||||||
LOGD("%s: Requesting creation of an unknown block entity - block type %d (%s)",
|
LOGD("%s: Requesting creation of an unknown block entity - block type %d (%s)",
|
||||||
__FUNCTION__, a_BlockType, ItemTypeToString(a_BlockType).c_str()
|
__FUNCTION__, a_BlockType, ItemTypeToString(a_BlockType).c_str()
|
||||||
);
|
);
|
||||||
|
ASSERT(!"Requesting creation of an unknown block entity");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,8 +11,9 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
cChestEntity::cChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
|
cChestEntity::cChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, BLOCKTYPE a_Type) :
|
||||||
super(E_BLOCK_CHEST, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World)
|
super(a_Type, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
|
||||||
|
m_NumActivePlayers(0)
|
||||||
{
|
{
|
||||||
cBlockEntityWindowOwner::SetBlockEntity(this);
|
cBlockEntityWindowOwner::SetBlockEntity(this);
|
||||||
}
|
}
|
||||||
@ -113,7 +114,7 @@ void cChestEntity::UsedBy(cPlayer * a_Player)
|
|||||||
// The few false positives aren't much to worry about
|
// The few false positives aren't much to worry about
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
cChunkDef::BlockToChunk(m_PosX, m_PosZ, ChunkX, ChunkZ);
|
cChunkDef::BlockToChunk(m_PosX, m_PosZ, ChunkX, ChunkZ);
|
||||||
m_World->MarkChunkDirty(ChunkX, ChunkZ);
|
m_World->MarkChunkDirty(ChunkX, ChunkZ, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,8 +34,8 @@ public:
|
|||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
/// Constructor used for normal operation
|
/** Constructor used for normal operation */
|
||||||
cChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
|
cChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, BLOCKTYPE a_Type);
|
||||||
|
|
||||||
virtual ~cChestEntity();
|
virtual ~cChestEntity();
|
||||||
|
|
||||||
@ -48,8 +48,20 @@ public:
|
|||||||
virtual void SendTo(cClientHandle & a_Client) override;
|
virtual void SendTo(cClientHandle & a_Client) override;
|
||||||
virtual void UsedBy(cPlayer * a_Player) override;
|
virtual void UsedBy(cPlayer * a_Player) override;
|
||||||
|
|
||||||
/// Opens a new chest window for this chest. Scans for neighbors to open a double chest window, if appropriate.
|
/** Opens a new chest window for this chest.
|
||||||
|
Scans for neighbors to open a double chest window, if appropriate. */
|
||||||
void OpenNewWindow(void);
|
void OpenNewWindow(void);
|
||||||
|
|
||||||
|
/** Gets the number of players who currently have this chest open */
|
||||||
|
int GetNumberOfPlayers(void) const { return m_NumActivePlayers; }
|
||||||
|
|
||||||
|
/** Sets the number of players who currently have this chest open */
|
||||||
|
void SetNumberOfPlayers(int a_NumActivePlayers) { m_NumActivePlayers = a_NumActivePlayers; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/** Number of players who currently have this chest open */
|
||||||
|
int m_NumActivePlayers;
|
||||||
} ; // tolua_export
|
} ; // tolua_export
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,6 +157,7 @@ bool cHopperEntity::MoveItemsIn(cChunk & a_Chunk, Int64 a_CurrentTick)
|
|||||||
bool res = false;
|
bool res = false;
|
||||||
switch (a_Chunk.GetBlock(m_RelX, m_PosY + 1, m_RelZ))
|
switch (a_Chunk.GetBlock(m_RelX, m_PosY + 1, m_RelZ))
|
||||||
{
|
{
|
||||||
|
case E_BLOCK_TRAPPED_CHEST:
|
||||||
case E_BLOCK_CHEST:
|
case E_BLOCK_CHEST:
|
||||||
{
|
{
|
||||||
// Chests have special handling because of double-chests
|
// Chests have special handling because of double-chests
|
||||||
@ -322,6 +323,7 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
|
|||||||
bool res = false;
|
bool res = false;
|
||||||
switch (DestChunk->GetBlock(OutRelX, OutY, OutRelZ))
|
switch (DestChunk->GetBlock(OutRelX, OutY, OutRelZ))
|
||||||
{
|
{
|
||||||
|
case E_BLOCK_TRAPPED_CHEST:
|
||||||
case E_BLOCK_CHEST:
|
case E_BLOCK_CHEST:
|
||||||
{
|
{
|
||||||
// Chests have special handling because of double-chests
|
// Chests have special handling because of double-chests
|
||||||
@ -378,7 +380,7 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the chest is a double-chest, if so, try to move from there:
|
// Check if the chest is a double-chest (chest directly above was empty), if so, try to move from there:
|
||||||
static const struct
|
static const struct
|
||||||
{
|
{
|
||||||
int x, z;
|
int x, z;
|
||||||
@ -395,13 +397,18 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
|
|||||||
int x = m_RelX + Coords[i].x;
|
int x = m_RelX + Coords[i].x;
|
||||||
int z = m_RelZ + Coords[i].z;
|
int z = m_RelZ + Coords[i].z;
|
||||||
cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z);
|
cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z);
|
||||||
if (
|
if (Neighbor == NULL)
|
||||||
(Neighbor == NULL) ||
|
|
||||||
(Neighbor->GetBlock(x, m_PosY + 1, z) != E_BLOCK_CHEST)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BLOCKTYPE Block = Neighbor->GetBlock(x, m_PosY + 1, z);
|
||||||
|
if (Block != Chest->GetBlockType())
|
||||||
|
{
|
||||||
|
// Not the same kind of chest
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Chest = (cChestEntity *)Neighbor->GetBlockEntity(m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z);
|
Chest = (cChestEntity *)Neighbor->GetBlockEntity(m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z);
|
||||||
if (Chest == NULL)
|
if (Chest == NULL)
|
||||||
{
|
{
|
||||||
@ -550,10 +557,11 @@ bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_Block
|
|||||||
}
|
}
|
||||||
if (MoveItemsToGrid(*Chest))
|
if (MoveItemsToGrid(*Chest))
|
||||||
{
|
{
|
||||||
|
// Chest block directly connected was not full
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the chest is a double-chest, if so, try to move into the other half:
|
// Check if the chest is a double-chest (chest block directly connected was full), if so, try to move into the other half:
|
||||||
static const struct
|
static const struct
|
||||||
{
|
{
|
||||||
int x, z;
|
int x, z;
|
||||||
@ -572,13 +580,18 @@ bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_Block
|
|||||||
int x = RelX + Coords[i].x;
|
int x = RelX + Coords[i].x;
|
||||||
int z = RelZ + Coords[i].z;
|
int z = RelZ + Coords[i].z;
|
||||||
cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z);
|
cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z);
|
||||||
if (
|
if (Neighbor == NULL)
|
||||||
(Neighbor == NULL) ||
|
|
||||||
(Neighbor->GetBlock(x, a_BlockY, z) != E_BLOCK_CHEST)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BLOCKTYPE Block = Neighbor->GetBlock(x, a_BlockY, z);
|
||||||
|
if (Block != Chest->GetBlockType())
|
||||||
|
{
|
||||||
|
// Not the same kind of chest
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Chest = (cChestEntity *)Neighbor->GetBlockEntity(a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z);
|
Chest = (cChestEntity *)Neighbor->GetBlockEntity(a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z);
|
||||||
if (Chest == NULL)
|
if (Chest == NULL)
|
||||||
{
|
{
|
||||||
|
@ -101,6 +101,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
|
|||||||
a_Info[E_BLOCK_NEW_LEAVES ].m_SpreadLightFalloff = 1;
|
a_Info[E_BLOCK_NEW_LEAVES ].m_SpreadLightFalloff = 1;
|
||||||
a_Info[E_BLOCK_SIGN_POST ].m_SpreadLightFalloff = 1;
|
a_Info[E_BLOCK_SIGN_POST ].m_SpreadLightFalloff = 1;
|
||||||
a_Info[E_BLOCK_TORCH ].m_SpreadLightFalloff = 1;
|
a_Info[E_BLOCK_TORCH ].m_SpreadLightFalloff = 1;
|
||||||
|
a_Info[E_BLOCK_TRAPPED_CHEST ].m_SpreadLightFalloff = 1;
|
||||||
a_Info[E_BLOCK_TRIPWIRE ].m_SpreadLightFalloff = 1;
|
a_Info[E_BLOCK_TRIPWIRE ].m_SpreadLightFalloff = 1;
|
||||||
a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_SpreadLightFalloff = 1;
|
a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_SpreadLightFalloff = 1;
|
||||||
a_Info[E_BLOCK_VINES ].m_SpreadLightFalloff = 1;
|
a_Info[E_BLOCK_VINES ].m_SpreadLightFalloff = 1;
|
||||||
@ -162,6 +163,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
|
|||||||
a_Info[E_BLOCK_STATIONARY_WATER ].m_Transparent = true;
|
a_Info[E_BLOCK_STATIONARY_WATER ].m_Transparent = true;
|
||||||
a_Info[E_BLOCK_STONE_BUTTON ].m_Transparent = true;
|
a_Info[E_BLOCK_STONE_BUTTON ].m_Transparent = true;
|
||||||
a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_Transparent = true;
|
a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_Transparent = true;
|
||||||
|
a_Info[E_BLOCK_TRAPPED_CHEST ].m_Transparent = true;
|
||||||
a_Info[E_BLOCK_TRIPWIRE ].m_Transparent = true;
|
a_Info[E_BLOCK_TRIPWIRE ].m_Transparent = true;
|
||||||
a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_Transparent = true;
|
a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_Transparent = true;
|
||||||
a_Info[E_BLOCK_TALL_GRASS ].m_Transparent = true;
|
a_Info[E_BLOCK_TALL_GRASS ].m_Transparent = true;
|
||||||
@ -287,6 +289,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
|
|||||||
a_Info[E_BLOCK_TALL_GRASS ].m_IsSnowable = false;
|
a_Info[E_BLOCK_TALL_GRASS ].m_IsSnowable = false;
|
||||||
a_Info[E_BLOCK_TNT ].m_IsSnowable = false;
|
a_Info[E_BLOCK_TNT ].m_IsSnowable = false;
|
||||||
a_Info[E_BLOCK_TORCH ].m_IsSnowable = false;
|
a_Info[E_BLOCK_TORCH ].m_IsSnowable = false;
|
||||||
|
a_Info[E_BLOCK_TRAPPED_CHEST ].m_IsSnowable = false;
|
||||||
a_Info[E_BLOCK_TRIPWIRE ].m_IsSnowable = false;
|
a_Info[E_BLOCK_TRIPWIRE ].m_IsSnowable = false;
|
||||||
a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_IsSnowable = false;
|
a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_IsSnowable = false;
|
||||||
a_Info[E_BLOCK_VINES ].m_IsSnowable = false;
|
a_Info[E_BLOCK_VINES ].m_IsSnowable = false;
|
||||||
|
@ -44,16 +44,16 @@ public:
|
|||||||
}
|
}
|
||||||
double yaw = a_Player->GetYaw();
|
double yaw = a_Player->GetYaw();
|
||||||
if (
|
if (
|
||||||
(Area.GetRelBlockType(0, 0, 1) == E_BLOCK_CHEST) ||
|
(Area.GetRelBlockType(0, 0, 1) == m_BlockType) ||
|
||||||
(Area.GetRelBlockType(2, 0, 1) == E_BLOCK_CHEST)
|
(Area.GetRelBlockType(2, 0, 1) == m_BlockType)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
a_BlockMeta = ((yaw >= -90) && (yaw < 90)) ? 2 : 3;
|
a_BlockMeta = ((yaw >= -90) && (yaw < 90)) ? 2 : 3;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
(Area.GetRelBlockType(0, 0, 1) == E_BLOCK_CHEST) ||
|
(Area.GetRelBlockType(0, 0, 1) == m_BlockType) ||
|
||||||
(Area.GetRelBlockType(2, 0, 1) == E_BLOCK_CHEST)
|
(Area.GetRelBlockType(2, 0, 1) == m_BlockType)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// FIXME: This is unreachable, as the condition is the same as the above one
|
// FIXME: This is unreachable, as the condition is the same as the above one
|
||||||
@ -130,12 +130,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int NumChestNeighbors = 0;
|
int NumChestNeighbors = 0;
|
||||||
if (Area.GetRelBlockType(1, 0, 2) == E_BLOCK_CHEST)
|
if (Area.GetRelBlockType(1, 0, 2) == m_BlockType)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
(Area.GetRelBlockType(0, 0, 2) == E_BLOCK_CHEST) ||
|
(Area.GetRelBlockType(0, 0, 2) == m_BlockType) ||
|
||||||
(Area.GetRelBlockType(1, 0, 1) == E_BLOCK_CHEST) ||
|
(Area.GetRelBlockType(1, 0, 1) == m_BlockType) ||
|
||||||
(Area.GetRelBlockType(1, 0, 3) == E_BLOCK_CHEST)
|
(Area.GetRelBlockType(1, 0, 3) == m_BlockType)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Already a doublechest neighbor, disallow:
|
// Already a doublechest neighbor, disallow:
|
||||||
@ -143,12 +143,12 @@ public:
|
|||||||
}
|
}
|
||||||
NumChestNeighbors += 1;
|
NumChestNeighbors += 1;
|
||||||
}
|
}
|
||||||
if (Area.GetRelBlockType(3, 0, 2) == E_BLOCK_CHEST)
|
if (Area.GetRelBlockType(3, 0, 2) == m_BlockType)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
(Area.GetRelBlockType(4, 0, 2) == E_BLOCK_CHEST) ||
|
(Area.GetRelBlockType(4, 0, 2) == m_BlockType) ||
|
||||||
(Area.GetRelBlockType(3, 0, 1) == E_BLOCK_CHEST) ||
|
(Area.GetRelBlockType(3, 0, 1) == m_BlockType) ||
|
||||||
(Area.GetRelBlockType(3, 0, 3) == E_BLOCK_CHEST)
|
(Area.GetRelBlockType(3, 0, 3) == m_BlockType)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Already a doublechest neighbor, disallow:
|
// Already a doublechest neighbor, disallow:
|
||||||
@ -156,12 +156,12 @@ public:
|
|||||||
}
|
}
|
||||||
NumChestNeighbors += 1;
|
NumChestNeighbors += 1;
|
||||||
}
|
}
|
||||||
if (Area.GetRelBlockType(2, 0, 1) == E_BLOCK_CHEST)
|
if (Area.GetRelBlockType(2, 0, 1) == m_BlockType)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
(Area.GetRelBlockType(2, 0, 0) == E_BLOCK_CHEST) ||
|
(Area.GetRelBlockType(2, 0, 0) == m_BlockType) ||
|
||||||
(Area.GetRelBlockType(1, 0, 1) == E_BLOCK_CHEST) ||
|
(Area.GetRelBlockType(1, 0, 1) == m_BlockType) ||
|
||||||
(Area.GetRelBlockType(3, 0, 1) == E_BLOCK_CHEST)
|
(Area.GetRelBlockType(3, 0, 1) == m_BlockType)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Already a doublechest neighbor, disallow:
|
// Already a doublechest neighbor, disallow:
|
||||||
@ -169,12 +169,12 @@ public:
|
|||||||
}
|
}
|
||||||
NumChestNeighbors += 1;
|
NumChestNeighbors += 1;
|
||||||
}
|
}
|
||||||
if (Area.GetRelBlockType(2, 0, 3) == E_BLOCK_CHEST)
|
if (Area.GetRelBlockType(2, 0, 3) == m_BlockType)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
(Area.GetRelBlockType(2, 0, 4) == E_BLOCK_CHEST) ||
|
(Area.GetRelBlockType(2, 0, 4) == m_BlockType) ||
|
||||||
(Area.GetRelBlockType(1, 0, 3) == E_BLOCK_CHEST) ||
|
(Area.GetRelBlockType(1, 0, 3) == m_BlockType) ||
|
||||||
(Area.GetRelBlockType(3, 0, 3) == E_BLOCK_CHEST)
|
(Area.GetRelBlockType(3, 0, 3) == m_BlockType)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Already a doublechest neighbor, disallow:
|
// Already a doublechest neighbor, disallow:
|
||||||
@ -217,7 +217,7 @@ public:
|
|||||||
/// If there's a chest in the a_Area in the specified coords, modifies its meta to a_NewMeta and returns true.
|
/// If there's a chest in the a_Area in the specified coords, modifies its meta to a_NewMeta and returns true.
|
||||||
bool CheckAndAdjustNeighbor(cChunkInterface & a_ChunkInterface, const cBlockArea & a_Area, int a_RelX, int a_RelZ, NIBBLETYPE a_NewMeta)
|
bool CheckAndAdjustNeighbor(cChunkInterface & a_ChunkInterface, const cBlockArea & a_Area, int a_RelX, int a_RelZ, NIBBLETYPE a_NewMeta)
|
||||||
{
|
{
|
||||||
if (a_Area.GetRelBlockType(a_RelX, 0, a_RelZ) != E_BLOCK_CHEST)
|
if (a_Area.GetRelBlockType(a_RelX, 0, a_RelZ) != m_BlockType)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -228,7 +228,7 @@ public:
|
|||||||
|
|
||||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||||
{
|
{
|
||||||
a_Pickups.push_back(cItem(E_BLOCK_CHEST, 1, 0));
|
a_Pickups.push_back(cItem(m_BlockType, 1, 0));
|
||||||
}
|
}
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
@ -238,9 +238,9 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
|
|||||||
case E_BLOCK_LAPIS_ORE: return new cBlockOreHandler (a_BlockType);
|
case E_BLOCK_LAPIS_ORE: return new cBlockOreHandler (a_BlockType);
|
||||||
case E_BLOCK_LAVA: return new cBlockLavaHandler (a_BlockType);
|
case E_BLOCK_LAVA: return new cBlockLavaHandler (a_BlockType);
|
||||||
case E_BLOCK_LEAVES: return new cBlockLeavesHandler (a_BlockType);
|
case E_BLOCK_LEAVES: return new cBlockLeavesHandler (a_BlockType);
|
||||||
|
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType);
|
||||||
case E_BLOCK_LILY_PAD: return new cBlockLilypadHandler (a_BlockType);
|
case E_BLOCK_LILY_PAD: return new cBlockLilypadHandler (a_BlockType);
|
||||||
case E_BLOCK_LIT_FURNACE: return new cBlockFurnaceHandler (a_BlockType);
|
case E_BLOCK_LIT_FURNACE: return new cBlockFurnaceHandler (a_BlockType);
|
||||||
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType);
|
|
||||||
case E_BLOCK_LOG: return new cBlockSidewaysHandler (a_BlockType);
|
case E_BLOCK_LOG: return new cBlockSidewaysHandler (a_BlockType);
|
||||||
case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType);
|
case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType);
|
||||||
case E_BLOCK_MELON_STEM: return new cBlockStemsHandler (a_BlockType);
|
case E_BLOCK_MELON_STEM: return new cBlockStemsHandler (a_BlockType);
|
||||||
@ -293,6 +293,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
|
|||||||
case E_BLOCK_TORCH: return new cBlockTorchHandler (a_BlockType);
|
case E_BLOCK_TORCH: return new cBlockTorchHandler (a_BlockType);
|
||||||
case E_BLOCK_TRAPDOOR: return new cBlockTrapdoorHandler (a_BlockType);
|
case E_BLOCK_TRAPDOOR: return new cBlockTrapdoorHandler (a_BlockType);
|
||||||
case E_BLOCK_TNT: return new cBlockTNTHandler (a_BlockType);
|
case E_BLOCK_TNT: return new cBlockTNTHandler (a_BlockType);
|
||||||
|
case E_BLOCK_TRAPPED_CHEST: return new cBlockChestHandler (a_BlockType);
|
||||||
case E_BLOCK_TRIPWIRE: return new cBlockTripwireHandler (a_BlockType);
|
case E_BLOCK_TRIPWIRE: return new cBlockTripwireHandler (a_BlockType);
|
||||||
case E_BLOCK_TRIPWIRE_HOOK: return new cBlockTripwireHookHandler (a_BlockType);
|
case E_BLOCK_TRIPWIRE_HOOK: return new cBlockTripwireHookHandler (a_BlockType);
|
||||||
case E_BLOCK_VINES: return new cBlockVineHandler (a_BlockType);
|
case E_BLOCK_VINES: return new cBlockVineHandler (a_BlockType);
|
||||||
|
@ -85,7 +85,7 @@ int cBlockPistonHandler::FirstPassthroughBlock(int a_PistonX, int a_PistonY, int
|
|||||||
NIBBLETYPE currMeta;
|
NIBBLETYPE currMeta;
|
||||||
AddPistonDir(a_PistonX, a_PistonY, a_PistonZ, pistonmeta, 1);
|
AddPistonDir(a_PistonX, a_PistonY, a_PistonZ, pistonmeta, 1);
|
||||||
a_World->GetBlockTypeMeta(a_PistonX, a_PistonY, a_PistonZ, currBlock, currMeta);
|
a_World->GetBlockTypeMeta(a_PistonX, a_PistonY, a_PistonZ, currBlock, currMeta);
|
||||||
if (CanBreakPush(currBlock))
|
if (cBlockInfo::IsPistonBreakable(currBlock))
|
||||||
{
|
{
|
||||||
// This block breaks when pushed, extend up to here
|
// This block breaks when pushed, extend up to here
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -104,6 +104,7 @@ private:
|
|||||||
case E_BLOCK_ENCHANTMENT_TABLE:
|
case E_BLOCK_ENCHANTMENT_TABLE:
|
||||||
case E_BLOCK_END_PORTAL:
|
case E_BLOCK_END_PORTAL:
|
||||||
case E_BLOCK_END_PORTAL_FRAME:
|
case E_BLOCK_END_PORTAL_FRAME:
|
||||||
|
// Notice the lack of an E_BLOCK_ENDER_CHEST here; its because ender chests can totally be pushed/pulled in MCS :)
|
||||||
case E_BLOCK_FURNACE:
|
case E_BLOCK_FURNACE:
|
||||||
case E_BLOCK_LIT_FURNACE:
|
case E_BLOCK_LIT_FURNACE:
|
||||||
case E_BLOCK_HOPPER:
|
case E_BLOCK_HOPPER:
|
||||||
@ -113,6 +114,7 @@ private:
|
|||||||
case E_BLOCK_NOTE_BLOCK:
|
case E_BLOCK_NOTE_BLOCK:
|
||||||
case E_BLOCK_OBSIDIAN:
|
case E_BLOCK_OBSIDIAN:
|
||||||
case E_BLOCK_PISTON_EXTENSION:
|
case E_BLOCK_PISTON_EXTENSION:
|
||||||
|
case E_BLOCK_TRAPPED_CHEST:
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -126,24 +128,10 @@ private:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the specified block can be pushed by a piston and broken / replaced
|
|
||||||
static inline bool CanBreakPush(BLOCKTYPE a_BlockType) { return cBlockInfo::IsPistonBreakable(a_BlockType); }
|
|
||||||
|
|
||||||
/// Returns true if the specified block can be pulled by a sticky piston
|
/// Returns true if the specified block can be pulled by a sticky piston
|
||||||
static inline bool CanPull(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
|
static inline bool CanPull(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
|
||||||
{
|
{
|
||||||
switch (a_BlockType)
|
if (cBlockInfo::IsPistonBreakable(a_BlockType))
|
||||||
{
|
|
||||||
case E_BLOCK_LAVA:
|
|
||||||
case E_BLOCK_STATIONARY_LAVA:
|
|
||||||
case E_BLOCK_STATIONARY_WATER:
|
|
||||||
case E_BLOCK_WATER:
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CanBreakPush(a_BlockType))
|
|
||||||
{
|
{
|
||||||
return false; // CanBreakPush returns true, but we need false to prevent pulling
|
return false; // CanBreakPush returns true, but we need false to prevent pulling
|
||||||
}
|
}
|
||||||
|
@ -1301,6 +1301,7 @@ void cChunk::CreateBlockEntities(void)
|
|||||||
switch (BlockType)
|
switch (BlockType)
|
||||||
{
|
{
|
||||||
case E_BLOCK_BEACON:
|
case E_BLOCK_BEACON:
|
||||||
|
case E_BLOCK_TRAPPED_CHEST:
|
||||||
case E_BLOCK_CHEST:
|
case E_BLOCK_CHEST:
|
||||||
case E_BLOCK_COMMAND_BLOCK:
|
case E_BLOCK_COMMAND_BLOCK:
|
||||||
case E_BLOCK_DISPENSER:
|
case E_BLOCK_DISPENSER:
|
||||||
@ -1431,6 +1432,7 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType,
|
|||||||
switch (a_BlockType)
|
switch (a_BlockType)
|
||||||
{
|
{
|
||||||
case E_BLOCK_BEACON:
|
case E_BLOCK_BEACON:
|
||||||
|
case E_BLOCK_TRAPPED_CHEST:
|
||||||
case E_BLOCK_CHEST:
|
case E_BLOCK_CHEST:
|
||||||
case E_BLOCK_COMMAND_BLOCK:
|
case E_BLOCK_COMMAND_BLOCK:
|
||||||
case E_BLOCK_DISPENSER:
|
case E_BLOCK_DISPENSER:
|
||||||
@ -2150,7 +2152,7 @@ bool cChunk::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallb
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ((*itr)->GetBlockType() != E_BLOCK_CHEST)
|
if (((*itr)->GetBlockType() != E_BLOCK_CHEST) && ((*itr)->GetBlockType() != E_BLOCK_TRAPPED_CHEST)) // Trapped chests use normal chests' handlers
|
||||||
{
|
{
|
||||||
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
||||||
return false;
|
return false;
|
||||||
@ -2530,8 +2532,8 @@ cChunk * cChunk::GetRelNeighborChunk(int a_RelX, int a_RelZ)
|
|||||||
{
|
{
|
||||||
int BlockX = m_PosX * cChunkDef::Width + a_RelX;
|
int BlockX = m_PosX * cChunkDef::Width + a_RelX;
|
||||||
int BlockZ = m_PosZ * cChunkDef::Width + a_RelZ;
|
int BlockZ = m_PosZ * cChunkDef::Width + a_RelZ;
|
||||||
int BlockY, ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
|
BlockToChunk(BlockX, BlockZ, ChunkX, ChunkZ);
|
||||||
return m_ChunkMap->GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ);
|
return m_ChunkMap->GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -847,7 +847,22 @@ void cChunkMap::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_M
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunkMap::MarkChunkDirty (int a_ChunkX, int a_ChunkZ)
|
void cChunkMap::MarkRedstoneDirty(int a_ChunkX, int a_ChunkZ)
|
||||||
|
{
|
||||||
|
cCSLock Lock(m_CSLayers);
|
||||||
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
||||||
|
if ((Chunk == NULL) || !Chunk->IsValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Chunk->SetIsRedstoneDirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cChunkMap::MarkChunkDirty(int a_ChunkX, int a_ChunkZ, bool a_MarkRedstoneDirty)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
||||||
@ -856,6 +871,10 @@ void cChunkMap::MarkChunkDirty (int a_ChunkX, int a_ChunkZ)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Chunk->MarkDirty();
|
Chunk->MarkDirty();
|
||||||
|
if (a_MarkRedstoneDirty)
|
||||||
|
{
|
||||||
|
Chunk->SetIsRedstoneDirty(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,7 +106,8 @@ public:
|
|||||||
/** Wakes up the simulators for the specified area of blocks */
|
/** Wakes up the simulators for the specified area of blocks */
|
||||||
void WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ);
|
void WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ);
|
||||||
|
|
||||||
void MarkChunkDirty (int a_ChunkX, int a_ChunkZ);
|
void MarkRedstoneDirty (int a_ChunkX, int a_ChunkZ);
|
||||||
|
void MarkChunkDirty (int a_ChunkX, int a_ChunkZ, bool a_MarkRedstoneDirty = false);
|
||||||
void MarkChunkSaving (int a_ChunkX, int a_ChunkZ);
|
void MarkChunkSaving (int a_ChunkX, int a_ChunkZ);
|
||||||
void MarkChunkSaved (int a_ChunkX, int a_ChunkZ);
|
void MarkChunkSaved (int a_ChunkX, int a_ChunkZ);
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
class cExpOrb :
|
class cExpOrb :
|
||||||
public cEntity
|
public cEntity
|
||||||
{
|
{
|
||||||
typedef cExpOrb super;
|
typedef cEntity super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
@ -200,8 +200,8 @@ bool cMap::UpdatePixel(unsigned int a_X, unsigned int a_Z)
|
|||||||
int BlockX = m_CenterX + ((a_X - (m_Width / 2)) * PixelWidth);
|
int BlockX = m_CenterX + ((a_X - (m_Width / 2)) * PixelWidth);
|
||||||
int BlockZ = m_CenterZ + ((a_Z - (m_Height / 2)) * PixelWidth);
|
int BlockZ = m_CenterZ + ((a_Z - (m_Height / 2)) * PixelWidth);
|
||||||
|
|
||||||
int ChunkX, ChunkY, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
m_World->BlockToChunk(BlockX, 0, BlockZ, ChunkX, ChunkY, ChunkZ);
|
cChunkDef::BlockToChunk(BlockX, BlockZ, ChunkX, ChunkZ);
|
||||||
|
|
||||||
int RelX = BlockX - (ChunkX * cChunkDef::Width);
|
int RelX = BlockX - (ChunkX * cChunkDef::Width);
|
||||||
int RelZ = BlockZ - (ChunkZ * cChunkDef::Width);
|
int RelZ = BlockZ - (ChunkZ * cChunkDef::Width);
|
||||||
|
@ -262,7 +262,7 @@ bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_S
|
|||||||
AString HexDump;
|
AString HexDump;
|
||||||
if (Response.compare(0, prefix.size(), prefix))
|
if (Response.compare(0, prefix.size(), prefix))
|
||||||
{
|
{
|
||||||
LOGINFO("User \"%s\" failed to auth, bad http status line received", a_UserName.c_str());
|
LOGINFO("User %s failed to auth, bad http status line received", a_UserName.c_str());
|
||||||
LOG("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
|
LOG("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -271,7 +271,7 @@ bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_S
|
|||||||
size_t idxHeadersEnd = Response.find("\r\n\r\n");
|
size_t idxHeadersEnd = Response.find("\r\n\r\n");
|
||||||
if (idxHeadersEnd == AString::npos)
|
if (idxHeadersEnd == AString::npos)
|
||||||
{
|
{
|
||||||
LOGINFO("User \"%s\" failed to authenticate, bad http response header received", a_UserName.c_str());
|
LOGINFO("User %s failed to authenticate, bad http response header received", a_UserName.c_str());
|
||||||
LOG("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
|
LOG("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "BoundingBox.h"
|
#include "BoundingBox.h"
|
||||||
#include "../BlockEntities/DropSpenserEntity.h"
|
#include "../BlockEntities/DropSpenserEntity.h"
|
||||||
#include "../BlockEntities/NoteEntity.h"
|
#include "../BlockEntities/NoteEntity.h"
|
||||||
|
#include "../BlockEntities/ChestEntity.h"
|
||||||
#include "../BlockEntities/CommandBlockEntity.h"
|
#include "../BlockEntities/CommandBlockEntity.h"
|
||||||
#include "../Entities/TNTEntity.h"
|
#include "../Entities/TNTEntity.h"
|
||||||
#include "../Entities/Pickup.h"
|
#include "../Entities/Pickup.h"
|
||||||
@ -15,8 +16,6 @@
|
|||||||
#include "../Blocks/BlockPiston.h"
|
#include "../Blocks/BlockPiston.h"
|
||||||
#include "../Blocks/BlockTripwireHook.h"
|
#include "../Blocks/BlockTripwireHook.h"
|
||||||
|
|
||||||
#define WAKE_SIMULATOR_IF_DIRTY(a_Chunk, a_BlockX, a_BlockY, a_BlockZ) if (a_Chunk->IsRedstoneDirty()) WakeUp(a_BlockX, a_BlockY, a_BlockZ, a_Chunk);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -63,14 +62,16 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
|
|||||||
int RelZ = 0;
|
int RelZ = 0;
|
||||||
BLOCKTYPE Block;
|
BLOCKTYPE Block;
|
||||||
NIBBLETYPE Meta;
|
NIBBLETYPE Meta;
|
||||||
cChunk * OtherChunk = a_Chunk;
|
|
||||||
|
|
||||||
if (a_OtherChunk != NULL)
|
if (a_OtherChunk != NULL)
|
||||||
{
|
{
|
||||||
RelX = a_BlockX - a_OtherChunk->GetPosX() * cChunkDef::Width;
|
RelX = a_BlockX - a_OtherChunk->GetPosX() * cChunkDef::Width;
|
||||||
RelZ = a_BlockZ - a_OtherChunk->GetPosZ() * cChunkDef::Width;
|
RelZ = a_BlockZ - a_OtherChunk->GetPosZ() * cChunkDef::Width;
|
||||||
a_OtherChunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta);
|
a_OtherChunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta);
|
||||||
OtherChunk = a_OtherChunk;
|
|
||||||
|
// If a_OtherChunk is passed (not NULL), it is the chunk that had a block change, and a_Chunk will be the neighbouring chunk of that block
|
||||||
|
// Because said neighbouring chunk does not know of this change but still needs to update its redstone, we set it to dirty
|
||||||
|
a_Chunk->SetIsRedstoneDirty(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -95,8 +96,6 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
|
|||||||
{
|
{
|
||||||
LOGD("cIncrementalRedstoneSimulator: 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);
|
LOGD("cIncrementalRedstoneSimulator: 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);
|
||||||
itr = PoweredBlocks->erase(itr);
|
itr = PoweredBlocks->erase(itr);
|
||||||
a_Chunk->SetIsRedstoneDirty(true);
|
|
||||||
OtherChunk->SetIsRedstoneDirty(true);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
@ -105,34 +104,13 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
|
|||||||
((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) ||
|
((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) ||
|
||||||
((Block == E_BLOCK_DETECTOR_RAIL) && ((Meta & 0x08) == 0)) ||
|
((Block == E_BLOCK_DETECTOR_RAIL) && ((Meta & 0x08) == 0)) ||
|
||||||
(((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta))) ||
|
(((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)) ||
|
|
||||||
(((Block == E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE) || (Block == E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE)) && (Meta == 0)) ||
|
|
||||||
((Block == E_BLOCK_TRIPWIRE_HOOK) && ((Meta & 0x08) == 0))
|
((Block == E_BLOCK_TRIPWIRE_HOOK) && ((Meta & 0x08) == 0))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
LOGD("cIncrementalRedstoneSimulator: 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);
|
LOGD("cIncrementalRedstoneSimulator: 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);
|
||||||
itr = PoweredBlocks->erase(itr);
|
itr = PoweredBlocks->erase(itr);
|
||||||
a_Chunk->SetIsRedstoneDirty(true);
|
|
||||||
OtherChunk->SetIsRedstoneDirty(true);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (Block == E_BLOCK_DAYLIGHT_SENSOR)
|
|
||||||
{
|
|
||||||
if (!m_World.IsChunkLighted(OtherChunk->GetPosX(), OtherChunk->GetPosZ()))
|
|
||||||
{
|
|
||||||
m_World.QueueLightChunk(OtherChunk->GetPosX(), OtherChunk->GetPosZ());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (OtherChunk->GetTimeAlteredLight(OtherChunk->GetSkyLight(RelX, a_BlockY + 1, RelZ)) <= 7)
|
|
||||||
{
|
|
||||||
itr = PoweredBlocks->erase(itr);
|
|
||||||
a_Chunk->SetIsRedstoneDirty(true);
|
|
||||||
OtherChunk->SetIsRedstoneDirty(true);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,23 +124,17 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
|
|||||||
{
|
{
|
||||||
LOGD("cIncrementalRedstoneSimulator: 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);
|
LOGD("cIncrementalRedstoneSimulator: 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);
|
||||||
itr = LinkedPoweredBlocks->erase(itr);
|
itr = LinkedPoweredBlocks->erase(itr);
|
||||||
a_Chunk->SetIsRedstoneDirty(true);
|
|
||||||
OtherChunk->SetIsRedstoneDirty(true);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
// Things that can send power through a block but which depends on meta
|
// Things that can send power through a block but which depends on meta
|
||||||
((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) ||
|
((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) ||
|
||||||
((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) ||
|
((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) ||
|
||||||
(((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta))) ||
|
(((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)) ||
|
|
||||||
(((Block == E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE) || (Block == E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE)) && (Meta == 0))
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
LOGD("cIncrementalRedstoneSimulator: 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);
|
LOGD("cIncrementalRedstoneSimulator: 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);
|
||||||
itr = LinkedPoweredBlocks->erase(itr);
|
itr = LinkedPoweredBlocks->erase(itr);
|
||||||
a_Chunk->SetIsRedstoneDirty(true);
|
|
||||||
OtherChunk->SetIsRedstoneDirty(true);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,8 +144,6 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
|
|||||||
{
|
{
|
||||||
LOGD("cIncrementalRedstoneSimulator: 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);
|
LOGD("cIncrementalRedstoneSimulator: 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);
|
||||||
itr = LinkedPoweredBlocks->erase(itr);
|
itr = LinkedPoweredBlocks->erase(itr);
|
||||||
a_Chunk->SetIsRedstoneDirty(true);
|
|
||||||
OtherChunk->SetIsRedstoneDirty(true);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -320,6 +290,7 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
|
|||||||
case E_BLOCK_FENCE_GATE: HandleFenceGate(dataitr->x, dataitr->y, dataitr->z); break;
|
case E_BLOCK_FENCE_GATE: HandleFenceGate(dataitr->x, dataitr->y, dataitr->z); break;
|
||||||
case E_BLOCK_TNT: HandleTNT(dataitr->x, dataitr->y, dataitr->z); break;
|
case E_BLOCK_TNT: HandleTNT(dataitr->x, dataitr->y, dataitr->z); break;
|
||||||
case E_BLOCK_TRAPDOOR: HandleTrapdoor(dataitr->x, dataitr->y, dataitr->z); break;
|
case E_BLOCK_TRAPDOOR: HandleTrapdoor(dataitr->x, dataitr->y, dataitr->z); break;
|
||||||
|
case E_BLOCK_TRAPPED_CHEST: HandleTrappedChest(dataitr->x, dataitr->y, dataitr->z); break;
|
||||||
|
|
||||||
case E_BLOCK_ACTIVATOR_RAIL:
|
case E_BLOCK_ACTIVATOR_RAIL:
|
||||||
case E_BLOCK_DETECTOR_RAIL:
|
case E_BLOCK_DETECTOR_RAIL:
|
||||||
@ -382,18 +353,13 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
|
|||||||
|
|
||||||
void cIncrementalRedstoneSimulator::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk)
|
void cIncrementalRedstoneSimulator::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk)
|
||||||
{
|
{
|
||||||
if (
|
if (AreCoordsOnChunkBoundary(a_BlockX, a_BlockY, a_BlockZ))
|
||||||
((a_BlockX % cChunkDef::Width) <= 1) ||
|
|
||||||
((a_BlockX % cChunkDef::Width) >= 14) ||
|
|
||||||
((a_BlockZ % cChunkDef::Width) <= 1) ||
|
|
||||||
((a_BlockZ % cChunkDef::Width) >= 14)
|
|
||||||
) // Are we on a chunk boundary? +- 2 because of LinkedPowered blocks
|
|
||||||
{
|
{
|
||||||
// On a chunk boundary, alert all four sides (i.e. at least one neighbouring chunk)
|
// On a chunk boundary, alert all four sides (i.e. at least one neighbouring chunk)
|
||||||
AddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk);
|
AddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk);
|
||||||
|
|
||||||
// Pass the original coordinates, because when adding things to our simulator lists, we get the chunk that they are in, and therefore any updates need to preseve their position
|
// Pass the original coordinates, because when adding things to our simulator lists, we get the chunk that they are in, and therefore any updates need to preseve their position
|
||||||
// RedstoneAddBlock to pass both the neighbouring chunk and the chunk which the coordiantes are in and +- 2 in GetNeighbour() to accomodate for LinkedPowered blocks being 2 away from chunk boundaries
|
// RedstoneAddBlock to pass both the neighbouring chunk and the chunk which the coordinates are in and +- 2 in GetNeighbour() to accomodate for LinkedPowered blocks being 2 away from chunk boundaries
|
||||||
RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX - 2, a_BlockZ), a_Chunk);
|
RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX - 2, a_BlockZ), a_Chunk);
|
||||||
RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX + 2, a_BlockZ), a_Chunk);
|
RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX + 2, a_BlockZ), a_Chunk);
|
||||||
RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ - 2), a_Chunk);
|
RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ - 2), a_Chunk);
|
||||||
@ -448,7 +414,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneTorch(int a_RelBlockX, int a_R
|
|||||||
if (i + 1 < ARRAYCOUNT(gCrossCoords)) // Sides of torch, not top (top is last)
|
if (i + 1 < ARRAYCOUNT(gCrossCoords)) // Sides of torch, not top (top is last)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
((IsMechanism(Type)) || (Type == E_BLOCK_REDSTONE_WIRE)) && // Is it a mechanism or wire? Not block/other torch etc.
|
IsMechanism(Type) && // Is it a mechanism? Not block/other torch etc.
|
||||||
(!Vector3i(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z).Equals(Vector3i(X, Y, Z))) // CAN'T power block is that it is on
|
(!Vector3i(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z).Equals(Vector3i(X, Y, Z))) // CAN'T power block is that it is on
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -468,7 +434,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneTorch(int a_RelBlockX, int a_R
|
|||||||
{
|
{
|
||||||
BLOCKTYPE Type = m_Chunk->GetBlock(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ);
|
BLOCKTYPE Type = m_Chunk->GetBlock(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ);
|
||||||
|
|
||||||
if ((IsMechanism(Type)) || (Type == E_BLOCK_REDSTONE_WIRE)) // Still can't make a normal block powered though!
|
if (IsMechanism(Type)) // Still can't make a normal block powered though!
|
||||||
{
|
{
|
||||||
SetBlockPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
|
SetBlockPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
|
||||||
}
|
}
|
||||||
@ -780,17 +746,20 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeaterDelays()
|
|||||||
{
|
{
|
||||||
for (RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end();)
|
for (RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end();)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (itr->a_ElapsedTicks >= itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks?
|
if (itr->a_ElapsedTicks >= itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks?
|
||||||
{
|
{
|
||||||
int RelBlockX = itr->a_RelBlockPos.x;
|
int RelBlockX = itr->a_RelBlockPos.x;
|
||||||
int RelBlockY = itr->a_RelBlockPos.y;
|
int RelBlockY = itr->a_RelBlockPos.y;
|
||||||
int RelBlockZ = itr->a_RelBlockPos.z;
|
int RelBlockZ = itr->a_RelBlockPos.z;
|
||||||
NIBBLETYPE Meta = m_Chunk->GetMeta(RelBlockX, RelBlockY, RelBlockZ);
|
BLOCKTYPE Block;
|
||||||
|
NIBBLETYPE Meta;
|
||||||
|
m_Chunk->GetBlockTypeMeta(RelBlockX, RelBlockY, RelBlockZ, Block, Meta);
|
||||||
if (itr->ShouldPowerOn)
|
if (itr->ShouldPowerOn)
|
||||||
{
|
{
|
||||||
|
if (Block != E_BLOCK_REDSTONE_REPEATER_ON) // For performance
|
||||||
m_Chunk->SetBlock(itr->a_RelBlockPos, E_BLOCK_REDSTONE_REPEATER_ON, Meta); // For performance
|
{
|
||||||
|
m_Chunk->SetBlock(itr->a_RelBlockPos, E_BLOCK_REDSTONE_REPEATER_ON, Meta);
|
||||||
|
}
|
||||||
|
|
||||||
switch (Meta & 0x3) // We only want the direction (bottom) bits
|
switch (Meta & 0x3) // We only want the direction (bottom) bits
|
||||||
{
|
{
|
||||||
@ -820,7 +789,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeaterDelays()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (Block != E_BLOCK_REDSTONE_REPEATER_OFF)
|
||||||
{
|
{
|
||||||
m_Chunk->SetBlock(RelBlockX, RelBlockY, RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, Meta);
|
m_Chunk->SetBlock(RelBlockX, RelBlockY, RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, Meta);
|
||||||
}
|
}
|
||||||
@ -828,9 +797,6 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeaterDelays()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 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_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z, itr->a_ElapsedTicks, itr->a_DelayTicks);
|
LOGD("Incremented a repeater @ {%i %i %i} | Elapsed ticks: %i | Target delay: %i", itr->a_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z, itr->a_ElapsedTicks, itr->a_DelayTicks);
|
||||||
itr->a_ElapsedTicks++;
|
itr->a_ElapsedTicks++;
|
||||||
itr++;
|
itr++;
|
||||||
@ -1139,7 +1105,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x0);
|
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x0);
|
||||||
WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
|
SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1206,7 +1172,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
|||||||
m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
|
m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
|
||||||
}
|
}
|
||||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED);
|
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED);
|
||||||
WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
|
SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -1274,7 +1240,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
|||||||
m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
|
m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
|
||||||
}
|
}
|
||||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED);
|
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED);
|
||||||
WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
|
SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -1341,7 +1307,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
|||||||
m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
|
m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
|
||||||
}
|
}
|
||||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED);
|
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED);
|
||||||
WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
|
SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1384,14 +1350,14 @@ void cIncrementalRedstoneSimulator::HandleTripwireHook(int a_RelBlockX, int a_Re
|
|||||||
{
|
{
|
||||||
if (ReverseBlockFace(cBlockTripwireHookHandler::MetadataToDirection(Meta)) == FaceToGoTowards)
|
if (ReverseBlockFace(cBlockTripwireHookHandler::MetadataToDirection(Meta)) == FaceToGoTowards)
|
||||||
{
|
{
|
||||||
// Other hook not facing in opposite direction
|
// Other hook facing in opposite direction - circuit completed!
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Tripwire hook not connected at all, AND away all the power state bits
|
// Tripwire hook not connected at all, AND away all the power state bits
|
||||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x3);
|
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x3);
|
||||||
WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
|
SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1399,7 +1365,7 @@ void cIncrementalRedstoneSimulator::HandleTripwireHook(int a_RelBlockX, int a_Re
|
|||||||
{
|
{
|
||||||
// Tripwire hook not connected at all, AND away all the power state bits
|
// Tripwire hook not connected at all, AND away all the power state bits
|
||||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x3);
|
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x3);
|
||||||
WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
|
SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1414,7 +1380,51 @@ void cIncrementalRedstoneSimulator::HandleTripwireHook(int a_RelBlockX, int a_Re
|
|||||||
{
|
{
|
||||||
// Connected but not activated, AND away the highest bit
|
// Connected but not activated, AND away the highest bit
|
||||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, (m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x7) | 0x4);
|
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, (m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x7) | 0x4);
|
||||||
WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
|
SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cIncrementalRedstoneSimulator::HandleTrappedChest(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
|
||||||
|
{
|
||||||
|
class cGetTrappedChestPlayers :
|
||||||
|
public cChestCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cGetTrappedChestPlayers(void) :
|
||||||
|
m_NumberOfPlayers(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool Item(cChestEntity * a_Chest) override
|
||||||
|
{
|
||||||
|
ASSERT(a_Chest->GetBlockType() == E_BLOCK_TRAPPED_CHEST);
|
||||||
|
m_NumberOfPlayers = a_Chest->GetNumberOfPlayers();
|
||||||
|
return (m_NumberOfPlayers <= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char GetPowerLevel(void) const
|
||||||
|
{
|
||||||
|
return std::min(m_NumberOfPlayers, MAX_POWER_LEVEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_NumberOfPlayers;
|
||||||
|
|
||||||
|
} GTCP;
|
||||||
|
|
||||||
|
int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX;
|
||||||
|
int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ;
|
||||||
|
if (m_Chunk->DoWithChestAt(BlockX, a_RelBlockY, BlockZ, GTCP))
|
||||||
|
{
|
||||||
|
SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, GTCP.GetPowerLevel());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1691,8 +1701,8 @@ bool cIncrementalRedstoneSimulator::IsPistonPowered(int a_RelBlockX, int a_RelBl
|
|||||||
bool cIncrementalRedstoneSimulator::IsWirePowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char & a_PowerLevel)
|
bool cIncrementalRedstoneSimulator::IsWirePowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char & a_PowerLevel)
|
||||||
{
|
{
|
||||||
a_PowerLevel = 0;
|
a_PowerLevel = 0;
|
||||||
int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
|
int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX;
|
||||||
int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
|
int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ;
|
||||||
|
|
||||||
for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr) // Check powered list
|
for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr) // Check powered list
|
||||||
{
|
{
|
||||||
@ -1709,6 +1719,14 @@ bool cIncrementalRedstoneSimulator::IsWirePowered(int a_RelBlockX, int a_RelBloc
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BLOCKTYPE Type = E_BLOCK_AIR;
|
||||||
|
int RelSourceX = itr->a_SourcePos.x - m_Chunk->GetPosX() * cChunkDef::Width;
|
||||||
|
int RelSourceZ = itr->a_SourcePos.z - m_Chunk->GetPosZ() * cChunkDef::Width;
|
||||||
|
if (!m_Chunk->UnboundedRelGetBlockType(RelSourceX, itr->a_SourcePos.y, RelSourceZ, Type) || (Type == E_BLOCK_REDSTONE_WIRE))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
a_PowerLevel = std::max(itr->a_PowerLevel, a_PowerLevel);
|
a_PowerLevel = std::max(itr->a_PowerLevel, a_PowerLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1881,20 +1899,9 @@ void cIncrementalRedstoneSimulator::SetBlockPowered(int a_RelBlockX, int a_RelBl
|
|||||||
int SourceX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelSourceX;
|
int SourceX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelSourceX;
|
||||||
int SourceZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelSourceZ;
|
int SourceZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelSourceZ;
|
||||||
|
|
||||||
BLOCKTYPE Block = 0;
|
cChunk * Neighbour = m_Chunk->GetRelNeighborChunkAdjustCoords(a_RelBlockX, a_RelBlockZ); // Adjust coordinates for the later call using these values
|
||||||
if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Block))
|
PoweredBlocksList * Powered = Neighbour->GetRedstoneSimulatorPoweredBlocksList(); // We need to insert the value into the chunk who owns the block position
|
||||||
{
|
for (PoweredBlocksList::iterator itr = Powered->begin(); itr != Powered->end(); ++itr)
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Block == E_BLOCK_AIR)
|
|
||||||
{
|
|
||||||
// Don't set air, fixes some bugs (wires powering themselves)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cChunk * Neighbour = m_Chunk->GetNeighborChunk(BlockX, BlockZ);
|
|
||||||
PoweredBlocksList * Powered = Neighbour->GetRedstoneSimulatorPoweredBlocksList();
|
|
||||||
for (PoweredBlocksList::iterator itr = Powered->begin(); itr != Powered->end(); ++itr) // Check powered list
|
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) &&
|
itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) &&
|
||||||
@ -1907,18 +1914,35 @@ void cIncrementalRedstoneSimulator::SetBlockPowered(int a_RelBlockX, int a_RelBl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PoweredBlocksList * OtherPowered = m_Chunk->GetNeighborChunk(SourceX, SourceZ)->GetRedstoneSimulatorPoweredBlocksList();
|
// No need to get neighbouring chunk as we can guarantee that when something is powering us, the entry will be in our chunk
|
||||||
for (PoweredBlocksList::const_iterator itr = OtherPowered->begin(); itr != OtherPowered->end(); ++itr) // Check powered list
|
// TODO: on C++11 support, change this to a llama function pased to a std::remove_if
|
||||||
|
for (PoweredBlocksList::iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
itr->a_BlockPos.Equals(Vector3i(SourceX, a_RelSourceY, SourceZ)) &&
|
itr->a_BlockPos.Equals(Vector3i(SourceX, a_RelSourceY, SourceZ)) &&
|
||||||
itr->a_SourcePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))
|
itr->a_SourcePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) &&
|
||||||
|
(m_Chunk->GetBlock(a_RelSourceX, a_RelSourceY, a_RelSourceZ) == E_BLOCK_REDSTONE_WIRE)
|
||||||
)
|
)
|
||||||
|
{
|
||||||
|
BLOCKTYPE Block;
|
||||||
|
NIBBLETYPE Meta;
|
||||||
|
Neighbour->GetBlockTypeMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Block, Meta);
|
||||||
|
|
||||||
|
if (Block == E_BLOCK_REDSTONE_WIRE)
|
||||||
|
{
|
||||||
|
if (Meta < a_PowerLevel)
|
||||||
|
{
|
||||||
|
m_PoweredBlocks->erase(itr); // Powering source with higher power level, allow it
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// Powered wires try to power their source - don't let them!
|
// Powered wires try to power their source - don't let them!
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sPoweredBlocks RC;
|
sPoweredBlocks RC;
|
||||||
RC.a_BlockPos = Vector3i(BlockX, a_RelBlockY, BlockZ);
|
RC.a_BlockPos = Vector3i(BlockX, a_RelBlockY, BlockZ);
|
||||||
@ -1947,20 +1971,6 @@ void cIncrementalRedstoneSimulator::SetBlockLinkedPowered(
|
|||||||
int SourceX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelSourceX;
|
int SourceX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelSourceX;
|
||||||
int SourceZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelSourceZ;
|
int SourceZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelSourceZ;
|
||||||
|
|
||||||
BLOCKTYPE DestBlock = 0;
|
|
||||||
if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ, DestBlock))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (DestBlock == E_BLOCK_AIR)
|
|
||||||
{
|
|
||||||
// Don't set air, fixes some bugs (wires powering themselves)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((DestBlock == E_BLOCK_REDSTONE_WIRE) && (m_Chunk->GetBlock(a_RelSourceX, a_RelSourceY, a_RelSourceZ) == E_BLOCK_REDSTONE_WIRE))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!IsViableMiddleBlock(a_MiddleBlock))
|
if (!IsViableMiddleBlock(a_MiddleBlock))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -2066,6 +2076,45 @@ bool cIncrementalRedstoneSimulator::QueueRepeaterPowerChange(int a_RelBlockX, in
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cIncrementalRedstoneSimulator::SetSourceUnpowered(int a_SourceX, int a_SourceY, int a_SourceZ, cChunk * a_Chunk, bool a_IsFirstCall)
|
||||||
|
{
|
||||||
|
// TODO: on C++11 support, change both of these to llama functions pased to a std::remove_if
|
||||||
|
|
||||||
|
for (PoweredBlocksList::iterator itr = a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->begin(); itr != a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->end();)
|
||||||
|
{
|
||||||
|
if (itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ)))
|
||||||
|
{
|
||||||
|
itr = a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->erase(itr);
|
||||||
|
a_Chunk->SetIsRedstoneDirty(true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++itr;
|
||||||
|
}
|
||||||
|
for (LinkedBlocksList::iterator itr = a_Chunk->GetRedstoneSimulatorLinkedBlocksList()->begin(); itr != a_Chunk->GetRedstoneSimulatorLinkedBlocksList()->end();)
|
||||||
|
{
|
||||||
|
if (itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ)))
|
||||||
|
{
|
||||||
|
itr = a_Chunk->GetRedstoneSimulatorLinkedBlocksList()->erase(itr);
|
||||||
|
a_Chunk->SetIsRedstoneDirty(true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++itr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a_IsFirstCall && AreCoordsOnChunkBoundary(a_SourceX, a_SourceY, a_SourceZ))
|
||||||
|
{
|
||||||
|
// +- 2 to accomodate linked powered blocks
|
||||||
|
SetSourceUnpowered(a_SourceX, a_SourceY, a_SourceZ, a_Chunk->GetNeighborChunk(a_SourceX - 2, a_SourceZ), false);
|
||||||
|
SetSourceUnpowered(a_SourceX, a_SourceY, a_SourceZ, a_Chunk->GetNeighborChunk(a_SourceX + 2, a_SourceZ), false);
|
||||||
|
SetSourceUnpowered(a_SourceX, a_SourceY, a_SourceZ, a_Chunk->GetNeighborChunk(a_SourceX, a_SourceZ - 2), false);
|
||||||
|
SetSourceUnpowered(a_SourceX, a_SourceY, a_SourceZ, a_Chunk->GetNeighborChunk(a_SourceX, a_SourceZ + 2), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cIncrementalRedstoneSimulator::eRedstoneDirection cIncrementalRedstoneSimulator::GetWireDirection(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
|
cIncrementalRedstoneSimulator::eRedstoneDirection cIncrementalRedstoneSimulator::GetWireDirection(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
|
||||||
{
|
{
|
||||||
int Dir = REDSTONE_NONE;
|
int Dir = REDSTONE_NONE;
|
||||||
|
@ -107,6 +107,8 @@ private:
|
|||||||
If this line is complete, it verifies that at least on wire reports an entity is on top (via its meta), and performs its task
|
If this line is complete, it verifies that at least on wire reports an entity is on top (via its meta), and performs its task
|
||||||
*/
|
*/
|
||||||
void HandleTripwireHook(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
void HandleTripwireHook(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/** Handles trapped chests */
|
||||||
|
void HandleTrappedChest(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
/* ==================== */
|
/* ==================== */
|
||||||
|
|
||||||
/* ====== CARRIERS ====== */
|
/* ====== CARRIERS ====== */
|
||||||
@ -114,8 +116,6 @@ private:
|
|||||||
void HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
void HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
/** Handles repeaters */
|
/** Handles repeaters */
|
||||||
void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
|
void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
|
||||||
/** Handles delayed updates to Repeaters **/
|
|
||||||
void HandleRedstoneRepeaterDelays();
|
|
||||||
/* ====================== */
|
/* ====================== */
|
||||||
|
|
||||||
/* ====== DEVICES ====== */
|
/* ====== DEVICES ====== */
|
||||||
@ -156,6 +156,10 @@ private:
|
|||||||
void SetAllDirsAsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
void SetAllDirsAsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||||
/** Queues a repeater to be powered or unpowered and returns if the m_RepeatersDelayList iterators were invalidated */
|
/** Queues a repeater to be powered or unpowered and returns if the m_RepeatersDelayList iterators were invalidated */
|
||||||
bool QueueRepeaterPowerChange(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn);
|
bool QueueRepeaterPowerChange(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn);
|
||||||
|
/** Removes a block from the Powered and LinkedPowered lists
|
||||||
|
Used for variable sources such as tripwire hooks, daylight sensors, and trapped chests
|
||||||
|
*/
|
||||||
|
void SetSourceUnpowered(int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, cChunk * a_Chunk, bool a_IsFirstCall = true);
|
||||||
|
|
||||||
/** Returns if a coordinate is powered or linked powered */
|
/** Returns if a coordinate is powered or linked powered */
|
||||||
bool AreCoordsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { return AreCoordsDirectlyPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ) || AreCoordsLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); }
|
bool AreCoordsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { return AreCoordsDirectlyPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ) || AreCoordsLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); }
|
||||||
@ -174,7 +178,8 @@ private:
|
|||||||
/** Returns if a wire is powered
|
/** 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 */
|
The only diffence between this and a normal AreCoordsPowered is that this function checks for a wire powering another wire */
|
||||||
bool IsWirePowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char & a_PowerLevel);
|
bool IsWirePowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char & a_PowerLevel);
|
||||||
|
/** Handles delayed updates to repeaters **/
|
||||||
|
void HandleRedstoneRepeaterDelays(void);
|
||||||
|
|
||||||
/** Returns if lever metadata marks it as emitting power */
|
/** Returns if lever metadata marks it as emitting power */
|
||||||
bool IsLeverOn(NIBBLETYPE a_BlockMeta);
|
bool IsLeverOn(NIBBLETYPE a_BlockMeta);
|
||||||
@ -186,7 +191,9 @@ private:
|
|||||||
/** Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation */
|
/** Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation */
|
||||||
inline static bool IsViableMiddleBlock(BLOCKTYPE Block) { return cBlockInfo::FullyOccupiesVoxel(Block); }
|
inline static bool IsViableMiddleBlock(BLOCKTYPE Block) { return cBlockInfo::FullyOccupiesVoxel(Block); }
|
||||||
|
|
||||||
/** Returns if a block is a mechanism (something that accepts power and does something) */
|
/** Returns if a block is a mechanism (something that accepts power and does something)
|
||||||
|
Used by torches to determine if they power a block whilst not standing on the ground
|
||||||
|
*/
|
||||||
inline static bool IsMechanism(BLOCKTYPE Block)
|
inline static bool IsMechanism(BLOCKTYPE Block)
|
||||||
{
|
{
|
||||||
switch (Block)
|
switch (Block)
|
||||||
@ -209,6 +216,7 @@ private:
|
|||||||
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
||||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||||
case E_BLOCK_POWERED_RAIL:
|
case E_BLOCK_POWERED_RAIL:
|
||||||
|
case E_BLOCK_REDSTONE_WIRE:
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -235,6 +243,7 @@ private:
|
|||||||
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
|
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
|
||||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||||
|
case E_BLOCK_TRAPPED_CHEST:
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -277,6 +286,7 @@ private:
|
|||||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||||
case E_BLOCK_TNT:
|
case E_BLOCK_TNT:
|
||||||
case E_BLOCK_TRAPDOOR:
|
case E_BLOCK_TRAPDOOR:
|
||||||
|
case E_BLOCK_TRAPPED_CHEST:
|
||||||
case E_BLOCK_TRIPWIRE_HOOK:
|
case E_BLOCK_TRIPWIRE_HOOK:
|
||||||
case E_BLOCK_TRIPWIRE:
|
case E_BLOCK_TRIPWIRE:
|
||||||
case E_BLOCK_WOODEN_BUTTON:
|
case E_BLOCK_WOODEN_BUTTON:
|
||||||
@ -289,6 +299,16 @@ private:
|
|||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static bool AreCoordsOnChunkBoundary(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
|
{
|
||||||
|
return ( // Are we on a chunk boundary? +- 2 because of LinkedPowered blocks
|
||||||
|
((a_BlockX % cChunkDef::Width) <= 1) ||
|
||||||
|
((a_BlockX % cChunkDef::Width) >= 14) ||
|
||||||
|
((a_BlockZ % cChunkDef::Width) <= 1) ||
|
||||||
|
((a_BlockZ % cChunkDef::Width) >= 14)
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -905,11 +905,13 @@ void cEnchantingWindow::GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ)
|
|||||||
// cChestWindow:
|
// cChestWindow:
|
||||||
|
|
||||||
cChestWindow::cChestWindow(cChestEntity * a_Chest) :
|
cChestWindow::cChestWindow(cChestEntity * a_Chest) :
|
||||||
cWindow(wtChest, "Chest"),
|
cWindow(wtChest, (a_Chest->GetBlockType() == E_BLOCK_CHEST) ? "Chest" : "Trapped Chest"),
|
||||||
m_World(a_Chest->GetWorld()),
|
m_World(a_Chest->GetWorld()),
|
||||||
m_BlockX(a_Chest->GetPosX()),
|
m_BlockX(a_Chest->GetPosX()),
|
||||||
m_BlockY(a_Chest->GetPosY()),
|
m_BlockY(a_Chest->GetPosY()),
|
||||||
m_BlockZ(a_Chest->GetPosZ())
|
m_BlockZ(a_Chest->GetPosZ()),
|
||||||
|
m_PrimaryChest(a_Chest),
|
||||||
|
m_SecondaryChest(NULL)
|
||||||
{
|
{
|
||||||
m_SlotAreas.push_back(new cSlotAreaChest(a_Chest, *this));
|
m_SlotAreas.push_back(new cSlotAreaChest(a_Chest, *this));
|
||||||
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
|
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
|
||||||
@ -919,7 +921,7 @@ cChestWindow::cChestWindow(cChestEntity * a_Chest) :
|
|||||||
m_World->BroadcastSoundEffect("random.chestopen", m_BlockX * 8, m_BlockY * 8, m_BlockZ * 8, 1, 1);
|
m_World->BroadcastSoundEffect("random.chestopen", m_BlockX * 8, m_BlockY * 8, m_BlockZ * 8, 1, 1);
|
||||||
|
|
||||||
// Send out the chest-open packet:
|
// Send out the chest-open packet:
|
||||||
m_World->BroadcastBlockAction(m_BlockX, m_BlockY, m_BlockZ, 1, 1, E_BLOCK_CHEST);
|
m_World->BroadcastBlockAction(m_BlockX, m_BlockY, m_BlockZ, 1, 1, a_Chest->GetBlockType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -927,11 +929,13 @@ cChestWindow::cChestWindow(cChestEntity * a_Chest) :
|
|||||||
|
|
||||||
|
|
||||||
cChestWindow::cChestWindow(cChestEntity * a_PrimaryChest, cChestEntity * a_SecondaryChest) :
|
cChestWindow::cChestWindow(cChestEntity * a_PrimaryChest, cChestEntity * a_SecondaryChest) :
|
||||||
cWindow(wtChest, "Double Chest"),
|
cWindow(wtChest, (a_PrimaryChest->GetBlockType() == E_BLOCK_CHEST) ? "Double Chest" : "Double Trapped Chest"),
|
||||||
m_World(a_PrimaryChest->GetWorld()),
|
m_World(a_PrimaryChest->GetWorld()),
|
||||||
m_BlockX(a_PrimaryChest->GetPosX()),
|
m_BlockX(a_PrimaryChest->GetPosX()),
|
||||||
m_BlockY(a_PrimaryChest->GetPosY()),
|
m_BlockY(a_PrimaryChest->GetPosY()),
|
||||||
m_BlockZ(a_PrimaryChest->GetPosZ())
|
m_BlockZ(a_PrimaryChest->GetPosZ()),
|
||||||
|
m_PrimaryChest(a_PrimaryChest),
|
||||||
|
m_SecondaryChest(a_SecondaryChest)
|
||||||
{
|
{
|
||||||
m_SlotAreas.push_back(new cSlotAreaDoubleChest(a_PrimaryChest, a_SecondaryChest, *this));
|
m_SlotAreas.push_back(new cSlotAreaDoubleChest(a_PrimaryChest, a_SecondaryChest, *this));
|
||||||
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
|
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
|
||||||
@ -943,7 +947,52 @@ cChestWindow::cChestWindow(cChestEntity * a_PrimaryChest, cChestEntity * a_Secon
|
|||||||
m_World->BroadcastSoundEffect("random.chestopen", m_BlockX * 8, m_BlockY * 8, m_BlockZ * 8, 1, 1);
|
m_World->BroadcastSoundEffect("random.chestopen", m_BlockX * 8, m_BlockY * 8, m_BlockZ * 8, 1, 1);
|
||||||
|
|
||||||
// Send out the chest-open packet:
|
// Send out the chest-open packet:
|
||||||
m_World->BroadcastBlockAction(m_BlockX, m_BlockY, m_BlockZ, 1, 1, E_BLOCK_CHEST);
|
m_World->BroadcastBlockAction(m_BlockX, m_BlockY, m_BlockZ, 1, 1, a_PrimaryChest->GetBlockType());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cChestWindow::OpenedByPlayer(cPlayer & a_Player)
|
||||||
|
{
|
||||||
|
int ChunkX, ChunkZ;
|
||||||
|
|
||||||
|
m_PrimaryChest->SetNumberOfPlayers(m_PrimaryChest->GetNumberOfPlayers() + 1);
|
||||||
|
cChunkDef::BlockToChunk(m_PrimaryChest->GetPosX(), m_PrimaryChest->GetPosZ(), ChunkX, ChunkZ);
|
||||||
|
m_PrimaryChest->GetWorld()->MarkRedstoneDirty(ChunkX, ChunkZ);
|
||||||
|
|
||||||
|
if (m_SecondaryChest != NULL)
|
||||||
|
{
|
||||||
|
m_SecondaryChest->SetNumberOfPlayers(m_SecondaryChest->GetNumberOfPlayers() + 1);
|
||||||
|
cChunkDef::BlockToChunk(m_SecondaryChest->GetPosX(), m_SecondaryChest->GetPosZ(), ChunkX, ChunkZ);
|
||||||
|
m_SecondaryChest->GetWorld()->MarkRedstoneDirty(ChunkX, ChunkZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
cWindow::OpenedByPlayer(a_Player);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cChestWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse)
|
||||||
|
{
|
||||||
|
int ChunkX, ChunkZ;
|
||||||
|
|
||||||
|
m_PrimaryChest->SetNumberOfPlayers(m_PrimaryChest->GetNumberOfPlayers() - 1);
|
||||||
|
cChunkDef::BlockToChunk(m_PrimaryChest->GetPosX(), m_PrimaryChest->GetPosZ(), ChunkX, ChunkZ);
|
||||||
|
m_PrimaryChest->GetWorld()->MarkRedstoneDirty(ChunkX, ChunkZ);
|
||||||
|
|
||||||
|
if (m_SecondaryChest != NULL)
|
||||||
|
{
|
||||||
|
m_SecondaryChest->SetNumberOfPlayers(m_SecondaryChest->GetNumberOfPlayers() - 1);
|
||||||
|
cChunkDef::BlockToChunk(m_SecondaryChest->GetPosX(), m_SecondaryChest->GetPosZ(), ChunkX, ChunkZ);
|
||||||
|
m_SecondaryChest->GetWorld()->MarkRedstoneDirty(ChunkX, ChunkZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
cWindow::ClosedByPlayer(a_Player, a_CanRefuse);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -953,7 +1002,7 @@ cChestWindow::cChestWindow(cChestEntity * a_PrimaryChest, cChestEntity * a_Secon
|
|||||||
cChestWindow::~cChestWindow()
|
cChestWindow::~cChestWindow()
|
||||||
{
|
{
|
||||||
// Send out the chest-close packet:
|
// Send out the chest-close packet:
|
||||||
m_World->BroadcastBlockAction(m_BlockX, m_BlockY, m_BlockZ, 1, 0, E_BLOCK_CHEST);
|
m_World->BroadcastBlockAction(m_BlockX, m_BlockY, m_BlockZ, 1, 0, m_PrimaryChest->GetBlockType());
|
||||||
|
|
||||||
m_World->BroadcastSoundEffect("random.chestclosed", m_BlockX * 8, m_BlockY * 8, m_BlockZ * 8, 1, 1);
|
m_World->BroadcastSoundEffect("random.chestclosed", m_BlockX * 8, m_BlockY * 8, m_BlockZ * 8, 1, 1);
|
||||||
}
|
}
|
||||||
@ -966,7 +1015,7 @@ cChestWindow::~cChestWindow()
|
|||||||
// cDropSpenserWindow:
|
// cDropSpenserWindow:
|
||||||
|
|
||||||
cDropSpenserWindow::cDropSpenserWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserEntity * a_DropSpenser) :
|
cDropSpenserWindow::cDropSpenserWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserEntity * a_DropSpenser) :
|
||||||
cWindow(wtDropSpenser, "Dropspenser")
|
cWindow(wtDropSpenser, (a_DropSpenser->GetBlockType() == E_BLOCK_DISPENSER) ? "Dispenser" : "Dropper")
|
||||||
{
|
{
|
||||||
m_ShouldDistributeToHotbarFirst = false;
|
m_ShouldDistributeToHotbarFirst = false;
|
||||||
m_SlotAreas.push_back(new cSlotAreaItemGrid(a_DropSpenser->GetContents(), *this));
|
m_SlotAreas.push_back(new cSlotAreaItemGrid(a_DropSpenser->GetContents(), *this));
|
||||||
|
@ -114,7 +114,7 @@ public:
|
|||||||
const cItem & a_ClickedItem
|
const cItem & a_ClickedItem
|
||||||
);
|
);
|
||||||
|
|
||||||
void OpenedByPlayer(cPlayer & a_Player);
|
virtual void OpenedByPlayer(cPlayer & a_Player);
|
||||||
|
|
||||||
/// Called when a player closes this window; notifies all slot areas. Returns true if close accepted
|
/// Called when a player closes this window; notifies all slot areas. Returns true if close accepted
|
||||||
virtual bool ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse);
|
virtual bool ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse);
|
||||||
@ -328,9 +328,14 @@ public:
|
|||||||
cChestWindow(cChestEntity * a_PrimaryChest, cChestEntity * a_SecondaryChest);
|
cChestWindow(cChestEntity * a_PrimaryChest, cChestEntity * a_SecondaryChest);
|
||||||
~cChestWindow();
|
~cChestWindow();
|
||||||
|
|
||||||
|
virtual bool ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) override;
|
||||||
|
virtual void OpenedByPlayer(cPlayer & a_Player) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
cWorld * m_World;
|
cWorld * m_World;
|
||||||
int m_BlockX, m_BlockY, m_BlockZ; // Position of the chest, for the window-close packet
|
int m_BlockX, m_BlockY, m_BlockZ; // Position of the chest, for the window-close packet
|
||||||
|
cChestEntity * m_PrimaryChest;
|
||||||
|
cChestEntity * m_SecondaryChest;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
@ -389,8 +389,8 @@ void cWorld::InitializeSpawn(void)
|
|||||||
IniFile.WriteFile(m_IniFileName);
|
IniFile.WriteFile(m_IniFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ChunkX = 0, ChunkY = 0, ChunkZ = 0;
|
int ChunkX = 0, ChunkZ = 0;
|
||||||
BlockToChunk((int)m_SpawnX, (int)m_SpawnY, (int)m_SpawnZ, ChunkX, ChunkY, ChunkZ);
|
cChunkDef::BlockToChunk((int)m_SpawnX, (int)m_SpawnZ, ChunkX, ChunkZ);
|
||||||
|
|
||||||
// For the debugging builds, don't make the server build too much world upon start:
|
// For the debugging builds, don't make the server build too much world upon start:
|
||||||
#if defined(_DEBUG) || defined(ANDROID_NDK)
|
#if defined(_DEBUG) || defined(ANDROID_NDK)
|
||||||
@ -2182,9 +2182,18 @@ void cWorld::SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHa
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::MarkChunkDirty (int a_ChunkX, int a_ChunkZ)
|
void cWorld::MarkRedstoneDirty(int a_ChunkX, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
m_ChunkMap->MarkChunkDirty (a_ChunkX, a_ChunkZ);
|
m_ChunkMap->MarkRedstoneDirty(a_ChunkX, a_ChunkZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cWorld::MarkChunkDirty(int a_ChunkX, int a_ChunkZ, bool a_MarkRedstoneDirty)
|
||||||
|
{
|
||||||
|
m_ChunkMap->MarkChunkDirty(a_ChunkX, a_ChunkZ, a_MarkRedstoneDirty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
15
src/World.h
15
src/World.h
@ -241,7 +241,8 @@ public:
|
|||||||
/** If there is a block entity at the specified coords, sends it to the client specified */
|
/** If there is a block entity at the specified coords, sends it to the client specified */
|
||||||
void SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client);
|
void SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client);
|
||||||
|
|
||||||
void MarkChunkDirty (int a_ChunkX, int a_ChunkZ);
|
void MarkRedstoneDirty(int a_ChunkX, int a_ChunkZ);
|
||||||
|
void MarkChunkDirty (int a_ChunkX, int a_ChunkZ, bool a_MarkRedstoneDirty = false);
|
||||||
void MarkChunkSaving(int a_ChunkX, int a_ChunkZ);
|
void MarkChunkSaving(int a_ChunkX, int a_ChunkZ);
|
||||||
void MarkChunkSaved (int a_ChunkX, int a_ChunkZ);
|
void MarkChunkSaved (int a_ChunkX, int a_ChunkZ);
|
||||||
|
|
||||||
@ -634,18 +635,6 @@ public:
|
|||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
inline static void BlockToChunk( int a_X, int a_Y, int a_Z, int & a_ChunkX, int & a_ChunkY, int & a_ChunkZ )
|
|
||||||
{
|
|
||||||
// TODO: Use floor() instead of weird if statements
|
|
||||||
// Also fix Y
|
|
||||||
(void)a_Y; // not unused anymore
|
|
||||||
a_ChunkX = a_X/cChunkDef::Width;
|
|
||||||
if(a_X < 0 && a_X % cChunkDef::Width != 0) a_ChunkX--;
|
|
||||||
a_ChunkY = 0;
|
|
||||||
a_ChunkZ = a_Z/cChunkDef::Width;
|
|
||||||
if(a_Z < 0 && a_Z % cChunkDef::Width != 0) a_ChunkZ--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Saves all chunks immediately. Dangerous interface, may deadlock, use QueueSaveAllChunks() instead */
|
/** Saves all chunks immediately. Dangerous interface, may deadlock, use QueueSaveAllChunks() instead */
|
||||||
void SaveAllChunks(void);
|
void SaveAllChunks(void);
|
||||||
|
|
||||||
|
@ -175,10 +175,10 @@ void cNBTChunkSerializer::AddBasicTileEntity(cBlockEntity * a_Entity, const char
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cNBTChunkSerializer::AddChestEntity(cChestEntity * a_Entity)
|
void cNBTChunkSerializer::AddChestEntity(cChestEntity * a_Entity, BLOCKTYPE a_ChestType)
|
||||||
{
|
{
|
||||||
m_Writer.BeginCompound("");
|
m_Writer.BeginCompound("");
|
||||||
AddBasicTileEntity(a_Entity, "Chest");
|
AddBasicTileEntity(a_Entity, (a_ChestType == E_BLOCK_CHEST) ? "Chest" : "TrappedChest");
|
||||||
m_Writer.BeginList("Items", TAG_Compound);
|
m_Writer.BeginList("Items", TAG_Compound);
|
||||||
AddItemGrid(a_Entity->GetContents());
|
AddItemGrid(a_Entity->GetContents());
|
||||||
m_Writer.EndList();
|
m_Writer.EndList();
|
||||||
@ -813,19 +813,21 @@ void cNBTChunkSerializer::BlockEntity(cBlockEntity * a_Entity)
|
|||||||
// Add tile-entity into NBT:
|
// Add tile-entity into NBT:
|
||||||
switch (a_Entity->GetBlockType())
|
switch (a_Entity->GetBlockType())
|
||||||
{
|
{
|
||||||
case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity); break;
|
case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity, a_Entity->GetBlockType()); break;
|
||||||
|
case E_BLOCK_COMMAND_BLOCK: AddCommandBlockEntity((cCommandBlockEntity *)a_Entity); break;
|
||||||
case E_BLOCK_DISPENSER: AddDispenserEntity ((cDispenserEntity *) a_Entity); break;
|
case E_BLOCK_DISPENSER: AddDispenserEntity ((cDispenserEntity *) a_Entity); break;
|
||||||
case E_BLOCK_DROPPER: AddDropperEntity ((cDropperEntity *) a_Entity); break;
|
case E_BLOCK_DROPPER: AddDropperEntity ((cDropperEntity *) a_Entity); break;
|
||||||
case E_BLOCK_ENDER_CHEST: /* No need to be saved */ break;
|
case E_BLOCK_ENDER_CHEST: /* No data to be saved */ break;
|
||||||
case E_BLOCK_FLOWER_POT: AddFlowerPotEntity ((cFlowerPotEntity *) a_Entity); break;
|
case E_BLOCK_FLOWER_POT: AddFlowerPotEntity ((cFlowerPotEntity *) a_Entity); break;
|
||||||
case E_BLOCK_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) a_Entity); break;
|
case E_BLOCK_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) a_Entity); break;
|
||||||
case E_BLOCK_HOPPER: AddHopperEntity ((cHopperEntity *) a_Entity); break;
|
|
||||||
case E_BLOCK_SIGN_POST:
|
|
||||||
case E_BLOCK_WALLSIGN: AddSignEntity ((cSignEntity *) a_Entity); break;
|
|
||||||
case E_BLOCK_HEAD: AddMobHeadEntity ((cMobHeadEntity *) a_Entity); break;
|
case E_BLOCK_HEAD: AddMobHeadEntity ((cMobHeadEntity *) a_Entity); break;
|
||||||
case E_BLOCK_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break;
|
case E_BLOCK_HOPPER: AddHopperEntity ((cHopperEntity *) a_Entity); break;
|
||||||
case E_BLOCK_JUKEBOX: AddJukeboxEntity ((cJukeboxEntity *) a_Entity); break;
|
case E_BLOCK_JUKEBOX: AddJukeboxEntity ((cJukeboxEntity *) a_Entity); break;
|
||||||
case E_BLOCK_COMMAND_BLOCK: AddCommandBlockEntity((cCommandBlockEntity *) a_Entity); break;
|
case E_BLOCK_LIT_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) a_Entity); break;
|
||||||
|
case E_BLOCK_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break;
|
||||||
|
case E_BLOCK_SIGN_POST: AddSignEntity ((cSignEntity *) a_Entity); break;
|
||||||
|
case E_BLOCK_TRAPPED_CHEST: AddChestEntity ((cChestEntity *) a_Entity, a_Entity->GetBlockType()); break;
|
||||||
|
case E_BLOCK_WALLSIGN: AddSignEntity ((cSignEntity *) a_Entity); break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
@ -92,7 +92,7 @@ protected:
|
|||||||
|
|
||||||
// Block entities:
|
// Block entities:
|
||||||
void AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID);
|
void AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID);
|
||||||
void AddChestEntity (cChestEntity * a_Entity);
|
void AddChestEntity (cChestEntity * a_Entity, BLOCKTYPE a_ChestType);
|
||||||
void AddDispenserEntity(cDispenserEntity * a_Entity);
|
void AddDispenserEntity(cDispenserEntity * a_Entity);
|
||||||
void AddDropperEntity (cDropperEntity * a_Entity);
|
void AddDropperEntity (cDropperEntity * a_Entity);
|
||||||
void AddFurnaceEntity (cFurnaceEntity * a_Furnace);
|
void AddFurnaceEntity (cFurnaceEntity * a_Furnace);
|
||||||
|
@ -582,7 +582,7 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con
|
|||||||
}
|
}
|
||||||
if (strncmp(a_NBT.GetData(sID), "Chest", a_NBT.GetDataLength(sID)) == 0)
|
if (strncmp(a_NBT.GetData(sID), "Chest", a_NBT.GetDataLength(sID)) == 0)
|
||||||
{
|
{
|
||||||
LoadChestFromNBT(a_BlockEntities, a_NBT, Child);
|
LoadChestFromNBT(a_BlockEntities, a_NBT, Child, E_BLOCK_CHEST);
|
||||||
}
|
}
|
||||||
else if (strncmp(a_NBT.GetData(sID), "Control", a_NBT.GetDataLength(sID)) == 0)
|
else if (strncmp(a_NBT.GetData(sID), "Control", a_NBT.GetDataLength(sID)) == 0)
|
||||||
{
|
{
|
||||||
@ -624,6 +624,10 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con
|
|||||||
{
|
{
|
||||||
LoadDispenserFromNBT(a_BlockEntities, a_NBT, Child);
|
LoadDispenserFromNBT(a_BlockEntities, a_NBT, Child);
|
||||||
}
|
}
|
||||||
|
else if (strncmp(a_NBT.GetData(sID), "TrappedChest", a_NBT.GetDataLength(sID)) == 0)
|
||||||
|
{
|
||||||
|
LoadChestFromNBT(a_BlockEntities, a_NBT, Child, E_BLOCK_TRAPPED_CHEST);
|
||||||
|
}
|
||||||
// TODO: Other block entities
|
// TODO: Other block entities
|
||||||
} // for Child - tag children
|
} // for Child - tag children
|
||||||
}
|
}
|
||||||
@ -740,7 +744,7 @@ void cWSSAnvil::LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWSSAnvil::LoadChestFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
void cWSSAnvil::LoadChestFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_ChestType)
|
||||||
{
|
{
|
||||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
||||||
int x, y, z;
|
int x, y, z;
|
||||||
@ -753,7 +757,7 @@ void cWSSAnvil::LoadChestFromNBT(cBlockEntityList & a_BlockEntities, const cPars
|
|||||||
{
|
{
|
||||||
return; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this
|
return; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this
|
||||||
}
|
}
|
||||||
std::auto_ptr<cChestEntity> Chest(new cChestEntity(x, y, z, m_World));
|
std::auto_ptr<cChestEntity> Chest(new cChestEntity(x, y, z, m_World, a_ChestType));
|
||||||
LoadItemGridFromNBT(Chest->GetContents(), a_NBT, Items);
|
LoadItemGridFromNBT(Chest->GetContents(), a_NBT, Items);
|
||||||
a_BlockEntities.push_back(Chest.release());
|
a_BlockEntities.push_back(Chest.release());
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ protected:
|
|||||||
*/
|
*/
|
||||||
void LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a_NBT, int a_ItemsTagIdx, int s_SlotOffset = 0);
|
void LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a_NBT, int a_ItemsTagIdx, int s_SlotOffset = 0);
|
||||||
|
|
||||||
void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_ChestType);
|
||||||
void LoadDispenserFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
void LoadDispenserFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||||
void LoadDropperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
void LoadDropperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||||
void LoadFlowerPotFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
void LoadFlowerPotFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||||
|
@ -273,7 +273,7 @@ void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_En
|
|||||||
{
|
{
|
||||||
for (Json::Value::iterator itr = AllChests.begin(); itr != AllChests.end(); ++itr )
|
for (Json::Value::iterator itr = AllChests.begin(); itr != AllChests.end(); ++itr )
|
||||||
{
|
{
|
||||||
std::auto_ptr<cChestEntity> ChestEntity(new cChestEntity(0, 0, 0, a_World));
|
std::auto_ptr<cChestEntity> ChestEntity(new cChestEntity(0, 0, 0, a_World, E_BLOCK_CHEST));
|
||||||
if (!ChestEntity->LoadFromJson(*itr))
|
if (!ChestEntity->LoadFromJson(*itr))
|
||||||
{
|
{
|
||||||
LOGWARNING("ERROR READING CHEST FROM JSON!" );
|
LOGWARNING("ERROR READING CHEST FROM JSON!" );
|
||||||
|
Loading…
Reference in New Issue
Block a user