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 102master
parent
b5821998b4
commit
bc1e236d54
|
@ -669,13 +669,13 @@ public:
|
|||
g_BlockTransparent[E_BLOCK_FLOWER_POT] = true;
|
||||
g_BlockTransparent[E_BLOCK_GLASS] = true;
|
||||
g_BlockTransparent[E_BLOCK_GLASS_PANE] = true;
|
||||
g_BlockTransparent[E_BLOCK_STAINED_GLASS] = true;
|
||||
g_BlockTransparent[E_BLOCK_STAINED_GLASS_PANE] = true;
|
||||
g_BlockTransparent[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE] = true;
|
||||
g_BlockTransparent[E_BLOCK_ICE] = true;
|
||||
g_BlockTransparent[E_BLOCK_IRON_DOOR] = true;
|
||||
g_BlockTransparent[E_BLOCK_LAVA] = true;
|
||||
g_BlockTransparent[E_BLOCK_LEAVES] = true;
|
||||
g_BlockTransparent[E_BLOCK_LEVER] = true;
|
||||
g_BlockTransparent[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE] = true;
|
||||
g_BlockTransparent[E_BLOCK_MELON_STEM] = true;
|
||||
g_BlockTransparent[E_BLOCK_NETHER_BRICK_FENCE] = true;
|
||||
g_BlockTransparent[E_BLOCK_NEW_LEAVES] = true;
|
||||
|
@ -687,6 +687,8 @@ public:
|
|||
g_BlockTransparent[E_BLOCK_RED_MUSHROOM] = true;
|
||||
g_BlockTransparent[E_BLOCK_SIGN_POST] = true;
|
||||
g_BlockTransparent[E_BLOCK_SNOW] = true;
|
||||
g_BlockTransparent[E_BLOCK_STAINED_GLASS] = true;
|
||||
g_BlockTransparent[E_BLOCK_STAINED_GLASS_PANE] = true;
|
||||
g_BlockTransparent[E_BLOCK_STATIONARY_LAVA] = true;
|
||||
g_BlockTransparent[E_BLOCK_STATIONARY_WATER] = true;
|
||||
g_BlockTransparent[E_BLOCK_STONE_PRESSURE_PLATE] = true;
|
||||
|
@ -700,7 +702,7 @@ public:
|
|||
|
||||
// TODO: Any other transparent blocks?
|
||||
|
||||
// One hit break blocks
|
||||
// One hit break blocks:
|
||||
g_BlockOneHitDig[E_BLOCK_ACTIVE_COMPARATOR] = true;
|
||||
g_BlockOneHitDig[E_BLOCK_BIG_FLOWER] = true;
|
||||
g_BlockOneHitDig[E_BLOCK_BROWN_MUSHROOM] = true;
|
||||
|
@ -711,7 +713,6 @@ public:
|
|||
g_BlockOneHitDig[E_BLOCK_FLOWER] = true;
|
||||
g_BlockOneHitDig[E_BLOCK_FLOWER_POT] = true;
|
||||
g_BlockOneHitDig[E_BLOCK_INACTIVE_COMPARATOR] = true;
|
||||
g_BlockOneHitDig[E_BLOCK_LOCKED_CHEST] = true;
|
||||
g_BlockOneHitDig[E_BLOCK_MELON_STEM] = true;
|
||||
g_BlockOneHitDig[E_BLOCK_POTATOES] = true;
|
||||
g_BlockOneHitDig[E_BLOCK_PUMPKIN_STEM] = true;
|
||||
|
@ -727,7 +728,7 @@ public:
|
|||
g_BlockOneHitDig[E_BLOCK_TALL_GRASS] = true;
|
||||
g_BlockOneHitDig[E_BLOCK_TORCH] = true;
|
||||
|
||||
// Blocks that breaks when pushed by piston
|
||||
// Blocks that break when pushed by piston:
|
||||
g_BlockPistonBreakable[E_BLOCK_ACTIVE_COMPARATOR] = true;
|
||||
g_BlockPistonBreakable[E_BLOCK_AIR] = true;
|
||||
g_BlockPistonBreakable[E_BLOCK_BED] = true;
|
||||
|
@ -765,11 +766,12 @@ public:
|
|||
g_BlockPistonBreakable[E_BLOCK_TORCH] = true;
|
||||
g_BlockPistonBreakable[E_BLOCK_VINES] = true;
|
||||
g_BlockPistonBreakable[E_BLOCK_WATER] = true;
|
||||
g_BlockPistonBreakable[E_BLOCK_WOODEN_BUTTON] = true;
|
||||
g_BlockPistonBreakable[E_BLOCK_WOODEN_DOOR] = true;
|
||||
g_BlockPistonBreakable[E_BLOCK_WOODEN_PRESSURE_PLATE] = true;
|
||||
|
||||
|
||||
// Blocks that can be snowed over:
|
||||
// Blocks that cannot be snowed over:
|
||||
g_BlockIsSnowable[E_BLOCK_ACTIVE_COMPARATOR] = false;
|
||||
g_BlockIsSnowable[E_BLOCK_AIR] = false;
|
||||
g_BlockIsSnowable[E_BLOCK_BIG_FLOWER] = false;
|
||||
|
@ -785,7 +787,6 @@ public:
|
|||
g_BlockIsSnowable[E_BLOCK_INACTIVE_COMPARATOR] = false;
|
||||
g_BlockIsSnowable[E_BLOCK_LAVA] = false;
|
||||
g_BlockIsSnowable[E_BLOCK_LILY_PAD] = false;
|
||||
g_BlockIsSnowable[E_BLOCK_LOCKED_CHEST] = false;
|
||||
g_BlockIsSnowable[E_BLOCK_REDSTONE_REPEATER_OFF] = false;
|
||||
g_BlockIsSnowable[E_BLOCK_REDSTONE_REPEATER_ON] = false;
|
||||
g_BlockIsSnowable[E_BLOCK_REDSTONE_TORCH_OFF] = false;
|
||||
|
@ -796,6 +797,8 @@ public:
|
|||
g_BlockIsSnowable[E_BLOCK_SAPLING] = false;
|
||||
g_BlockIsSnowable[E_BLOCK_SIGN_POST] = false;
|
||||
g_BlockIsSnowable[E_BLOCK_SNOW] = false;
|
||||
g_BlockIsSnowable[E_BLOCK_STAINED_GLASS] = false;
|
||||
g_BlockIsSnowable[E_BLOCK_STAINED_GLASS_PANE] = false;
|
||||
g_BlockIsSnowable[E_BLOCK_STATIONARY_LAVA] = false;
|
||||
g_BlockIsSnowable[E_BLOCK_STATIONARY_WATER] = false;
|
||||
g_BlockIsSnowable[E_BLOCK_TALL_GRASS] = false;
|
||||
|
@ -806,7 +809,7 @@ public:
|
|||
g_BlockIsSnowable[E_BLOCK_WATER] = false;
|
||||
|
||||
|
||||
// Blocks that don't drop without a special tool
|
||||
// Blocks that don't drop without a special tool:
|
||||
g_BlockRequiresSpecialTool[E_BLOCK_BRICK] = true;
|
||||
g_BlockRequiresSpecialTool[E_BLOCK_CAULDRON] = true;
|
||||
g_BlockRequiresSpecialTool[E_BLOCK_COAL_ORE] = true;
|
||||
|
@ -841,7 +844,7 @@ public:
|
|||
g_BlockRequiresSpecialTool[E_BLOCK_STONE_SLAB] = true;
|
||||
g_BlockRequiresSpecialTool[E_BLOCK_VINES] = true;
|
||||
|
||||
// Nonsolid Blocks:
|
||||
// Nonsolid blocks:
|
||||
g_BlockIsSolid[E_BLOCK_ACTIVATOR_RAIL] = false;
|
||||
g_BlockIsSolid[E_BLOCK_AIR] = false;
|
||||
g_BlockIsSolid[E_BLOCK_BIG_FLOWER] = false;
|
||||
|
@ -860,11 +863,8 @@ public:
|
|||
g_BlockIsSolid[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE] = false;
|
||||
g_BlockIsSolid[E_BLOCK_MELON_STEM] = false;
|
||||
g_BlockIsSolid[E_BLOCK_NETHER_PORTAL] = false;
|
||||
g_BlockIsSolid[E_BLOCK_PISTON] = false;
|
||||
g_BlockIsSolid[E_BLOCK_PISTON_EXTENSION] = false;
|
||||
g_BlockIsSolid[E_BLOCK_RAIL] = false;
|
||||
g_BlockIsSolid[E_BLOCK_REDSTONE_REPEATER_OFF] = false;
|
||||
g_BlockIsSolid[E_BLOCK_REDSTONE_REPEATER_ON] = false;
|
||||
g_BlockIsSolid[E_BLOCK_REDSTONE_TORCH_OFF] = false;
|
||||
g_BlockIsSolid[E_BLOCK_REDSTONE_TORCH_ON] = false;
|
||||
g_BlockIsSolid[E_BLOCK_REDSTONE_WIRE] = false;
|
||||
|
@ -887,7 +887,7 @@ public:
|
|||
g_BlockIsSolid[E_BLOCK_WOODEN_PRESSURE_PLATE] = false;
|
||||
g_BlockIsSolid[E_BLOCK_WOODEN_SLAB] = false;
|
||||
|
||||
// Torch placeable
|
||||
// Torch placeable blocks:
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_BEDROCK] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_BLOCK_OF_COAL] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_BLOCK_OF_REDSTONE] = true;
|
||||
|
@ -933,7 +933,7 @@ public:
|
|||
g_BlockIsTorchPlaceable[E_BLOCK_NETHER_QUARTZ_ORE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_NOTE_BLOCK] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_OBSIDIAN] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_PACKED_ICE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_PACKED_ICE] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_PLANKS] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_PUMPKIN] = true;
|
||||
g_BlockIsTorchPlaceable[E_BLOCK_QUARTZ_BLOCK] = true;
|
||||
|
@ -955,3 +955,4 @@ public:
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -17,21 +17,14 @@ cBlockButtonHandler::cBlockButtonHandler(BLOCKTYPE a_BlockType)
|
|||
|
||||
void cBlockButtonHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
|
||||
{
|
||||
// Flip the ON bit on/off. Using XOR bitwise operation to turn it on/off.
|
||||
// Flip the ON bit on/off using the XOR bitwise operation
|
||||
NIBBLETYPE Meta = ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08) & 0x0f);
|
||||
a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
|
||||
|
||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta);
|
||||
a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f);
|
||||
|
||||
if (Meta & 0x08)
|
||||
{
|
||||
a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f);
|
||||
}
|
||||
else
|
||||
{
|
||||
a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.5f);
|
||||
}
|
||||
|
||||
// Queue a button reset (unpress), with a GetBlock to prevent duplication of buttons (press, break, wait for reset)
|
||||
a_World->QueueSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ), ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08) & 0x0f), m_BlockType == E_BLOCK_STONE_BUTTON ? 20 : 25);
|
||||
// Queue a button reset (unpress)
|
||||
a_World->QueueSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08) & 0x0f), m_BlockType == E_BLOCK_STONE_BUTTON ? 20 : 30);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,11 +14,11 @@ public:
|
|||
|
||||
virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override;
|
||||
|
||||
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// Reset meta to 0
|
||||
a_Pickups.push_back(cItem(m_BlockType == E_BLOCK_WOODEN_BUTTON ? E_BLOCK_WOODEN_BUTTON : E_BLOCK_STONE_BUTTON, 1, 0));
|
||||
a_Pickups.push_back(cItem(m_BlockType, 1, 0));
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,10 +51,10 @@ public:
|
|||
{
|
||||
switch (a_BlockFace)
|
||||
{
|
||||
case BLOCK_FACE_ZP: { return 0x4; }
|
||||
case BLOCK_FACE_ZM: { return 0x3; }
|
||||
case BLOCK_FACE_XP: { return 0x2; }
|
||||
case BLOCK_FACE_XM: { return 0x1; }
|
||||
case BLOCK_FACE_ZM: { return 0x4; }
|
||||
case BLOCK_FACE_ZP: { return 0x3; }
|
||||
case BLOCK_FACE_XM: { return 0x2; }
|
||||
case BLOCK_FACE_XP: { return 0x1; }
|
||||
default:
|
||||
{
|
||||
ASSERT(!"Unhandled block face!");
|
||||
|
@ -62,6 +62,30 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline static NIBBLETYPE BlockMetaDataToBlockFace(NIBBLETYPE a_Meta)
|
||||
{
|
||||
switch (a_Meta & 0x7)
|
||||
{
|
||||
case 0x1: return BLOCK_FACE_XP;
|
||||
case 0x2: return BLOCK_FACE_XM;
|
||||
case 0x3: return BLOCK_FACE_ZP;
|
||||
case 0x4: return BLOCK_FACE_ZM;
|
||||
default:
|
||||
{
|
||||
ASSERT(!"Unhandled block meta!");
|
||||
return BLOCK_FACE_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
|
||||
{
|
||||
NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
|
||||
|
||||
AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true);
|
||||
return (a_RelY > 0) && (g_BlockIsSolid[a_Chunk.GetBlock(a_RelX, a_RelY, a_RelZ)]);
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
#include "Globals.h"
|
||||
#include "BlockComparator.h"
|
||||
#include "../Simulator/RedstoneSimulator.h"
|
||||
#include "BlockRedstoneRepeater.h"
|
||||
#include "../Entities/Player.h"
|
||||
|
||||
|
||||
|
@ -44,7 +44,7 @@ bool cBlockComparatorHandler::GetPlacementBlockTypeMeta(
|
|||
)
|
||||
{
|
||||
a_BlockType = m_BlockType;
|
||||
a_BlockMeta = cRedstoneSimulator::RepeaterRotationToMetaData(a_Player->GetRotation());
|
||||
a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetRotation());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,18 +19,11 @@ cBlockLeverHandler::cBlockLeverHandler(BLOCKTYPE a_BlockType)
|
|||
|
||||
void cBlockLeverHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
|
||||
{
|
||||
// Flip the ON bit on/off. Using XOR bitwise operation to turn it on/off.
|
||||
// Flip the ON bit on/off using the XOR bitwise operation
|
||||
NIBBLETYPE Meta = ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08) & 0x0f);
|
||||
|
||||
a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
|
||||
if (Meta & 0x08)
|
||||
{
|
||||
a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f);
|
||||
}
|
||||
else
|
||||
{
|
||||
a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.5f);
|
||||
}
|
||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta);
|
||||
a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "../Simulator/RedstoneSimulator.h"
|
||||
|
||||
|
||||
|
||||
|
@ -37,11 +36,27 @@ public:
|
|||
) override
|
||||
{
|
||||
a_BlockType = m_BlockType;
|
||||
a_BlockMeta = cRedstoneSimulator::LeverDirectionToMetaData(a_BlockFace);
|
||||
a_BlockMeta = LeverDirectionToMetaData(a_BlockFace);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline static NIBBLETYPE LeverDirectionToMetaData(char a_Dir)
|
||||
{
|
||||
// Determine lever direction:
|
||||
switch (a_Dir)
|
||||
{
|
||||
case BLOCK_FACE_TOP: return 0x6;
|
||||
case BLOCK_FACE_EAST: return 0x1;
|
||||
case BLOCK_FACE_WEST: return 0x2;
|
||||
case BLOCK_FACE_SOUTH: return 0x3;
|
||||
case BLOCK_FACE_NORTH: return 0x4;
|
||||
case BLOCK_FACE_BOTTOM: return 0x0;
|
||||
default: return 0x6;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.wood";
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
#include "Globals.h"
|
||||
#include "BlockRedstoneRepeater.h"
|
||||
#include "../Simulator/RedstoneSimulator.h"
|
||||
#include "../Entities/Player.h"
|
||||
|
||||
|
||||
|
@ -42,7 +41,7 @@ bool cBlockRedstoneRepeaterHandler::GetPlacementBlockTypeMeta(
|
|||
)
|
||||
{
|
||||
a_BlockType = m_BlockType;
|
||||
a_BlockMeta = cRedstoneSimulator::RepeaterRotationToMetaData(a_Player->GetRotation());
|
||||
a_BlockMeta = RepeaterRotationToMetaData(a_Player->GetRotation());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,33 @@ public:
|
|||
{
|
||||
return "step.wood";
|
||||
}
|
||||
|
||||
|
||||
inline static NIBBLETYPE RepeaterRotationToMetaData(double a_Rotation)
|
||||
{
|
||||
a_Rotation += 90 + 45; // So its not aligned with axis
|
||||
if (a_Rotation > 360)
|
||||
{
|
||||
a_Rotation -= 360;
|
||||
}
|
||||
|
||||
if ((a_Rotation >= 0) && (a_Rotation < 90))
|
||||
{
|
||||
return 0x1;
|
||||
}
|
||||
else if ((a_Rotation >= 180) && (a_Rotation < 270))
|
||||
{
|
||||
return 0x3;
|
||||
}
|
||||
else if ((a_Rotation >= 90) && (a_Rotation < 180))
|
||||
{
|
||||
return 0x2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0x0;
|
||||
}
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
|
|
@ -682,18 +682,18 @@ void cChunk::ProcessQueuedSetBlocks(void)
|
|||
Int64 CurrTick = m_World->GetWorldAge();
|
||||
for (sSetBlockQueueVector::iterator itr = m_SetBlockQueue.begin(); itr != m_SetBlockQueue.end();)
|
||||
{
|
||||
if (itr->m_Tick < CurrTick)
|
||||
if (itr->m_Tick <= CurrTick)
|
||||
{
|
||||
// Current world age is bigger than/equal to target world age - delay time reached
|
||||
SetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta);
|
||||
itr = m_SetBlockQueue.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not yet
|
||||
++itr;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Now is the time to set the block
|
||||
SetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta);
|
||||
itr = m_SetBlockQueue.erase(itr);
|
||||
}
|
||||
} // for itr - m_SetBlockQueue[]
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "Simulator/FireSimulator.h"
|
||||
#include "Simulator/SandSimulator.h"
|
||||
#include "Simulator/RedstoneSimulator.h"
|
||||
|
||||
|
||||
|
||||
|
@ -338,6 +339,7 @@ public:
|
|||
cFluidSimulatorData * GetWaterSimulatorData(void) { return m_WaterSimulatorData; }
|
||||
cFluidSimulatorData * GetLavaSimulatorData (void) { return m_LavaSimulatorData; }
|
||||
cSandSimulatorChunkData & GetSandSimulatorData (void) { return m_SandSimulatorData; }
|
||||
cRedstoneSimulatorChunkData & GetRedstoneSimulatorData(void) { return m_RedstoneSimulatorData; }
|
||||
|
||||
cBlockEntity * GetBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
cBlockEntity * GetBlockEntity(const Vector3i & a_BlockPos) { return GetBlockEntity(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z); }
|
||||
|
@ -407,6 +409,7 @@ private:
|
|||
cFluidSimulatorData * m_WaterSimulatorData;
|
||||
cFluidSimulatorData * m_LavaSimulatorData;
|
||||
cSandSimulatorChunkData m_SandSimulatorData;
|
||||
cRedstoneSimulatorChunkData m_RedstoneSimulatorData;
|
||||
|
||||
|
||||
// pick up a random block of this chunk
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "ItemHandler.h"
|
||||
#include "../Simulator/RedstoneSimulator.h"
|
||||
#include "../Blocks/BlockRedstoneRepeater.h"
|
||||
|
||||
|
||||
|
||||
|
@ -30,7 +30,7 @@ public:
|
|||
) override
|
||||
{
|
||||
a_BlockType = E_BLOCK_INACTIVE_COMPARATOR;
|
||||
a_BlockMeta = cRedstoneSimulator::RepeaterRotationToMetaData(a_Player->GetRotation());
|
||||
a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetRotation());
|
||||
return true;
|
||||
}
|
||||
} ;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "ItemHandler.h"
|
||||
#include "../Simulator/RedstoneSimulator.h"
|
||||
#include "../Blocks/BlockRedstoneRepeater.h"
|
||||
|
||||
|
||||
|
||||
|
@ -30,7 +30,7 @@ public:
|
|||
) override
|
||||
{
|
||||
a_BlockType = E_BLOCK_REDSTONE_REPEATER_OFF;
|
||||
a_BlockMeta = cRedstoneSimulator::RepeaterRotationToMetaData(a_Player->GetRotation());
|
||||
a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetRotation());
|
||||
return true;
|
||||
}
|
||||
} ;
|
||||
|
|
|
@ -14,14 +14,8 @@
|
|||
|
||||
|
||||
|
||||
extern bool g_BlockPistonBreakable[];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Number of ticks that the piston extending / retracting waits before setting the block
|
||||
const int PISTON_TICK_DELAY = 20;
|
||||
const int PISTON_TICK_DELAY = 6;
|
||||
|
||||
|
||||
|
||||
|
@ -120,7 +114,7 @@ void cPiston::ExtendPiston(int pistx, int pisty, int pistz)
|
|||
AddDir(pistx, pisty, pistz, pistonMeta, -1);
|
||||
// "pist" now at piston body, "ext" at future extension
|
||||
|
||||
m_World->QueueSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta | 0x8, PISTON_TICK_DELAY);
|
||||
m_World->SetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta | 0x8);
|
||||
m_World->QueueSetBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0), PISTON_TICK_DELAY);
|
||||
}
|
||||
|
||||
|
@ -141,7 +135,7 @@ void cPiston::RetractPiston(int pistx, int pisty, int pistz)
|
|||
|
||||
m_World->BroadcastBlockAction(pistx, pisty, pistz, 1, pistonMeta & ~(8), pistonBlock);
|
||||
m_World->BroadcastSoundEffect("tile.piston.in", pistx * 8, pisty * 8, pistz * 8, 0.5f, 0.7f);
|
||||
m_World->QueueSetBlock(pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8), PISTON_TICK_DELAY);
|
||||
m_World->SetBlock(pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8));
|
||||
|
||||
// Check the extension:
|
||||
AddDir(pistx, pisty, pistz, pistonMeta, 1);
|
||||
|
@ -199,15 +193,6 @@ bool cPiston::IsSticky(BLOCKTYPE a_BlockType)
|
|||
|
||||
|
||||
|
||||
bool cPiston::IsStickyExtension(NIBBLETYPE a_ExtMeta)
|
||||
{
|
||||
return ((a_ExtMeta & 0x08) != 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPiston::CanPush(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
|
||||
{
|
||||
switch (a_BlockType)
|
||||
|
|
|
@ -63,9 +63,6 @@ public:
|
|||
|
||||
/// Returns true if the piston (with the specified meta) is extended
|
||||
static bool IsExtended(NIBBLETYPE a_PistonMeta);
|
||||
|
||||
/// Returns true if the extension (with the specified meta) is sticky
|
||||
static bool IsStickyExtension(NIBBLETYPE a_ExtMeta);
|
||||
|
||||
/// Returns true if the specified block can be pushed by a piston (and left intact)
|
||||
static bool CanPush(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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 <Vector3i> BlockList;
|
||||
|
||||
typedef std::deque< sRepeaterChange > RepeaterList;
|
||||
RepeaterList m_SetRepeaters;
|
||||
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 SetRepeater(const Vector3i & a_Position, int a_Ticks, bool a_bPowerOn);
|
||||
typedef std::vector <sPoweredBlocks> PoweredBlocksList;
|
||||
typedef std::vector <sLinkedPoweredBlocks> LinkedBlocksList;
|
||||
|
||||
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override {}
|
||||
PoweredBlocksList m_PoweredBlocks;
|
||||
LinkedBlocksList m_LinkedPoweredBlocks;
|
||||
|
||||
void HandleChange( const Vector3i & a_BlockPos );
|
||||
BlockList RemoveCurrent( const Vector3i & a_BlockPos );
|
||||
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override;
|
||||
|
||||
bool PowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock, char a_Power );
|
||||
int UnPowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock );
|
||||
// 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
|
||||
|
||||
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;
|
||||
/* ====== SOURCES ====== */
|
||||
///<summary>Handles the redstone torch</summary>
|
||||
void HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
|
||||
///<summary>Handles the redstone block</summary>
|
||||
void HandleRedstoneBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
///<summary>Handles levers</summary>
|
||||
void HandleRedstoneLever(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
///<summary>Handles buttons</summary>
|
||||
void HandleRedstoneButton(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType);
|
||||
/* ==================== */
|
||||
|
||||
BlockList m_RefreshPistons;
|
||||
BlockList m_RefreshDropSpensers;
|
||||
/* ====== CARRIERS ====== */
|
||||
///<summary>Handles redstone wire</summary>
|
||||
void HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
///<summary>Handles repeaters</summary>
|
||||
void HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
|
||||
/* ====================== */
|
||||
|
||||
BlockList m_RefreshTorchesAround;
|
||||
|
||||
void RefreshTorchesAround( const Vector3i & a_BlockPos );
|
||||
/* ====== DEVICES ====== */
|
||||
///<summary>Handles pistons</summary>
|
||||
void HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
///<summary>Handles dispensers and droppers</summary>
|
||||
void HandleDropSpenser(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
///<summary>Handles TNT (exploding)</summary>
|
||||
void HandleTNT(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
///<summary>Handles redstone lamps</summary>
|
||||
void HandleRedstoneLamp(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
|
||||
///<summary>Handles doords</summary>
|
||||
void HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
///<summary>Handles activator, detector, and powered rails</summary>
|
||||
void HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType);
|
||||
/* ===================== */
|
||||
|
||||
// TODO: The entire simulator is synchronized, no need to lock data structures; remove this
|
||||
cCriticalSection m_CS;
|
||||
};
|
||||
/* ====== 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;
|
||||
}
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue