IncrementalRedstoneSimulator now has no dependencies on cChunk
This commit is contained in:
parent
b87585977f
commit
26a4845a99
11
src/Chunk.h
11
src/Chunk.h
@ -417,11 +417,6 @@ public:
|
|||||||
cSandSimulatorChunkData & GetSandSimulatorData (void) { return m_SandSimulatorData; }
|
cSandSimulatorChunkData & GetSandSimulatorData (void) { return m_SandSimulatorData; }
|
||||||
|
|
||||||
cRedstoneSimulatorChunkData * GetRedstoneSimulatorData(void) { return &m_RedstoneSimulatorData; }
|
cRedstoneSimulatorChunkData * GetRedstoneSimulatorData(void) { return &m_RedstoneSimulatorData; }
|
||||||
cRedstoneSimulatorChunkData * GetRedstoneSimulatorQueuedData(void) { return &m_RedstoneSimulatorQueuedData; }
|
|
||||||
cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>::PoweredBlocksList * GetRedstoneSimulatorPoweredBlocksList(void) { return &m_RedstoneSimulatorPoweredBlocksList; }
|
|
||||||
cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>::LinkedBlocksList * GetRedstoneSimulatorLinkedBlocksList(void) { return &m_RedstoneSimulatorLinkedBlocksList; }
|
|
||||||
cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>::SimulatedPlayerToggleableList * GetRedstoneSimulatorSimulatedPlayerToggleableList(void) { return &m_RedstoneSimulatorSimulatedPlayerToggleableList; }
|
|
||||||
cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>::RepeatersDelayList * GetRedstoneSimulatorRepeatersDelayList(void) { return &m_RedstoneSimulatorRepeatersDelayList; }
|
|
||||||
bool IsRedstoneDirty(void) const { return m_IsRedstoneDirty; }
|
bool IsRedstoneDirty(void) const { return m_IsRedstoneDirty; }
|
||||||
void SetIsRedstoneDirty(bool a_Flag) { m_IsRedstoneDirty = a_Flag; }
|
void SetIsRedstoneDirty(bool a_Flag) { m_IsRedstoneDirty = a_Flag; }
|
||||||
|
|
||||||
@ -507,11 +502,7 @@ private:
|
|||||||
cSandSimulatorChunkData m_SandSimulatorData;
|
cSandSimulatorChunkData m_SandSimulatorData;
|
||||||
|
|
||||||
cRedstoneSimulatorChunkData m_RedstoneSimulatorData;
|
cRedstoneSimulatorChunkData m_RedstoneSimulatorData;
|
||||||
cRedstoneSimulatorChunkData m_RedstoneSimulatorQueuedData;
|
|
||||||
cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>::PoweredBlocksList m_RedstoneSimulatorPoweredBlocksList;
|
|
||||||
cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>::LinkedBlocksList m_RedstoneSimulatorLinkedBlocksList;
|
|
||||||
cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>::SimulatedPlayerToggleableList m_RedstoneSimulatorSimulatedPlayerToggleableList;
|
|
||||||
cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>::RepeatersDelayList m_RedstoneSimulatorRepeatersDelayList;
|
|
||||||
|
|
||||||
/** Indicates if simulate-once blocks should be updated by the redstone simulator */
|
/** Indicates if simulate-once blocks should be updated by the redstone simulator */
|
||||||
bool m_IsRedstoneDirty;
|
bool m_IsRedstoneDirty;
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
|
||||||
#ifndef SELF_TEST
|
|
||||||
|
|
||||||
#include "IncrementalRedstoneSimulator.h"
|
|
||||||
|
|
||||||
#include "IncrementalRedstoneSimulator.inc"
|
#include "IncrementalRedstoneSimulator.inc"
|
||||||
|
|
||||||
@ -18,6 +15,8 @@
|
|||||||
#include "Blocks/BlockPiston.h"
|
#include "Blocks/BlockPiston.h"
|
||||||
#include "BlockEntities/ChestEntity.h"
|
#include "BlockEntities/ChestEntity.h"
|
||||||
|
|
||||||
#pragma clang diagnostic ignored "-Wweak-template-vtables"
|
cRedstoneSimulator<cChunk, cWorld> * MakeIncrementalRedstoneSimulator(cWorld & a_World)
|
||||||
template class cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>;
|
{
|
||||||
#endif
|
return new cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>(a_World);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -3,313 +3,7 @@
|
|||||||
|
|
||||||
#include "RedstoneSimulator.h"
|
#include "RedstoneSimulator.h"
|
||||||
|
|
||||||
/// Per-chunk data for the simulator, specified individual chunks to simulate
|
class cWorld;
|
||||||
typedef cCoordWithBlockAndBoolVector cRedstoneSimulatorChunkData;
|
class cChunk;
|
||||||
|
|
||||||
class cRedstonePoweredEntity;
|
|
||||||
|
|
||||||
typedef cItemCallback<cRedstonePoweredEntity> cRedstonePoweredCallback;
|
|
||||||
|
|
||||||
|
|
||||||
template<class ChunkType, class WorldType, template <BLOCKTYPE block> class GetHandlerCompileTime, class ChestType>
|
|
||||||
class cIncrementalRedstoneSimulator :
|
|
||||||
public cRedstoneSimulator<ChunkType, WorldType>
|
|
||||||
{
|
|
||||||
typedef cRedstoneSimulator<ChunkType, WorldType> super;
|
|
||||||
public:
|
|
||||||
|
|
||||||
cIncrementalRedstoneSimulator(WorldType & a_World);
|
|
||||||
~cIncrementalRedstoneSimulator();
|
|
||||||
|
|
||||||
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
|
|
||||||
virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, ChunkType * a_Chunk) override;
|
|
||||||
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override { return IsRedstone(a_BlockType); }
|
|
||||||
virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) override;
|
|
||||||
|
|
||||||
enum eRedstoneDirection
|
|
||||||
{
|
|
||||||
REDSTONE_NONE = 0,
|
|
||||||
REDSTONE_X_POS = 0x1,
|
|
||||||
REDSTONE_X_NEG = 0x2,
|
|
||||||
REDSTONE_Z_POS = 0x4,
|
|
||||||
REDSTONE_Z_NEG = 0x8,
|
|
||||||
};
|
|
||||||
eRedstoneDirection GetWireDirection(int a_BlockX, int a_BlockY, int a_BlockZ);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
#define MAX_POWER_LEVEL 15
|
|
||||||
|
|
||||||
struct sPoweredBlocks // Define structure of the directly powered blocks list
|
|
||||||
{
|
|
||||||
Vector3i a_BlockPos; // Position of powered block
|
|
||||||
Vector3i a_SourcePos; // Position of source powering the block at a_BlockPos
|
|
||||||
unsigned char a_PowerLevel;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sLinkedPoweredBlocks // Define structure of the indirectly powered blocks list (i.e. repeaters powering through a block to the block at the other side)
|
|
||||||
{
|
|
||||||
Vector3i a_BlockPos;
|
|
||||||
Vector3i a_MiddlePos; // Position of block that is betwixt a source and the destination
|
|
||||||
Vector3i a_SourcePos;
|
|
||||||
unsigned char a_PowerLevel;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sSimulatedPlayerToggleableList // Define structure of the list containing simulate-on-update blocks (such as trapdoors that respond once to a block update, and can be toggled by a player)
|
|
||||||
{
|
|
||||||
Vector3i a_RelBlockPos;
|
|
||||||
bool WasLastStatePowered; // Was the last state powered or not? Determines whether a source update has happened and if I should resimulate
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sRepeatersDelayList // Define structure of list containing repeaters' delay states
|
|
||||||
{
|
|
||||||
Vector3i a_RelBlockPos;
|
|
||||||
unsigned char a_DelayTicks; // For how many ticks should the repeater delay
|
|
||||||
unsigned char a_ElapsedTicks; // How much of the previous has been elapsed?
|
|
||||||
bool ShouldPowerOn; // What happens when the delay time is fulfilled?
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef std::vector <sPoweredBlocks> PoweredBlocksList;
|
|
||||||
typedef std::vector <sLinkedPoweredBlocks> LinkedBlocksList;
|
|
||||||
typedef std::vector <sSimulatedPlayerToggleableList> SimulatedPlayerToggleableList;
|
|
||||||
typedef std::vector <sRepeatersDelayList> RepeatersDelayList;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
cRedstoneSimulatorChunkData * m_RedstoneSimulatorChunkData;
|
|
||||||
PoweredBlocksList * m_PoweredBlocks;
|
|
||||||
LinkedBlocksList * m_LinkedPoweredBlocks;
|
|
||||||
SimulatedPlayerToggleableList * m_SimulatedPlayerToggleableBlocks;
|
|
||||||
RepeatersDelayList * m_RepeatersDelayList;
|
|
||||||
|
|
||||||
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) override { RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); }
|
|
||||||
void RedstoneAddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk, ChunkType * a_OtherChunk = NULL);
|
|
||||||
ChunkType * m_Chunk;
|
|
||||||
|
|
||||||
// We want a_MyState for devices needing a full FastSetBlock (as opposed to meta) because with our simulation model, we cannot keep setting the block if it is already set correctly
|
|
||||||
// In addition to being non-performant, it would stop the player from actually breaking said device
|
|
||||||
|
|
||||||
/* ====== SOURCES ====== */
|
|
||||||
/** Handles the redstone torch */
|
|
||||||
void HandleRedstoneTorch(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
|
|
||||||
/** Handles the redstone block */
|
|
||||||
void HandleRedstoneBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
|
||||||
/** Handles levers */
|
|
||||||
void HandleRedstoneLever(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
|
||||||
/** Handles buttons */
|
|
||||||
void HandleRedstoneButton(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
|
||||||
/** Handles daylight sensors */
|
|
||||||
void HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
|
||||||
/** Handles pressure plates */
|
|
||||||
void HandlePressurePlate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType);
|
|
||||||
/** Handles tripwire hooks
|
|
||||||
Performs correct meta and power setting for self by going in the direction it faces and looking for a continous line of tripwire bounded by another oppositely facing hook
|
|
||||||
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);
|
|
||||||
/** Handles trapped chests */
|
|
||||||
void HandleTrappedChest(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
|
||||||
/* ==================== */
|
|
||||||
|
|
||||||
/* ====== CARRIERS ====== */
|
|
||||||
/** Handles redstone wire */
|
|
||||||
void HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
|
||||||
/** Handles repeaters */
|
|
||||||
void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
|
|
||||||
/* ====================== */
|
|
||||||
|
|
||||||
/* ====== DEVICES ====== */
|
|
||||||
/** Handles pistons */
|
|
||||||
void HandlePiston(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
|
||||||
/** Handles dispensers and droppers */
|
|
||||||
void HandleDropSpenser(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
|
||||||
/** Handles TNT (exploding) */
|
|
||||||
void HandleTNT(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
|
||||||
/** Handles redstone lamps */
|
|
||||||
void HandleRedstoneLamp(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
|
|
||||||
/** Handles doords */
|
|
||||||
void HandleDoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
|
||||||
/** Handles command blocks */
|
|
||||||
void HandleCommandBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
|
||||||
/** Handles activator, detector, and powered rails */
|
|
||||||
void HandleRail(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType);
|
|
||||||
/** Handles trapdoors */
|
|
||||||
void HandleTrapdoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
|
||||||
/** Handles fence gates */
|
|
||||||
void HandleFenceGate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
|
||||||
/** Handles noteblocks */
|
|
||||||
void HandleNoteBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
|
||||||
/** Handles tripwires */
|
|
||||||
void HandleTripwire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
|
||||||
/* ===================== */
|
|
||||||
|
|
||||||
/* ====== Helper functions ====== */
|
|
||||||
/** Marks a block as powered */
|
|
||||||
void SetBlockPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
|
||||||
/** Marks a block as being powered through another block */
|
|
||||||
void SetBlockLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelMiddleX, int a_RelMiddleY, int a_RelMiddleZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, BLOCKTYPE a_MiddeBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
|
||||||
/** 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_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool WasLastStatePowered);
|
|
||||||
/** Marks the second block in a direction as linked powered */
|
|
||||||
void SetDirectionLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, char a_Direction, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
|
||||||
/** Marks all blocks immediately surrounding a coordinate as powered */
|
|
||||||
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 */
|
|
||||||
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, ChunkType * a_Chunk, bool a_IsFirstCall = true);
|
|
||||||
|
|
||||||
/** 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, m_Chunk) || AreCoordsLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); }
|
|
||||||
/** Returns if a coordinate is in the directly powered blocks list */
|
|
||||||
bool AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, ChunkType * a_Chunk);
|
|
||||||
/** Returns if a coordinate is in the indirectly powered blocks list */
|
|
||||||
bool AreCoordsLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
|
||||||
/** Returns if a coordinate was marked as simulated (for blocks toggleable by players) */
|
|
||||||
bool AreCoordsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool IsCurrentStatePowered);
|
|
||||||
/** Returns if a repeater is powered by testing for power sources behind the repeater */
|
|
||||||
bool IsRepeaterPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta);
|
|
||||||
/** Returns if a repeater is locked */
|
|
||||||
bool IsRepeaterLocked(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta);
|
|
||||||
/** Returns if a piston is powered */
|
|
||||||
bool IsPistonPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, 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_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 */
|
|
||||||
bool IsLeverOn(NIBBLETYPE a_BlockMeta);
|
|
||||||
/** Returns if button metadata marks it as emitting power */
|
|
||||||
bool IsButtonOn(NIBBLETYPE a_BlockMeta) { return IsLeverOn(a_BlockMeta); }
|
|
||||||
/* ============================== */
|
|
||||||
|
|
||||||
/* ====== Misc Functions ====== */
|
|
||||||
/** Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation */
|
|
||||||
inline static bool IsViableMiddleBlock(BLOCKTYPE Block) { return cBlockInfo::FullyOccupiesVoxel(Block); }
|
|
||||||
|
|
||||||
/** 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)
|
|
||||||
{
|
|
||||||
switch (Block)
|
|
||||||
{
|
|
||||||
case E_BLOCK_ACTIVATOR_RAIL:
|
|
||||||
case E_BLOCK_COMMAND_BLOCK:
|
|
||||||
case E_BLOCK_PISTON:
|
|
||||||
case E_BLOCK_STICKY_PISTON:
|
|
||||||
case E_BLOCK_DISPENSER:
|
|
||||||
case E_BLOCK_DROPPER:
|
|
||||||
case E_BLOCK_FENCE_GATE:
|
|
||||||
case E_BLOCK_HOPPER:
|
|
||||||
case E_BLOCK_NOTE_BLOCK:
|
|
||||||
case E_BLOCK_TNT:
|
|
||||||
case E_BLOCK_TRAPDOOR:
|
|
||||||
case E_BLOCK_REDSTONE_LAMP_OFF:
|
|
||||||
case E_BLOCK_REDSTONE_LAMP_ON:
|
|
||||||
case E_BLOCK_WOODEN_DOOR:
|
|
||||||
case E_BLOCK_IRON_DOOR:
|
|
||||||
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
|
||||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
|
||||||
case E_BLOCK_POWERED_RAIL:
|
|
||||||
case E_BLOCK_REDSTONE_WIRE:
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default: return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 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_ON:
|
|
||||||
case E_BLOCK_LEVER:
|
|
||||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
|
||||||
case E_BLOCK_BLOCK_OF_REDSTONE:
|
|
||||||
case E_BLOCK_ACTIVE_COMPARATOR:
|
|
||||||
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
|
|
||||||
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
|
|
||||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
|
||||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
|
||||||
case E_BLOCK_TRAPPED_CHEST:
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default: return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns if a block is any sort of redstone device */
|
|
||||||
inline static bool IsRedstone(BLOCKTYPE Block)
|
|
||||||
{
|
|
||||||
switch (Block)
|
|
||||||
{
|
|
||||||
// All redstone devices, please alpha sort
|
|
||||||
case E_BLOCK_ACTIVATOR_RAIL:
|
|
||||||
case E_BLOCK_ACTIVE_COMPARATOR:
|
|
||||||
case E_BLOCK_BLOCK_OF_REDSTONE:
|
|
||||||
case E_BLOCK_COMMAND_BLOCK:
|
|
||||||
case E_BLOCK_DETECTOR_RAIL:
|
|
||||||
case E_BLOCK_DISPENSER:
|
|
||||||
case E_BLOCK_DAYLIGHT_SENSOR:
|
|
||||||
case E_BLOCK_DROPPER:
|
|
||||||
case E_BLOCK_FENCE_GATE:
|
|
||||||
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
|
|
||||||
case E_BLOCK_HOPPER:
|
|
||||||
case E_BLOCK_INACTIVE_COMPARATOR:
|
|
||||||
case E_BLOCK_IRON_DOOR:
|
|
||||||
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:
|
|
||||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
|
||||||
case E_BLOCK_REDSTONE_TORCH_OFF:
|
|
||||||
case E_BLOCK_REDSTONE_TORCH_ON:
|
|
||||||
case E_BLOCK_REDSTONE_WIRE:
|
|
||||||
case E_BLOCK_STICKY_PISTON:
|
|
||||||
case E_BLOCK_STONE_BUTTON:
|
|
||||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
|
||||||
case E_BLOCK_TNT:
|
|
||||||
case E_BLOCK_TRAPDOOR:
|
|
||||||
case E_BLOCK_TRAPPED_CHEST:
|
|
||||||
case E_BLOCK_TRIPWIRE_HOOK:
|
|
||||||
case E_BLOCK_TRIPWIRE:
|
|
||||||
case E_BLOCK_WOODEN_BUTTON:
|
|
||||||
case E_BLOCK_WOODEN_DOOR:
|
|
||||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
|
||||||
case E_BLOCK_PISTON:
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
cRedstoneSimulator<cChunk, cWorld> * MakeIncrementalRedstoneSimulator(cWorld & a_World);
|
||||||
|
@ -3,20 +3,334 @@
|
|||||||
#include "BoundingBox.h"
|
#include "BoundingBox.h"
|
||||||
#include "BlockEntities/RedstonePoweredEntity.h"
|
#include "BlockEntities/RedstonePoweredEntity.h"
|
||||||
#include "Blocks/ChunkInterface.h"
|
#include "Blocks/ChunkInterface.h"
|
||||||
|
#include "RedstoneSimulator.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef cItemCallback<cRedstonePoweredEntity> cRedstonePoweredCallback;
|
||||||
|
|
||||||
|
|
||||||
template<class ChunkType, class WorldType, template <BLOCKTYPE block> class GetHandlerCompileTime, class ChestType>
|
template<class ChunkType, class WorldType, template <BLOCKTYPE block> class GetHandlerCompileTime, class ChestType>
|
||||||
cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulator(WorldType & a_World) :
|
class cIncrementalRedstoneSimulator :
|
||||||
super(a_World),
|
public cRedstoneSimulator<ChunkType, WorldType>
|
||||||
m_RedstoneSimulatorChunkData(),
|
{
|
||||||
m_PoweredBlocks(),
|
typedef cRedstoneSimulator<ChunkType, WorldType> super;
|
||||||
m_LinkedPoweredBlocks(),
|
public:
|
||||||
m_SimulatedPlayerToggleableBlocks(),
|
|
||||||
m_RepeatersDelayList(),
|
cIncrementalRedstoneSimulator(WorldType & a_World)
|
||||||
m_Chunk()
|
: cRedstoneSimulator<ChunkType, WorldType>(a_World)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
~cIncrementalRedstoneSimulator();
|
||||||
|
|
||||||
|
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
|
||||||
|
virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, ChunkType * a_Chunk) override;
|
||||||
|
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override { return IsRedstone(a_BlockType); }
|
||||||
|
virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) override;
|
||||||
|
|
||||||
|
enum eRedstoneDirection
|
||||||
|
{
|
||||||
|
REDSTONE_NONE = 0,
|
||||||
|
REDSTONE_X_POS = 0x1,
|
||||||
|
REDSTONE_X_NEG = 0x2,
|
||||||
|
REDSTONE_Z_POS = 0x4,
|
||||||
|
REDSTONE_Z_NEG = 0x8,
|
||||||
|
};
|
||||||
|
eRedstoneDirection GetWireDirection(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
#define MAX_POWER_LEVEL 15
|
||||||
|
|
||||||
|
struct sPoweredBlocks // Define structure of the directly powered blocks list
|
||||||
|
{
|
||||||
|
Vector3i a_BlockPos; // Position of powered block
|
||||||
|
Vector3i a_SourcePos; // Position of source powering the block at a_BlockPos
|
||||||
|
unsigned char a_PowerLevel;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sLinkedPoweredBlocks // Define structure of the indirectly powered blocks list (i.e. repeaters powering through a block to the block at the other side)
|
||||||
|
{
|
||||||
|
Vector3i a_BlockPos;
|
||||||
|
Vector3i a_MiddlePos; // Position of block that is betwixt a source and the destination
|
||||||
|
Vector3i a_SourcePos;
|
||||||
|
unsigned char a_PowerLevel;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sSimulatedPlayerToggleableList // Define structure of the list containing simulate-on-update blocks (such as trapdoors that respond once to a block update, and can be toggled by a player)
|
||||||
|
{
|
||||||
|
Vector3i a_RelBlockPos;
|
||||||
|
bool WasLastStatePowered; // Was the last state powered or not? Determines whether a source update has happened and if I should resimulate
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sRepeatersDelayList // Define structure of list containing repeaters' delay states
|
||||||
|
{
|
||||||
|
Vector3i a_RelBlockPos;
|
||||||
|
unsigned char a_DelayTicks; // For how many ticks should the repeater delay
|
||||||
|
unsigned char a_ElapsedTicks; // How much of the previous has been elapsed?
|
||||||
|
bool ShouldPowerOn; // What happens when the delay time is fulfilled?
|
||||||
|
};
|
||||||
|
|
||||||
|
class cIncrementalRedstoneSimulatorChunkData :
|
||||||
|
cRedstoneSimulatorChunkData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Per-chunk data for the simulator, specified individual chunks to simulate
|
||||||
|
cCoordWithBlockAndBoolVector m_ChunkData;
|
||||||
|
cCoordWithBlockAndBoolVector m_QueuedChunkData;
|
||||||
|
std::vector<sPoweredBlocks> m_PoweredBlocks;
|
||||||
|
std::vector<sLinkedPoweredBlocks> m_LinkedBlocks;
|
||||||
|
std::vector<sSimulatedPlayerToggleableList> m_SimulatedPlayerToggleableBlocks;
|
||||||
|
std::vector<sRepeatersDelayList> m_RepeatersDelayList;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef std::vector <sPoweredBlocks> PoweredBlocksList;
|
||||||
|
typedef std::vector <sLinkedPoweredBlocks> LinkedBlocksList;
|
||||||
|
typedef std::vector <sSimulatedPlayerToggleableList> SimulatedPlayerToggleableList;
|
||||||
|
typedef std::vector <sRepeatersDelayList> RepeatersDelayList;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
cIncrementalRedstoneSimulatorChunkData * m_RedstoneSimulatorChunkData;
|
||||||
|
PoweredBlocksList * m_PoweredBlocks;
|
||||||
|
LinkedBlocksList * m_LinkedPoweredBlocks;
|
||||||
|
SimulatedPlayerToggleableList * m_SimulatedPlayerToggleableBlocks;
|
||||||
|
RepeatersDelayList * m_RepeatersDelayList;
|
||||||
|
|
||||||
|
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) override { RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); }
|
||||||
|
void RedstoneAddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk, ChunkType * a_OtherChunk = NULL);
|
||||||
|
ChunkType * m_Chunk;
|
||||||
|
|
||||||
|
// We want a_MyState for devices needing a full FastSetBlock (as opposed to meta) because with our simulation model, we cannot keep setting the block if it is already set correctly
|
||||||
|
// In addition to being non-performant, it would stop the player from actually breaking said device
|
||||||
|
|
||||||
|
/* ====== SOURCES ====== */
|
||||||
|
/** Handles the redstone torch */
|
||||||
|
void HandleRedstoneTorch(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
|
||||||
|
/** Handles the redstone block */
|
||||||
|
void HandleRedstoneBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/** Handles levers */
|
||||||
|
void HandleRedstoneLever(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/** Handles buttons */
|
||||||
|
void HandleRedstoneButton(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/** Handles daylight sensors */
|
||||||
|
void HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/** Handles pressure plates */
|
||||||
|
void HandlePressurePlate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType);
|
||||||
|
/** Handles tripwire hooks
|
||||||
|
Performs correct meta and power setting for self by going in the direction it faces and looking for a continous line of tripwire bounded by another oppositely facing hook
|
||||||
|
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);
|
||||||
|
/** Handles trapped chests */
|
||||||
|
void HandleTrappedChest(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/* ==================== */
|
||||||
|
|
||||||
|
/* ====== CARRIERS ====== */
|
||||||
|
/** Handles redstone wire */
|
||||||
|
void HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/** Handles repeaters */
|
||||||
|
void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
|
||||||
|
/* ====================== */
|
||||||
|
|
||||||
|
/* ====== DEVICES ====== */
|
||||||
|
/** Handles pistons */
|
||||||
|
void HandlePiston(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/** Handles dispensers and droppers */
|
||||||
|
void HandleDropSpenser(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/** Handles TNT (exploding) */
|
||||||
|
void HandleTNT(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/** Handles redstone lamps */
|
||||||
|
void HandleRedstoneLamp(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
|
||||||
|
/** Handles doords */
|
||||||
|
void HandleDoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/** Handles command blocks */
|
||||||
|
void HandleCommandBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/** Handles activator, detector, and powered rails */
|
||||||
|
void HandleRail(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType);
|
||||||
|
/** Handles trapdoors */
|
||||||
|
void HandleTrapdoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/** Handles fence gates */
|
||||||
|
void HandleFenceGate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/** Handles noteblocks */
|
||||||
|
void HandleNoteBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/** Handles tripwires */
|
||||||
|
void HandleTripwire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/* ===================== */
|
||||||
|
|
||||||
|
/* ====== Helper functions ====== */
|
||||||
|
/** Marks a block as powered */
|
||||||
|
void SetBlockPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||||
|
/** Marks a block as being powered through another block */
|
||||||
|
void SetBlockLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelMiddleX, int a_RelMiddleY, int a_RelMiddleZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, BLOCKTYPE a_MiddeBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||||
|
/** 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_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool WasLastStatePowered);
|
||||||
|
/** Marks the second block in a direction as linked powered */
|
||||||
|
void SetDirectionLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, char a_Direction, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||||
|
/** Marks all blocks immediately surrounding a coordinate as powered */
|
||||||
|
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 */
|
||||||
|
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, ChunkType * a_Chunk, bool a_IsFirstCall = true);
|
||||||
|
|
||||||
|
/** 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, m_Chunk) || AreCoordsLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); }
|
||||||
|
/** Returns if a coordinate is in the directly powered blocks list */
|
||||||
|
bool AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, ChunkType * a_Chunk);
|
||||||
|
/** Returns if a coordinate is in the indirectly powered blocks list */
|
||||||
|
bool AreCoordsLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||||
|
/** Returns if a coordinate was marked as simulated (for blocks toggleable by players) */
|
||||||
|
bool AreCoordsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool IsCurrentStatePowered);
|
||||||
|
/** Returns if a repeater is powered by testing for power sources behind the repeater */
|
||||||
|
bool IsRepeaterPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta);
|
||||||
|
/** Returns if a repeater is locked */
|
||||||
|
bool IsRepeaterLocked(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta);
|
||||||
|
/** Returns if a piston is powered */
|
||||||
|
bool IsPistonPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, 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_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 */
|
||||||
|
bool IsLeverOn(NIBBLETYPE a_BlockMeta);
|
||||||
|
/** Returns if button metadata marks it as emitting power */
|
||||||
|
bool IsButtonOn(NIBBLETYPE a_BlockMeta) { return IsLeverOn(a_BlockMeta); }
|
||||||
|
/* ============================== */
|
||||||
|
|
||||||
|
/* ====== Misc Functions ====== */
|
||||||
|
/** Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation */
|
||||||
|
inline static bool IsViableMiddleBlock(BLOCKTYPE Block) { return cBlockInfo::FullyOccupiesVoxel(Block); }
|
||||||
|
|
||||||
|
/** 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)
|
||||||
|
{
|
||||||
|
switch (Block)
|
||||||
|
{
|
||||||
|
case E_BLOCK_ACTIVATOR_RAIL:
|
||||||
|
case E_BLOCK_COMMAND_BLOCK:
|
||||||
|
case E_BLOCK_PISTON:
|
||||||
|
case E_BLOCK_STICKY_PISTON:
|
||||||
|
case E_BLOCK_DISPENSER:
|
||||||
|
case E_BLOCK_DROPPER:
|
||||||
|
case E_BLOCK_FENCE_GATE:
|
||||||
|
case E_BLOCK_HOPPER:
|
||||||
|
case E_BLOCK_NOTE_BLOCK:
|
||||||
|
case E_BLOCK_TNT:
|
||||||
|
case E_BLOCK_TRAPDOOR:
|
||||||
|
case E_BLOCK_REDSTONE_LAMP_OFF:
|
||||||
|
case E_BLOCK_REDSTONE_LAMP_ON:
|
||||||
|
case E_BLOCK_WOODEN_DOOR:
|
||||||
|
case E_BLOCK_IRON_DOOR:
|
||||||
|
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
||||||
|
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||||
|
case E_BLOCK_POWERED_RAIL:
|
||||||
|
case E_BLOCK_REDSTONE_WIRE:
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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_ON:
|
||||||
|
case E_BLOCK_LEVER:
|
||||||
|
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||||
|
case E_BLOCK_BLOCK_OF_REDSTONE:
|
||||||
|
case E_BLOCK_ACTIVE_COMPARATOR:
|
||||||
|
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
|
||||||
|
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
|
||||||
|
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||||
|
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||||
|
case E_BLOCK_TRAPPED_CHEST:
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns if a block is any sort of redstone device */
|
||||||
|
inline static bool IsRedstone(BLOCKTYPE Block)
|
||||||
|
{
|
||||||
|
switch (Block)
|
||||||
|
{
|
||||||
|
// All redstone devices, please alpha sort
|
||||||
|
case E_BLOCK_ACTIVATOR_RAIL:
|
||||||
|
case E_BLOCK_ACTIVE_COMPARATOR:
|
||||||
|
case E_BLOCK_BLOCK_OF_REDSTONE:
|
||||||
|
case E_BLOCK_COMMAND_BLOCK:
|
||||||
|
case E_BLOCK_DETECTOR_RAIL:
|
||||||
|
case E_BLOCK_DISPENSER:
|
||||||
|
case E_BLOCK_DAYLIGHT_SENSOR:
|
||||||
|
case E_BLOCK_DROPPER:
|
||||||
|
case E_BLOCK_FENCE_GATE:
|
||||||
|
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
|
||||||
|
case E_BLOCK_HOPPER:
|
||||||
|
case E_BLOCK_INACTIVE_COMPARATOR:
|
||||||
|
case E_BLOCK_IRON_DOOR:
|
||||||
|
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:
|
||||||
|
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||||
|
case E_BLOCK_REDSTONE_TORCH_OFF:
|
||||||
|
case E_BLOCK_REDSTONE_TORCH_ON:
|
||||||
|
case E_BLOCK_REDSTONE_WIRE:
|
||||||
|
case E_BLOCK_STICKY_PISTON:
|
||||||
|
case E_BLOCK_STONE_BUTTON:
|
||||||
|
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||||
|
case E_BLOCK_TNT:
|
||||||
|
case E_BLOCK_TRAPDOOR:
|
||||||
|
case E_BLOCK_TRAPPED_CHEST:
|
||||||
|
case E_BLOCK_TRIPWIRE_HOOK:
|
||||||
|
case E_BLOCK_TRIPWIRE:
|
||||||
|
case E_BLOCK_WOODEN_BUTTON:
|
||||||
|
case E_BLOCK_WOODEN_DOOR:
|
||||||
|
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||||
|
case E_BLOCK_PISTON:
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -70,8 +384,8 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
// 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
|
// 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
|
// Checking only when a block is changed, as opposed to every tick, also improves performance
|
||||||
|
|
||||||
PoweredBlocksList * PoweredBlocks = a_Chunk->GetRedstoneSimulatorPoweredBlocksList();
|
PoweredBlocksList & PoweredBlocks = ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_PoweredBlocks;
|
||||||
for (typename PoweredBlocksList::iterator itr = PoweredBlocks->begin(); itr != PoweredBlocks->end();)
|
for (typename PoweredBlocksList::iterator itr = PoweredBlocks.begin(); itr != PoweredBlocks.end();)
|
||||||
{
|
{
|
||||||
if (!itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
|
if (!itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
|
||||||
{
|
{
|
||||||
@ -82,7 +396,7 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
if (!IsPotentialSource(Block))
|
if (!IsPotentialSource(Block))
|
||||||
{
|
{
|
||||||
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);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
@ -95,22 +409,22 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
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);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkedBlocksList * LinkedPoweredBlocks = a_Chunk->GetRedstoneSimulatorLinkedBlocksList();
|
LinkedBlocksList & LinkedPoweredBlocks = ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_LinkedBlocks;
|
||||||
// We loop through all values (insteading of breaking out at the first) to make sure everything is gone, as there can be multiple SourceBlock entries for one AddBlock coordinate
|
// We loop through all values (insteading of breaking out at the first) to make sure everything is gone, as there can be multiple SourceBlock entries for one AddBlock coordinate
|
||||||
for (typename LinkedBlocksList::iterator itr = LinkedPoweredBlocks->begin(); itr != LinkedPoweredBlocks->end();)
|
for (typename LinkedBlocksList::iterator itr = LinkedPoweredBlocks.begin(); itr != LinkedPoweredBlocks.end();)
|
||||||
{
|
{
|
||||||
if (itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
|
if (itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
|
||||||
{
|
{
|
||||||
if (!IsPotentialSource(Block))
|
if (!IsPotentialSource(Block))
|
||||||
{
|
{
|
||||||
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);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
@ -121,7 +435,7 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
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);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,15 +444,15 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
if (!IsViableMiddleBlock(Block))
|
if (!IsViableMiddleBlock(Block))
|
||||||
{
|
{
|
||||||
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);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatedPlayerToggleableList * SimulatedPlayerToggleableBlocks = a_Chunk->GetRedstoneSimulatorSimulatedPlayerToggleableList();
|
SimulatedPlayerToggleableList & SimulatedPlayerToggleableBlocks = ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_SimulatedPlayerToggleableBlocks;
|
||||||
for (typename SimulatedPlayerToggleableList::iterator itr = SimulatedPlayerToggleableBlocks->begin(); itr != SimulatedPlayerToggleableBlocks->end(); ++itr)
|
for (typename SimulatedPlayerToggleableList::iterator itr = SimulatedPlayerToggleableBlocks.begin(); itr != SimulatedPlayerToggleableBlocks.end(); ++itr)
|
||||||
{
|
{
|
||||||
if (!itr->a_RelBlockPos.Equals(Vector3i(RelX, a_BlockY, RelZ)))
|
if (!itr->a_RelBlockPos.Equals(Vector3i(RelX, a_BlockY, RelZ)))
|
||||||
{
|
{
|
||||||
@ -148,13 +462,13 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
if (!IsAllowedBlock(Block))
|
if (!IsAllowedBlock(Block))
|
||||||
{
|
{
|
||||||
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from toggleable simulated list as it is no longer redstone", itr->a_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z);
|
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from toggleable simulated list as it is no longer redstone", itr->a_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z);
|
||||||
SimulatedPlayerToggleableBlocks->erase(itr);
|
SimulatedPlayerToggleableBlocks.erase(itr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RepeatersDelayList * RepeatersDelayList = a_Chunk->GetRedstoneSimulatorRepeatersDelayList();
|
RepeatersDelayList & RepeatersDelayList = ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_RepeatersDelayList;
|
||||||
for (typename RepeatersDelayList::iterator itr = RepeatersDelayList->begin(); itr != RepeatersDelayList->end(); ++itr)
|
for (typename RepeatersDelayList::iterator itr = RepeatersDelayList.begin(); itr != RepeatersDelayList.end(); ++itr)
|
||||||
{
|
{
|
||||||
if (!itr->a_RelBlockPos.Equals(Vector3i(RelX, a_BlockY, RelZ)))
|
if (!itr->a_RelBlockPos.Equals(Vector3i(RelX, a_BlockY, RelZ)))
|
||||||
{
|
{
|
||||||
@ -163,7 +477,7 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
|
|
||||||
if ((Block != E_BLOCK_REDSTONE_REPEATER_ON) && (Block != E_BLOCK_REDSTONE_REPEATER_OFF))
|
if ((Block != E_BLOCK_REDSTONE_REPEATER_ON) && (Block != E_BLOCK_REDSTONE_REPEATER_OFF))
|
||||||
{
|
{
|
||||||
RepeatersDelayList->erase(itr);
|
RepeatersDelayList.erase(itr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,8 +488,8 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cRedstoneSimulatorChunkData * RedstoneSimulatorChunkData = a_Chunk->GetRedstoneSimulatorData();
|
cCoordWithBlockAndBoolVector & RedstoneSimulatorChunkData = ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_ChunkData;
|
||||||
for (cRedstoneSimulatorChunkData::iterator itr = RedstoneSimulatorChunkData->begin(); itr != RedstoneSimulatorChunkData->end(); ++itr)
|
for (cCoordWithBlockAndBoolVector::iterator itr = RedstoneSimulatorChunkData.begin(); itr != RedstoneSimulatorChunkData.end(); ++itr)
|
||||||
{
|
{
|
||||||
if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ)) // We are at an entry matching the current (changed) block
|
if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ)) // We are at an entry matching the current (changed) block
|
||||||
{
|
{
|
||||||
@ -197,7 +511,8 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (cRedstoneSimulatorChunkData::iterator itr = a_Chunk->GetRedstoneSimulatorQueuedData()->begin(); itr != a_Chunk->GetRedstoneSimulatorQueuedData()->end(); ++itr)
|
cCoordWithBlockAndBoolVector & QueuedData = ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_QueuedChunkData;
|
||||||
|
for (cCoordWithBlockAndBoolVector::iterator itr = QueuedData.begin(); itr != QueuedData.end(); ++itr)
|
||||||
{
|
{
|
||||||
if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ))
|
if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ))
|
||||||
{
|
{
|
||||||
@ -205,7 +520,7 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a_Chunk->GetRedstoneSimulatorQueuedData()->push_back(cCoordWithBlockAndBool(RelX, a_BlockY, RelZ, Block, false));
|
QueuedData.push_back(cCoordWithBlockAndBool(RelX, a_BlockY, RelZ, Block, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -214,19 +529,23 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
template <class ChunkType, class WorldType, template <BLOCKTYPE block> class GetHandlerCompileTime, class ChestType>
|
template <class ChunkType, class WorldType, template <BLOCKTYPE block> class GetHandlerCompileTime, class ChestType>
|
||||||
void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, ChunkType * a_Chunk)
|
void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, ChunkType * a_Chunk)
|
||||||
{
|
{
|
||||||
m_RedstoneSimulatorChunkData = a_Chunk->GetRedstoneSimulatorData();
|
m_RedstoneSimulatorChunkData = (cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData();
|
||||||
if (m_RedstoneSimulatorChunkData->empty() && a_Chunk->GetRedstoneSimulatorQueuedData()->empty())
|
if (m_RedstoneSimulatorChunkData->m_ChunkData.empty() && ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_QueuedChunkData.empty())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_RedstoneSimulatorChunkData->insert(m_RedstoneSimulatorChunkData->end(), a_Chunk->GetRedstoneSimulatorQueuedData()->begin(), a_Chunk->GetRedstoneSimulatorQueuedData()->end());
|
m_RedstoneSimulatorChunkData->m_ChunkData.insert(
|
||||||
a_Chunk->GetRedstoneSimulatorQueuedData()->clear();
|
m_RedstoneSimulatorChunkData->m_ChunkData.end(),
|
||||||
|
m_RedstoneSimulatorChunkData ->m_QueuedChunkData.begin(),
|
||||||
|
m_RedstoneSimulatorChunkData ->m_QueuedChunkData.end());
|
||||||
|
|
||||||
m_PoweredBlocks = a_Chunk->GetRedstoneSimulatorPoweredBlocksList();
|
m_RedstoneSimulatorChunkData->m_QueuedChunkData.clear();
|
||||||
m_RepeatersDelayList = a_Chunk->GetRedstoneSimulatorRepeatersDelayList();
|
|
||||||
m_SimulatedPlayerToggleableBlocks = a_Chunk->GetRedstoneSimulatorSimulatedPlayerToggleableList();
|
m_PoweredBlocks = &m_RedstoneSimulatorChunkData->m_PoweredBlocks;
|
||||||
m_LinkedPoweredBlocks = a_Chunk->GetRedstoneSimulatorLinkedBlocksList();
|
m_RepeatersDelayList = &m_RedstoneSimulatorChunkData->m_RepeatersDelayList;
|
||||||
|
m_SimulatedPlayerToggleableBlocks = &m_RedstoneSimulatorChunkData->m_SimulatedPlayerToggleableBlocks;
|
||||||
|
m_LinkedPoweredBlocks = &m_RedstoneSimulatorChunkData->m_LinkedBlocks;
|
||||||
m_Chunk = a_Chunk;
|
m_Chunk = a_Chunk;
|
||||||
bool ShouldUpdateSimulateOnceBlocks = false;
|
bool ShouldUpdateSimulateOnceBlocks = false;
|
||||||
|
|
||||||
@ -240,11 +559,11 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
|
|
||||||
HandleRedstoneRepeaterDelays();
|
HandleRedstoneRepeaterDelays();
|
||||||
|
|
||||||
for (cRedstoneSimulatorChunkData::iterator dataitr = m_RedstoneSimulatorChunkData->begin(); dataitr != m_RedstoneSimulatorChunkData->end();)
|
for (cCoordWithBlockAndBoolVector::iterator dataitr = m_RedstoneSimulatorChunkData->m_ChunkData.begin(); dataitr != m_RedstoneSimulatorChunkData->m_ChunkData.end();)
|
||||||
{
|
{
|
||||||
if (dataitr->DataTwo)
|
if (dataitr->DataTwo)
|
||||||
{
|
{
|
||||||
dataitr = m_RedstoneSimulatorChunkData->erase(dataitr);
|
dataitr = m_RedstoneSimulatorChunkData->m_ChunkData.erase(dataitr);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1497,7 +1816,7 @@ bool cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
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 (typename PoweredBlocksList::const_iterator itr = a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->begin(); itr != a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->end(); ++itr) // Check powered list
|
for (typename PoweredBlocksList::const_iterator itr = ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_PoweredBlocks.begin(); itr != ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_PoweredBlocks.end(); ++itr) // Check powered list
|
||||||
{
|
{
|
||||||
if (itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)))
|
if (itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)))
|
||||||
{
|
{
|
||||||
@ -1904,8 +2223,8 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PoweredBlocksList * Powered = Neighbour->GetRedstoneSimulatorPoweredBlocksList(); // We need to insert the value into the chunk who owns the block position
|
PoweredBlocksList & Powered = ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)Neighbour->GetRedstoneSimulatorData())->m_PoweredBlocks; // We need to insert the value into the chunk who owns the block position
|
||||||
for (typename PoweredBlocksList::iterator itr = Powered->begin(); itr != Powered->end(); ++itr)
|
for (typename PoweredBlocksList::iterator itr = Powered.begin(); itr != Powered.end(); ++itr)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) &&
|
itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) &&
|
||||||
@ -1952,7 +2271,7 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
RC.a_BlockPos = Vector3i(BlockX, a_RelBlockY, BlockZ);
|
RC.a_BlockPos = Vector3i(BlockX, a_RelBlockY, BlockZ);
|
||||||
RC.a_SourcePos = Vector3i(SourceX, a_RelSourceY, SourceZ);
|
RC.a_SourcePos = Vector3i(SourceX, a_RelSourceY, SourceZ);
|
||||||
RC.a_PowerLevel = a_PowerLevel;
|
RC.a_PowerLevel = a_PowerLevel;
|
||||||
Powered->push_back(RC);
|
Powered.push_back(RC);
|
||||||
Neighbour->SetIsRedstoneDirty(true);
|
Neighbour->SetIsRedstoneDirty(true);
|
||||||
m_Chunk->SetIsRedstoneDirty(true);
|
m_Chunk->SetIsRedstoneDirty(true);
|
||||||
}
|
}
|
||||||
@ -1986,8 +2305,8 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkedBlocksList * Linked = Neighbour->GetRedstoneSimulatorLinkedBlocksList();
|
LinkedBlocksList & Linked = ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)Neighbour->GetRedstoneSimulatorData())->m_LinkedBlocks;
|
||||||
for (typename LinkedBlocksList::iterator itr = Linked->begin(); itr != Linked->end(); ++itr) // Check linked powered list
|
for (typename LinkedBlocksList::iterator itr = Linked.begin(); itr != Linked.end(); ++itr) // Check linked powered list
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) &&
|
itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) &&
|
||||||
@ -2006,7 +2325,7 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
RC.a_MiddlePos = Vector3i(MiddleX, a_RelMiddleY, MiddleZ);
|
RC.a_MiddlePos = Vector3i(MiddleX, a_RelMiddleY, MiddleZ);
|
||||||
RC.a_SourcePos = Vector3i(SourceX, a_RelSourceY, SourceZ);
|
RC.a_SourcePos = Vector3i(SourceX, a_RelSourceY, SourceZ);
|
||||||
RC.a_PowerLevel = a_PowerLevel;
|
RC.a_PowerLevel = a_PowerLevel;
|
||||||
Linked->push_back(RC);
|
Linked.push_back(RC);
|
||||||
Neighbour->SetIsRedstoneDirty(true);
|
Neighbour->SetIsRedstoneDirty(true);
|
||||||
m_Chunk->SetIsRedstoneDirty(true);
|
m_Chunk->SetIsRedstoneDirty(true);
|
||||||
}
|
}
|
||||||
@ -2096,21 +2415,21 @@ void cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
|
|||||||
}
|
}
|
||||||
// TODO: on C++11 support, change both of these to llama functions pased to a std::remove_if
|
// TODO: on C++11 support, change both of these to llama functions pased to a std::remove_if
|
||||||
|
|
||||||
for (typename PoweredBlocksList::iterator itr = a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->begin(); itr != a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->end();)
|
for (typename PoweredBlocksList::iterator itr = ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_PoweredBlocks.begin(); itr != ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_PoweredBlocks.end();)
|
||||||
{
|
{
|
||||||
if (itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ)))
|
if (itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ)))
|
||||||
{
|
{
|
||||||
itr = a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->erase(itr);
|
itr = ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_PoweredBlocks.erase(itr);
|
||||||
a_Chunk->SetIsRedstoneDirty(true);
|
a_Chunk->SetIsRedstoneDirty(true);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
for (typename LinkedBlocksList::iterator itr = a_Chunk->GetRedstoneSimulatorLinkedBlocksList()->begin(); itr != a_Chunk->GetRedstoneSimulatorLinkedBlocksList()->end();)
|
for (typename LinkedBlocksList::iterator itr = ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_LinkedBlocks.begin(); itr != ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_LinkedBlocks.end();)
|
||||||
{
|
{
|
||||||
if (itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ)))
|
if (itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ)))
|
||||||
{
|
{
|
||||||
itr = a_Chunk->GetRedstoneSimulatorLinkedBlocksList()->erase(itr);
|
itr = ((cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime, ChestType>::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_LinkedBlocks.erase(itr);
|
||||||
a_Chunk->SetIsRedstoneDirty(true);
|
a_Chunk->SetIsRedstoneDirty(true);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,12 @@
|
|||||||
#include "Simulator.h"
|
#include "Simulator.h"
|
||||||
|
|
||||||
|
|
||||||
|
class cRedstoneSimulatorChunkData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~cRedstoneSimulatorChunkData() {}
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
template <class ChunkType, class WorldType>
|
template <class ChunkType, class WorldType>
|
||||||
class cRedstoneSimulator :
|
class cRedstoneSimulator :
|
||||||
|
@ -3272,7 +3272,7 @@ cRedstoneSimulator<cChunk, cWorld> * cWorld::InitializeRedstoneSimulator(cIniFil
|
|||||||
|
|
||||||
if (NoCaseCompare(SimulatorName, "Incremental") == 0)
|
if (NoCaseCompare(SimulatorName, "Incremental") == 0)
|
||||||
{
|
{
|
||||||
res = new cIncrementalRedstoneSimulator<cChunk, cWorld, GetHandlerCompileTime, cChestEntity>(*this);
|
res = MakeIncrementalRedstoneSimulator(*this);
|
||||||
}
|
}
|
||||||
else if (NoCaseCompare(SimulatorName, "noop") == 0)
|
else if (NoCaseCompare(SimulatorName, "noop") == 0)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user