From bc1e236d547479833cc4f8d8218064cbdb9dfc0d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 18 Nov 2013 22:30:34 +0000 Subject: Redstone Megacommit [SEE DESC] + Updated BlockID - look for yourself * Improved button, repeater, lever, and comparator code -> simplification and splitting of some stuff from the redstone simulator file * Fixed buttons not breaking when in an invalid game state * Fixed QueueSetBlock -> improved (AGAIN) piston code + Rewrote redstone simulator Fixes: #57, #58, #205, and part of #131. Fixes FS issues: 281, 116, and 102 --- source/Simulator/RedstoneSimulator.h | 217 ++++++++++++++++++++++++++--------- 1 file changed, 165 insertions(+), 52 deletions(-) (limited to 'source/Simulator/RedstoneSimulator.h') diff --git a/source/Simulator/RedstoneSimulator.h b/source/Simulator/RedstoneSimulator.h index c0d5795c7..d68c6daeb 100644 --- a/source/Simulator/RedstoneSimulator.h +++ b/source/Simulator/RedstoneSimulator.h @@ -3,6 +3,9 @@ #include "Simulator.h" +/// Per-chunk data for the simulator, specified individual chunks to simulate; 'Data' is not used +typedef cCoordWithIntList cRedstoneSimulatorChunkData; + @@ -12,13 +15,13 @@ class cRedstoneSimulator : { typedef cSimulator super; public: + cRedstoneSimulator(cWorld & a_World); ~cRedstoneSimulator(); - virtual void Simulate( float a_Dt ) override; - virtual bool IsAllowedBlock( BLOCKTYPE a_BlockType ) override { return true; } - - virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override; + virtual void Simulate(float a_Dt) override {}; // Not used in this simulator + virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override; + virtual bool IsAllowedBlock( BLOCKTYPE a_BlockType ) override { return IsRedstone(a_BlockType); } enum eRedstoneDirection { @@ -31,56 +34,166 @@ public: eRedstoneDirection GetWireDirection(int a_BlockX, int a_BlockY, int a_BlockZ); eRedstoneDirection GetWireDirection(const Vector3i & a_Pos) { return GetWireDirection(a_Pos.x, a_Pos.y, a_Pos.z); } - static bool IsRepeaterPointingTo (const Vector3i & a_RepeaterPos, char a_MetaData, const Vector3i & a_BlockPos); - static bool IsRepeaterPointingAway(const Vector3i & a_RepeaterPos, char a_MetaData, const Vector3i & a_BlockPos); - static NIBBLETYPE RepeaterRotationToMetaData(double a_Rotation); - static Vector3i GetRepeaterDirection(NIBBLETYPE a_MetaData); - static NIBBLETYPE LeverDirectionToMetaData(char a_Dir); - static bool IsLeverOn(cWorld * a_World, const Vector3i & a_BlockPos); - static bool IsLeverOn(NIBBLETYPE a_BlockMeta); - - private: - struct sRepeaterChange + + struct sPoweredBlocks // Define structure of the directly powered blocks list { - Vector3i Position; - int Ticks; - bool bPowerOn; - bool bPowerOffNextTime; + Vector3i a_BlockPos; // Position of powered block + Vector3i a_SourcePos; // Position of source powering the block at a_BlockPos + BLOCKTYPE a_SourceBlock; // The source block type (for pistons pushing away sources and replacing with non source etc.) }; - typedef std::deque BlockList; - - typedef std::deque< sRepeaterChange > RepeaterList; - RepeaterList m_SetRepeaters; - - void SetRepeater(const Vector3i & a_Position, int a_Ticks, bool a_bPowerOn); - - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override {} - - void HandleChange( const Vector3i & a_BlockPos ); - BlockList RemoveCurrent( const Vector3i & a_BlockPos ); - - bool PowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock, char a_Power ); - int UnPowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock ); - - bool IsPowered( const Vector3i & a_BlockPos, bool a_bOnlyByWire = false ); - bool IsPowering( const Vector3i & a_PowerPos, const Vector3i & a_BlockPos, eRedstoneDirection a_WireDirection, bool a_bOnlyByWire ); - - BlockList m_Blocks; - BlockList m_BlocksBuffer; - - BlockList m_RefreshPistons; - BlockList m_RefreshDropSpensers; - - BlockList m_RefreshTorchesAround; + 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; + Vector3i a_SourcePos; + BLOCKTYPE a_SourceBlock; + BLOCKTYPE a_MiddleBlock; + }; - void RefreshTorchesAround( const Vector3i & a_BlockPos ); - - // TODO: The entire simulator is synchronized, no need to lock data structures; remove this - cCriticalSection m_CS; -}; - - - - + typedef std::vector PoweredBlocksList; + typedef std::vector LinkedBlocksList; + + PoweredBlocksList m_PoweredBlocks; + LinkedBlocksList m_LinkedPoweredBlocks; + + virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override; + + // 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_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState); + ///Handles the redstone block + void HandleRedstoneBlock(int a_BlockX, int a_BlockY, int a_BlockZ); + ///Handles levers + void HandleRedstoneLever(int a_BlockX, int a_BlockY, int a_BlockZ); + ///Handles buttons + void HandleRedstoneButton(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType); + /* ==================== */ + + /* ====== CARRIERS ====== */ + ///Handles redstone wire + void HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_BlockZ); + ///Handles repeaters + void HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState); + /* ====================== */ + + /* ====== DEVICES ====== */ + ///Handles pistons + void HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ); + ///Handles dispensers and droppers + void HandleDropSpenser(int a_BlockX, int a_BlockY, int a_BlockZ); + ///Handles TNT (exploding) + void HandleTNT(int a_BlockX, int a_BlockY, int a_BlockZ); + ///Handles redstone lamps + void HandleRedstoneLamp(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState); + ///Handles doords + void HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ); + ///Handles activator, detector, and powered rails + void HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType); + /* ===================== */ + + /* ====== Helper functions ====== */ + void SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock); + void SetBlockLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_MiddleX, int a_MiddleY, int a_MiddleZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddeBlock); + void SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceType); + + bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ); + bool IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta); + + bool IsLeverOn(NIBBLETYPE a_BlockMeta); + bool IsButtonOn(NIBBLETYPE a_BlockMeta); + /* ============================== */ + + inline static bool IsMechanism(BLOCKTYPE Block) + { + switch (Block) + { + case E_BLOCK_PISTON: + case E_BLOCK_STICKY_PISTON: + case E_BLOCK_DISPENSER: + case E_BLOCK_DROPPER: + case E_BLOCK_TNT: + 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: + { + return true; + } + default: return false; + } + } + + inline static bool IsPotentialSource(BLOCKTYPE Block) + { + switch (Block) + { + case E_BLOCK_WOODEN_BUTTON: + case E_BLOCK_STONE_BUTTON: + case E_BLOCK_REDSTONE_WIRE: + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_LEVER: + case E_BLOCK_REDSTONE_REPEATER_ON: + case E_BLOCK_REDSTONE_REPEATER_OFF: + case E_BLOCK_BLOCK_OF_REDSTONE: + case E_BLOCK_ACTIVE_COMPARATOR: + case E_BLOCK_INACTIVE_COMPARATOR: + { + return true; + } + default: return false; + } + } + + 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_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_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_TRIPWIRE_HOOK: + 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; + } + } +}; \ No newline at end of file -- cgit v1.2.3