Cleaned up simulators
This commit is contained in:
parent
6fbc98def2
commit
85c298d73e
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "BlockHandler.h"
|
#include "BlockHandler.h"
|
||||||
#include "../Chunk.h"
|
#include "../Chunk.h"
|
||||||
|
#include "ChunkInterface.h"
|
||||||
#include "MetaRotator.h"
|
#include "MetaRotator.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -1370,9 +1370,9 @@ void cChunk::CreateBlockEntities(void)
|
|||||||
|
|
||||||
void cChunk::WakeUpSimulators(void)
|
void cChunk::WakeUpSimulators(void)
|
||||||
{
|
{
|
||||||
cSimulator<cChunk, cWorld> * WaterSimulator = m_World->GetWaterSimulator();
|
cSimulator * WaterSimulator = m_World->GetWaterSimulator();
|
||||||
cSimulator<cChunk, cWorld> * LavaSimulator = m_World->GetLavaSimulator();
|
cSimulator * LavaSimulator = m_World->GetLavaSimulator();
|
||||||
cSimulator<cChunk, cWorld> * RedstoneSimulator = m_World->GetRedstoneSimulator();
|
cSimulator * RedstoneSimulator = m_World->GetRedstoneSimulator();
|
||||||
int BaseX = m_PosX * cChunkDef::Width;
|
int BaseX = m_PosX * cChunkDef::Width;
|
||||||
int BaseZ = m_PosZ * cChunkDef::Width;
|
int BaseZ = m_PosZ * cChunkDef::Width;
|
||||||
for (int x = 0; x < Width; x++)
|
for (int x = 0; x < Width; x++)
|
||||||
|
@ -16,7 +16,7 @@ it progresses to the next step (blockmeta++). This value is updated if a neighbo
|
|||||||
The simulator reads its parameters from the ini file given to the constructor.
|
The simulator reads its parameters from the ini file given to the constructor.
|
||||||
*/
|
*/
|
||||||
class cFireSimulator :
|
class cFireSimulator :
|
||||||
public cSimulator<cChunk, cWorld>
|
public cSimulator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cFireSimulator(cWorld & a_World, cIniFile & a_IniFile);
|
cFireSimulator(cWorld & a_World, cIniFile & a_IniFile);
|
||||||
|
@ -37,9 +37,9 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
class cFluidSimulator :
|
class cFluidSimulator :
|
||||||
public cSimulator<cChunk, cWorld>
|
public cSimulator
|
||||||
{
|
{
|
||||||
typedef cSimulator<cChunk, cWorld> super;
|
typedef cSimulator super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid);
|
cFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,8 +2,359 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "RedstoneSimulator.h"
|
#include "RedstoneSimulator.h"
|
||||||
|
#include "BlockEntities/RedstonePoweredEntity.h"
|
||||||
|
|
||||||
class cWorld;
|
class cWorld;
|
||||||
class cChunk;
|
class cChunk;
|
||||||
|
|
||||||
cRedstoneSimulator<cChunk, cWorld> * MakeIncrementalRedstoneSimulator(cWorld & a_World);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef cItemCallback<cRedstonePoweredEntity> cRedstonePoweredCallback;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class cIncrementalRedstoneSimulator :
|
||||||
|
public cRedstoneSimulator
|
||||||
|
{
|
||||||
|
typedef cRedstoneSimulator super;
|
||||||
|
public:
|
||||||
|
|
||||||
|
cIncrementalRedstoneSimulator(cWorld & a_World)
|
||||||
|
: cRedstoneSimulator(a_World)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~cIncrementalRedstoneSimulator() {};
|
||||||
|
|
||||||
|
virtual cRedstoneSimulatorChunkData * CreateChunkData() override
|
||||||
|
{
|
||||||
|
return new cIncrementalRedstoneSimulatorChunkData;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt); } // not used
|
||||||
|
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); }
|
||||||
|
virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * 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 :
|
||||||
|
public 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, cChunk * a_Chunk) override { RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); }
|
||||||
|
void RedstoneAddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk, cChunk * a_OtherChunk = NULL);
|
||||||
|
cChunk * 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, cChunk * 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, cChunk * 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_ACACIA_DOOR:
|
||||||
|
case E_BLOCK_ACACIA_FENCE_GATE:
|
||||||
|
case E_BLOCK_ACTIVATOR_RAIL:
|
||||||
|
case E_BLOCK_BIRCH_DOOR:
|
||||||
|
case E_BLOCK_BIRCH_FENCE_GATE:
|
||||||
|
case E_BLOCK_COMMAND_BLOCK:
|
||||||
|
case E_BLOCK_DARK_OAK_DOOR:
|
||||||
|
case E_BLOCK_DARK_OAK_FENCE_GATE:
|
||||||
|
case E_BLOCK_DISPENSER:
|
||||||
|
case E_BLOCK_DROPPER:
|
||||||
|
case E_BLOCK_FENCE_GATE:
|
||||||
|
case E_BLOCK_HOPPER:
|
||||||
|
case E_BLOCK_IRON_DOOR:
|
||||||
|
case E_BLOCK_IRON_TRAPDOOR:
|
||||||
|
case E_BLOCK_JUNGLE_DOOR:
|
||||||
|
case E_BLOCK_JUNGLE_FENCE_GATE:
|
||||||
|
case E_BLOCK_NOTE_BLOCK:
|
||||||
|
case E_BLOCK_PISTON:
|
||||||
|
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_WIRE:
|
||||||
|
case E_BLOCK_SPRUCE_DOOR:
|
||||||
|
case E_BLOCK_SPRUCE_FENCE_GATE:
|
||||||
|
case E_BLOCK_STICKY_PISTON:
|
||||||
|
case E_BLOCK_TNT:
|
||||||
|
case E_BLOCK_TRAPDOOR:
|
||||||
|
case E_BLOCK_WOODEN_DOOR:
|
||||||
|
{
|
||||||
|
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_ACACIA_DOOR:
|
||||||
|
case E_BLOCK_ACACIA_FENCE_GATE:
|
||||||
|
case E_BLOCK_ACTIVATOR_RAIL:
|
||||||
|
case E_BLOCK_ACTIVE_COMPARATOR:
|
||||||
|
case E_BLOCK_BIRCH_DOOR:
|
||||||
|
case E_BLOCK_BIRCH_FENCE_GATE:
|
||||||
|
case E_BLOCK_BLOCK_OF_REDSTONE:
|
||||||
|
case E_BLOCK_COMMAND_BLOCK:
|
||||||
|
case E_BLOCK_DARK_OAK_DOOR:
|
||||||
|
case E_BLOCK_DARK_OAK_FENCE_GATE:
|
||||||
|
case E_BLOCK_DAYLIGHT_SENSOR:
|
||||||
|
case E_BLOCK_DETECTOR_RAIL:
|
||||||
|
case E_BLOCK_DISPENSER:
|
||||||
|
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_IRON_TRAPDOOR:
|
||||||
|
case E_BLOCK_JUNGLE_DOOR:
|
||||||
|
case E_BLOCK_JUNGLE_FENCE_GATE:
|
||||||
|
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_SPRUCE_DOOR:
|
||||||
|
case E_BLOCK_SPRUCE_FENCE_GATE:
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
File diff suppressed because it is too large
Load Diff
@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
|
|
||||||
class cRedstoneNoopSimulator :
|
class cRedstoneNoopSimulator :
|
||||||
public cRedstoneSimulator<cChunk, cWorld>
|
public cRedstoneSimulator
|
||||||
{
|
{
|
||||||
typedef cRedstoneSimulator<cChunk, cWorld> super;
|
typedef cRedstoneSimulator super;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
cRedstoneNoopSimulator(cWorld & a_World) :
|
cRedstoneNoopSimulator(cWorld & a_World) :
|
||||||
|
@ -13,14 +13,14 @@ public:
|
|||||||
|
|
||||||
inline cRedstoneSimulatorChunkData::~cRedstoneSimulatorChunkData() {}
|
inline cRedstoneSimulatorChunkData::~cRedstoneSimulatorChunkData() {}
|
||||||
|
|
||||||
template <class ChunkType, class WorldType>
|
|
||||||
class cRedstoneSimulator :
|
class cRedstoneSimulator :
|
||||||
public cSimulator<ChunkType, WorldType>
|
public cSimulator
|
||||||
{
|
{
|
||||||
typedef cSimulator<ChunkType, WorldType> super;
|
typedef cSimulator super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cRedstoneSimulator(WorldType & a_World) :
|
cRedstoneSimulator(cWorld & a_World) :
|
||||||
super(a_World)
|
super(a_World)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ typedef cCoordWithIntList cSandSimulatorChunkData;
|
|||||||
|
|
||||||
/// Despite the class name, this simulator takes care of all blocks that fall when suspended in the air.
|
/// Despite the class name, this simulator takes care of all blocks that fall when suspended in the air.
|
||||||
class cSandSimulator :
|
class cSandSimulator :
|
||||||
public cSimulator<cChunk, cWorld>
|
public cSimulator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cSandSimulator(cWorld & a_World, cIniFile & a_IniFile);
|
cSandSimulator(cWorld & a_World, cIniFile & a_IniFile);
|
||||||
|
@ -6,13 +6,35 @@
|
|||||||
#include "../Defines.h"
|
#include "../Defines.h"
|
||||||
#include "../Chunk.h"
|
#include "../Chunk.h"
|
||||||
|
|
||||||
#include "Simulator.inc"
|
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
#pragma clang diagnostic ignored "-Wweak-template-vtables"
|
#pragma clang diagnostic ignored "-Wweak-template-vtables"
|
||||||
#endif // __clang__
|
#endif // __clang__
|
||||||
|
|
||||||
template class cSimulator<cChunk, cWorld>;
|
|
||||||
|
|
||||||
|
#include "Simulator.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cSimulator::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk)
|
||||||
|
{
|
||||||
|
AddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk);
|
||||||
|
AddBlock(a_BlockX - 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX - 1, a_BlockZ));
|
||||||
|
AddBlock(a_BlockX + 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX + 1, a_BlockZ));
|
||||||
|
AddBlock(a_BlockX, a_BlockY, a_BlockZ - 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ - 1));
|
||||||
|
AddBlock(a_BlockX, a_BlockY, a_BlockZ + 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ + 1));
|
||||||
|
if (a_BlockY > 0)
|
||||||
|
{
|
||||||
|
AddBlock(a_BlockX, a_BlockY - 1, a_BlockZ, a_Chunk);
|
||||||
|
}
|
||||||
|
if (a_BlockY < cChunkDef::Height - 1)
|
||||||
|
{
|
||||||
|
AddBlock(a_BlockX, a_BlockY + 1, a_BlockZ, a_Chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,24 +3,28 @@
|
|||||||
|
|
||||||
#include "../Vector3.h"
|
#include "../Vector3.h"
|
||||||
|
|
||||||
|
class cWorld;
|
||||||
|
class cChunk;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class ChunkType, class WorldType>
|
|
||||||
class cSimulator
|
class cSimulator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cSimulator(WorldType & a_World);
|
cSimulator(cWorld & a_World)
|
||||||
virtual ~cSimulator();
|
: m_World(a_World)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~cSimulator() {}
|
||||||
|
|
||||||
/// Called in each tick, a_Dt is the time passed since the last tick, in msec
|
/// Called in each tick, a_Dt is the time passed since the last tick, in msec
|
||||||
virtual void Simulate(float a_Dt) = 0;
|
virtual void Simulate(float a_Dt) = 0;
|
||||||
|
|
||||||
/// Called in each tick for each chunk, a_Dt is the time passed since the last tick, in msec; direct access to chunk data available
|
/// Called in each tick for each chunk, a_Dt is the time passed since the last tick, in msec; direct access to chunk data available
|
||||||
virtual void SimulateChunk(float a_Dt, int a_ChunkX,
|
virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
|
||||||
int a_ChunkZ, ChunkType * a_Chunk)
|
|
||||||
{
|
{
|
||||||
UNUSED(a_Dt);
|
UNUSED(a_Dt);
|
||||||
UNUSED(a_ChunkX);
|
UNUSED(a_ChunkX);
|
||||||
@ -29,7 +33,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Called when a block changes
|
/// Called when a block changes
|
||||||
virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk);
|
virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk);
|
||||||
|
|
||||||
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) = 0;
|
virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) = 0;
|
||||||
|
|
||||||
@ -37,9 +41,9 @@ protected:
|
|||||||
friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up
|
friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up
|
||||||
|
|
||||||
/// Called to simulate a new block
|
/// Called to simulate a new block
|
||||||
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) = 0;
|
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) = 0;
|
||||||
|
|
||||||
WorldType & m_World;
|
cWorld & m_World;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "Simulator.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class ChunkType, class WorldType>
|
|
||||||
cSimulator<ChunkType, WorldType>::cSimulator(WorldType & a_World)
|
|
||||||
: m_World(a_World)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class ChunkType, class WorldType>
|
|
||||||
cSimulator<ChunkType, WorldType>::~cSimulator()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class ChunkType, class WorldType>
|
|
||||||
void cSimulator<ChunkType, WorldType>::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk)
|
|
||||||
{
|
|
||||||
AddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk);
|
|
||||||
AddBlock(a_BlockX - 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX - 1, a_BlockZ));
|
|
||||||
AddBlock(a_BlockX + 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX + 1, a_BlockZ));
|
|
||||||
AddBlock(a_BlockX, a_BlockY, a_BlockZ - 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ - 1));
|
|
||||||
AddBlock(a_BlockX, a_BlockY, a_BlockZ + 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ + 1));
|
|
||||||
if (a_BlockY > 0)
|
|
||||||
{
|
|
||||||
AddBlock(a_BlockX, a_BlockY - 1, a_BlockZ, a_Chunk);
|
|
||||||
}
|
|
||||||
if (a_BlockY < cChunkDef::Height - 1)
|
|
||||||
{
|
|
||||||
AddBlock(a_BlockX, a_BlockY + 1, a_BlockZ, a_Chunk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@ void cSimulatorManager::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cSimulatorManager::RegisterSimulator(cSimulator<cChunk, cWorld> * a_Simulator, int a_Rate)
|
void cSimulatorManager::RegisterSimulator(cSimulator * a_Simulator, int a_Rate)
|
||||||
{
|
{
|
||||||
m_Simulators.push_back(std::make_pair(a_Simulator, a_Rate));
|
m_Simulators.push_back(std::make_pair(a_Simulator, a_Rate));
|
||||||
}
|
}
|
||||||
|
@ -37,10 +37,10 @@ public:
|
|||||||
|
|
||||||
void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk);
|
void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk);
|
||||||
|
|
||||||
void RegisterSimulator(cSimulator<cChunk, cWorld> * a_Simulator, int a_Rate); // Takes ownership of the simulator object!
|
void RegisterSimulator(cSimulator * a_Simulator, int a_Rate); // Takes ownership of the simulator object!
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::vector <std::pair<cSimulator<cChunk, cWorld> *, int> > cSimulators;
|
typedef std::vector <std::pair<cSimulator *, int> > cSimulators;
|
||||||
|
|
||||||
cWorld & m_World;
|
cWorld & m_World;
|
||||||
cSimulators m_Simulators;
|
cSimulators m_Simulators;
|
||||||
|
@ -3352,7 +3352,7 @@ void cWorld::SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicke
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
cRedstoneSimulator<cChunk, cWorld> * cWorld::InitializeRedstoneSimulator(cIniFile & a_IniFile)
|
cRedstoneSimulator * cWorld::InitializeRedstoneSimulator(cIniFile & a_IniFile)
|
||||||
{
|
{
|
||||||
AString SimulatorName = a_IniFile.GetValueSet("Physics", "RedstoneSimulator", "Incremental");
|
AString SimulatorName = a_IniFile.GetValueSet("Physics", "RedstoneSimulator", "Incremental");
|
||||||
|
|
||||||
@ -3362,11 +3362,11 @@ cRedstoneSimulator<cChunk, cWorld> * cWorld::InitializeRedstoneSimulator(cIniFil
|
|||||||
SimulatorName = "Incremental";
|
SimulatorName = "Incremental";
|
||||||
}
|
}
|
||||||
|
|
||||||
cRedstoneSimulator<cChunk, cWorld> * res = nullptr;
|
cRedstoneSimulator * res = nullptr;
|
||||||
|
|
||||||
if (NoCaseCompare(SimulatorName, "Incremental") == 0)
|
if (NoCaseCompare(SimulatorName, "Incremental") == 0)
|
||||||
{
|
{
|
||||||
res = MakeIncrementalRedstoneSimulator(*this);
|
res = new cIncrementalRedstoneSimulator(*this);
|
||||||
}
|
}
|
||||||
else if (NoCaseCompare(SimulatorName, "noop") == 0)
|
else if (NoCaseCompare(SimulatorName, "noop") == 0)
|
||||||
{
|
{
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
class cFireSimulator;
|
class cFireSimulator;
|
||||||
class cFluidSimulator;
|
class cFluidSimulator;
|
||||||
class cSandSimulator;
|
class cSandSimulator;
|
||||||
template <class ChunkType, class WorldType>
|
|
||||||
class cRedstoneSimulator;
|
class cRedstoneSimulator;
|
||||||
class cItem;
|
class cItem;
|
||||||
class cPlayer;
|
class cPlayer;
|
||||||
@ -510,7 +509,7 @@ public:
|
|||||||
|
|
||||||
inline cFluidSimulator * GetWaterSimulator(void) { return m_WaterSimulator; }
|
inline cFluidSimulator * GetWaterSimulator(void) { return m_WaterSimulator; }
|
||||||
inline cFluidSimulator * GetLavaSimulator (void) { return m_LavaSimulator; }
|
inline cFluidSimulator * GetLavaSimulator (void) { return m_LavaSimulator; }
|
||||||
inline cRedstoneSimulator<cChunk, cWorld> * GetRedstoneSimulator(void) { return m_RedstoneSimulator; }
|
inline cRedstoneSimulator * GetRedstoneSimulator(void) { return m_RedstoneSimulator; }
|
||||||
|
|
||||||
/** Calls the callback for each block entity in the specified chunk; returns true if all block entities processed, false if the callback aborted by returning true */
|
/** Calls the callback for each block entity in the specified chunk; returns true if all block entities processed, false if the callback aborted by returning true */
|
||||||
bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||||
@ -919,7 +918,7 @@ private:
|
|||||||
cFluidSimulator * m_WaterSimulator;
|
cFluidSimulator * m_WaterSimulator;
|
||||||
cFluidSimulator * m_LavaSimulator;
|
cFluidSimulator * m_LavaSimulator;
|
||||||
std::unique_ptr<cFireSimulator> m_FireSimulator;
|
std::unique_ptr<cFireSimulator> m_FireSimulator;
|
||||||
cRedstoneSimulator<cChunk, cWorld> * m_RedstoneSimulator;
|
cRedstoneSimulator * m_RedstoneSimulator;
|
||||||
|
|
||||||
cCriticalSection m_CSPlayers;
|
cCriticalSection m_CSPlayers;
|
||||||
cPlayerList m_Players;
|
cPlayerList m_Players;
|
||||||
@ -1060,7 +1059,7 @@ private:
|
|||||||
cFluidSimulator * InitializeFluidSimulator(cIniFile & a_IniFile, const char * a_FluidName, BLOCKTYPE a_SimulateBlock, BLOCKTYPE a_StationaryBlock);
|
cFluidSimulator * InitializeFluidSimulator(cIniFile & a_IniFile, const char * a_FluidName, BLOCKTYPE a_SimulateBlock, BLOCKTYPE a_StationaryBlock);
|
||||||
|
|
||||||
/** Creates a new redstone simulator.*/
|
/** Creates a new redstone simulator.*/
|
||||||
cRedstoneSimulator<cChunk, cWorld> * InitializeRedstoneSimulator(cIniFile & a_IniFile);
|
cRedstoneSimulator * InitializeRedstoneSimulator(cIniFile & a_IniFile);
|
||||||
|
|
||||||
/** Adds the players queued in the m_PlayersToAdd queue into the m_Players list.
|
/** Adds the players queued in the m_PlayersToAdd queue into the m_Players list.
|
||||||
Assumes it is called from the Tick thread. */
|
Assumes it is called from the Tick thread. */
|
||||||
|
Loading…
Reference in New Issue
Block a user