Files
cuberite-2a/src/Simulator/RedstoneSimulator.h
T

276 lines
9.8 KiB
C++
Raw Normal View History

#pragma once
#include "Simulator.h"
2013-11-18 22:30:34 +00:00
/// Per-chunk data for the simulator, specified individual chunks to simulate; 'Data' is not used
2014-01-10 20:31:05 +00:00
typedef cCoordWithBlockVector cRedstoneSimulatorChunkData;
2013-11-18 22:30:34 +00:00
class cRedstoneSimulator :
public cSimulator
{
typedef cSimulator super;
public:
2013-11-18 22:30:34 +00:00
cRedstoneSimulator(cWorld & a_World);
~cRedstoneSimulator();
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
2013-11-18 22:30:34 +00:00
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
{
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:
2013-11-18 22:30:34 +00:00
struct sPoweredBlocks // Define structure of the directly powered blocks list
{
2013-11-18 22:30:34 +00:00
Vector3i a_BlockPos; // Position of powered block
Vector3i a_SourcePos; // Position of source powering the block at a_BlockPos
};
2013-11-18 22:30:34 +00:00
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;
};
2013-12-07 14:41:58 +00:00
struct sSimulatedPlayerToggleableList
{
Vector3i a_BlockPos;
bool WasLastStatePowered;
};
2013-12-10 00:21:24 +00:00
struct sRepeatersDelayList
{
Vector3i a_BlockPos;
short a_DelayTicks;
short a_ElapsedTicks;
bool ShouldPowerOn;
2013-12-10 00:21:24 +00:00
};
2013-11-18 22:30:34 +00:00
typedef std::vector <sPoweredBlocks> PoweredBlocksList;
typedef std::vector <sLinkedPoweredBlocks> LinkedBlocksList;
2013-12-07 14:41:58 +00:00
typedef std::vector <sSimulatedPlayerToggleableList> SimulatedPlayerToggleableList;
2013-12-10 00:21:24 +00:00
typedef std::vector <sRepeatersDelayList> RepeatersDelayList;
2013-11-18 22:30:34 +00:00
PoweredBlocksList m_PoweredBlocks;
LinkedBlocksList m_LinkedPoweredBlocks;
2013-12-07 14:41:58 +00:00
SimulatedPlayerToggleableList m_SimulatedPlayerToggleableBlocks;
2013-12-10 00:21:24 +00:00
RepeatersDelayList m_RepeatersDelayList;
2013-11-18 22:30:34 +00:00
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 ====== */
2014-01-10 20:31:05 +00:00
/** Handles the redstone torch */
2013-11-18 22:30:34 +00:00
void HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
2014-01-10 20:31:05 +00:00
/** Handles the redstone block */
2013-11-18 22:30:34 +00:00
void HandleRedstoneBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
2014-01-10 20:31:05 +00:00
/** Handles levers */
2013-11-18 22:30:34 +00:00
void HandleRedstoneLever(int a_BlockX, int a_BlockY, int a_BlockZ);
2014-01-10 20:31:05 +00:00
/** Handles buttons */
2013-11-18 22:30:34 +00:00
void HandleRedstoneButton(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType);
2014-01-10 20:31:05 +00:00
/** Handles daylight sensors */
void HandleDaylightSensor(int a_BlockX, int a_BlockY, int a_BlockZ);
2014-01-10 20:31:05 +00:00
/** Handles pressure plates */
void HandlePressurePlate(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType);
2013-11-18 22:30:34 +00:00
/* ==================== */
/* ====== CARRIERS ====== */
2014-01-10 20:31:05 +00:00
/** Handles redstone wire */
2013-11-18 22:30:34 +00:00
void HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_BlockZ);
2014-01-10 20:31:05 +00:00
/** Handles repeaters */
2013-11-18 22:30:34 +00:00
void HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
/* ====================== */
/* ====== DEVICES ====== */
2014-01-10 20:31:05 +00:00
/** Handles pistons */
2013-11-18 22:30:34 +00:00
void HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ);
2014-01-10 20:31:05 +00:00
/** Handles dispensers and droppers */
2013-11-18 22:30:34 +00:00
void HandleDropSpenser(int a_BlockX, int a_BlockY, int a_BlockZ);
2014-01-10 20:31:05 +00:00
/** Handles TNT (exploding) */
2013-11-18 22:30:34 +00:00
void HandleTNT(int a_BlockX, int a_BlockY, int a_BlockZ);
2014-01-10 20:31:05 +00:00
/** Handles redstone lamps */
2013-11-18 22:30:34 +00:00
void HandleRedstoneLamp(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
2014-01-10 20:31:05 +00:00
/** Handles doords */
2013-11-18 22:30:34 +00:00
void HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ);
2014-01-10 20:31:05 +00:00
/** Handles activator, detector, and powered rails */
2013-11-18 22:30:34 +00:00
void HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType);
2014-01-10 20:31:05 +00:00
/** Handles trapdoors */
2013-11-29 22:27:08 +00:00
void HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ);
2014-01-10 20:31:05 +00:00
/** Handles noteblocks */
void HandleNoteBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
2013-11-18 22:30:34 +00:00
/* ===================== */
/* ====== Helper functions ====== */
2014-01-10 20:31:05 +00:00
/** Marks a block as powered */
2013-11-18 22:30:34 +00:00
void SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock);
2014-01-10 20:31:05 +00:00
/** Marks a block as being powered through another block */
2013-11-18 22:30:34 +00:00
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);
2014-01-10 20:31:05 +00:00
/** 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 */
2013-12-07 14:41:58 +00:00
void SetPlayerToggleableBlockAsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool WasLastStatePowered);
2014-01-10 20:31:05 +00:00
/** Marks the second block in a direction as linked powered */
2013-11-20 22:54:28 +00:00
void SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceBlock);
2014-01-10 20:31:05 +00:00
/** Marks all blocks immediately surrounding a coordinate as powered */
2013-11-20 22:54:28 +00:00
void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock);
2014-01-10 20:31:05 +00:00
/** Queues a repeater to be powered or unpowered */
void QueueRepeaterPowerChange(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta, short a_ElapsedTicks, bool ShouldPowerOn);
2013-11-18 22:30:34 +00:00
2014-01-10 20:31:05 +00:00
/** Returns if a coordinate is powered or linked powered */
2013-12-14 02:40:54 +00:00
bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ) { return AreCoordsDirectlyPowered(a_BlockX, a_BlockY, a_BlockZ) || AreCoordsLinkedPowered(a_BlockX, a_BlockY, a_BlockZ); }
2014-01-10 20:31:05 +00:00
/** Returns if a coordinate is in the directly powered blocks list */
2013-12-14 02:40:54 +00:00
bool AreCoordsDirectlyPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
2014-01-10 20:31:05 +00:00
/** Returns if a coordinate is in the indirectly powered blocks list */
2013-12-14 02:40:54 +00:00
bool AreCoordsLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
2014-01-10 20:31:05 +00:00
/** Returns if a coordinate was marked as simulated (for blocks toggleable by players) */
2013-12-07 14:41:58 +00:00
bool AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered);
2014-01-10 20:31:05 +00:00
/** Returns if a repeater is powered */
2013-11-18 22:30:34 +00:00
bool IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
2014-01-10 20:31:05 +00:00
/** Returns if a piston is powered */
bool IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
2014-01-10 20:31:05 +00:00
/** Returns if a wire is powered
The only diffence between this and a normal AreCoordsPowered is that this function checks for a wire powering another wire
*/
bool IsWirePowered(int a_BlockX, int a_BlockY, int a_BlockZ);
2013-11-18 22:30:34 +00:00
2014-01-10 20:31:05 +00:00
/** Returns if lever metadata marks it as emitting power */
2013-11-18 22:30:34 +00:00
bool IsLeverOn(NIBBLETYPE a_BlockMeta);
2014-01-10 20:31:05 +00:00
/** Returns if button metadata marks it as emitting power */
2013-11-18 22:30:34 +00:00
bool IsButtonOn(NIBBLETYPE a_BlockMeta);
/* ============================== */
2013-11-21 22:44:18 +00:00
/* ====== Misc Functions ====== */
2014-01-10 20:31:05 +00:00
/** Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation */
2013-11-21 22:44:18 +00:00
inline static bool IsViableMiddleBlock(BLOCKTYPE Block)
{
if (!g_BlockIsSolid[Block]) { return false; }
switch (Block)
{
// Add SOLID but not viable middle blocks here
2013-12-11 18:42:38 +00:00
case E_BLOCK_PISTON:
case E_BLOCK_PISTON_EXTENSION:
case E_BLOCK_STICKY_PISTON:
2013-11-21 22:44:18 +00:00
case E_BLOCK_REDSTONE_REPEATER_ON:
case E_BLOCK_REDSTONE_REPEATER_OFF:
2013-12-20 21:19:13 +00:00
case E_BLOCK_DAYLIGHT_SENSOR:
2013-11-21 22:44:18 +00:00
{
return false;
}
2013-12-20 21:19:13 +00:00
default: return true;
2013-11-21 22:44:18 +00:00
}
}
2014-01-10 20:31:05 +00:00
/** Returns if a block is a mechanism (something that accepts power and does something) */
2013-11-18 22:30:34 +00:00
inline static bool IsMechanism(BLOCKTYPE Block)
{
switch (Block)
{
2013-11-20 22:54:28 +00:00
case E_BLOCK_ACTIVATOR_RAIL:
2013-11-18 22:30:34 +00:00
case E_BLOCK_PISTON:
case E_BLOCK_STICKY_PISTON:
case E_BLOCK_DISPENSER:
case E_BLOCK_DROPPER:
2013-11-20 22:54:28 +00:00
case E_BLOCK_FENCE_GATE:
case E_BLOCK_HOPPER:
case E_BLOCK_NOTE_BLOCK:
2013-11-18 22:30:34 +00:00
case E_BLOCK_TNT:
2013-11-20 22:54:28 +00:00
case E_BLOCK_TRAPDOOR:
2013-11-18 22:30:34 +00:00
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;
}
}
2014-01-10 20:31:05 +00:00
/** Returns if a block has the potential to output power */
2013-11-18 22:30:34 +00:00
inline static bool IsPotentialSource(BLOCKTYPE Block)
{
switch (Block)
{
2013-12-20 21:19:13 +00:00
case E_BLOCK_DAYLIGHT_SENSOR:
2013-11-18 22:30:34 +00:00
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:
{
return true;
}
default: return false;
}
}
2014-01-10 20:31:05 +00:00
/** Returns if a block is any sort of redstone device */
2013-11-18 22:30:34 +00:00
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;
}
}
2013-12-21 15:08:01 +00:00
};