Merge pull request #387 from mc-server/trapdoors
Trapdoors, redstone fixes, and snow
This commit is contained in:
commit
2bbe5046e9
@ -2095,10 +2095,6 @@
|
||||
RelativePath="..\src\Blocks\BlockBrewingStand.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\Blocks\BlockButton.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\Blocks\BlockButton.h"
|
||||
>
|
||||
@ -2127,10 +2123,6 @@
|
||||
RelativePath="..\src\Blocks\BlockCobWeb.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\Blocks\BlockComparator.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\Blocks\BlockComparator.h"
|
||||
>
|
||||
@ -2231,10 +2223,6 @@
|
||||
RelativePath="..\src\blocks\BlockLeaves.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\Blocks\BlockLever.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\Blocks\BlockLever.h"
|
||||
>
|
||||
@ -2283,10 +2271,6 @@
|
||||
RelativePath="..\src\Blocks\BlockRail.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\blocks\BlockRedstone.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\blocks\BlockRedstone.h"
|
||||
>
|
||||
@ -2295,10 +2279,6 @@
|
||||
RelativePath="..\src\blocks\BlockRedstoneOre.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\blocks\BlockRedstoneRepeater.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\blocks\BlockRedstoneRepeater.h"
|
||||
>
|
||||
@ -2351,6 +2331,10 @@
|
||||
RelativePath="..\src\blocks\BlockTorch.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\Blocks\BlockTrapdoor.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\blocks\BlockVine.h"
|
||||
>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug profiled|Win32">
|
||||
@ -185,6 +185,7 @@
|
||||
<ResourceCompile Include="MCServer.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\Blocks\BlockTrapdoor.h" />
|
||||
<ClInclude Include="resource_MCServer.h" />
|
||||
<ClInclude Include="..\src\Authenticator.h" />
|
||||
<ClInclude Include="..\src\BlockArea.h" />
|
||||
@ -794,14 +795,9 @@
|
||||
<ClCompile Include="..\src\Generating\StructGen.cpp" />
|
||||
<ClCompile Include="..\src\Generating\Trees.cpp" />
|
||||
<ClCompile Include="..\src\Blocks\BlockBed.cpp" />
|
||||
<ClCompile Include="..\src\Blocks\BlockButton.cpp" />
|
||||
<ClCompile Include="..\src\Blocks\BlockComparator.cpp" />
|
||||
<ClCompile Include="..\src\blocks\BlockDoor.cpp" />
|
||||
<ClCompile Include="..\src\blocks\BlockHandler.cpp" />
|
||||
<ClCompile Include="..\src\Blocks\BlockLever.cpp" />
|
||||
<ClCompile Include="..\src\blocks\BlockPiston.cpp" />
|
||||
<ClCompile Include="..\src\blocks\BlockRedstone.cpp" />
|
||||
<ClCompile Include="..\src\blocks\BlockRedstoneRepeater.cpp" />
|
||||
<ClCompile Include="..\src\items\ItemHandler.cpp" />
|
||||
<ClCompile Include="..\src\Protocol\ChunkDataSerializer.cpp" />
|
||||
<ClCompile Include="..\src\Protocol\Protocol125.cpp" />
|
||||
|
@ -942,6 +942,9 @@
|
||||
<ClInclude Include="..\src\HTTPServer\NameValueParser.h">
|
||||
<Filter>Source Files\HTTPServer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\Blocks\BlockTrapdoor.h">
|
||||
<Filter>Source Files\Blocks</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\webadmin\template.html">
|
||||
@ -1555,30 +1558,15 @@
|
||||
<ClCompile Include="..\src\Blocks\BlockBed.cpp">
|
||||
<Filter>Source Files\Blocks</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\Blocks\BlockButton.cpp">
|
||||
<Filter>Source Files\Blocks</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\Blocks\BlockComparator.cpp">
|
||||
<Filter>Source Files\Blocks</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\blocks\BlockDoor.cpp">
|
||||
<Filter>Source Files\Blocks</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\blocks\BlockHandler.cpp">
|
||||
<Filter>Source Files\Blocks</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\Blocks\BlockLever.cpp">
|
||||
<Filter>Source Files\Blocks</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\blocks\BlockPiston.cpp">
|
||||
<Filter>Source Files\Blocks</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\blocks\BlockRedstone.cpp">
|
||||
<Filter>Source Files\Blocks</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\blocks\BlockRedstoneRepeater.cpp">
|
||||
<Filter>Source Files\Blocks</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\items\ItemHandler.cpp">
|
||||
<Filter>Source Files\Items</Filter>
|
||||
</ClCompile>
|
||||
@ -1666,9 +1654,6 @@
|
||||
<ClCompile Include="..\src\HTTPServer\NameValueParser.cpp">
|
||||
<Filter>Source Files\HTTPServer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\source\BlockEntities\BlockEntity.cpp">
|
||||
<Filter>Source Files\BlockEntities</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="..\MCServer\API.txt">
|
||||
|
@ -174,7 +174,7 @@ enum ENUM_BLOCK_ID
|
||||
E_BLOCK_NEW_LEAVES = 161, // Acacia and Dark Oak IDs in Minecraft 1.7.x
|
||||
E_BLOCK_NEW_LOG = 162,
|
||||
E_BLOCK_ACACIA_WOOD_STAIRS = 163,
|
||||
E_BLOCK_DARK_OAK_WOOD_STAIRS = 164, /////////////////////////////////
|
||||
E_BLOCK_DARK_OAK_WOOD_STAIRS = 164,
|
||||
E_BLOCK_HAY_BALE = 170,
|
||||
E_BLOCK_CARPET = 171,
|
||||
E_BLOCK_HARDENED_CLAY = 172,
|
||||
@ -187,8 +187,7 @@ enum ENUM_BLOCK_ID
|
||||
E_BLOCK_NUMBER_OF_TYPES, ///< Number of individual (different) blocktypes
|
||||
E_BLOCK_MAX_TYPE_ID = E_BLOCK_NUMBER_OF_TYPES - 1, ///< Maximum BlockType number used
|
||||
|
||||
// Synonym or ID compatibility
|
||||
|
||||
// Synonym or ID compatibility
|
||||
E_BLOCK_YELLOW_FLOWER = E_BLOCK_DANDELION,
|
||||
E_BLOCK_RED_ROSE = E_BLOCK_FLOWER,
|
||||
E_BLOCK_LOCKED_CHEST = E_BLOCK_STAINED_GLASS,
|
||||
|
@ -1,32 +0,0 @@
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BlockButton.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBlockButtonHandler::cBlockButtonHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(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 the XOR bitwise operation
|
||||
NIBBLETYPE Meta = (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) | 0x08);
|
||||
|
||||
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);
|
||||
|
||||
// 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) & 0x07), m_BlockType == E_BLOCK_STONE_BUTTON ? 20 : 30);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -10,9 +10,23 @@ class cBlockButtonHandler :
|
||||
public cBlockHandler
|
||||
{
|
||||
public:
|
||||
cBlockButtonHandler(BLOCKTYPE a_BlockType);
|
||||
cBlockButtonHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
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 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
|
||||
{
|
||||
// Flip the ON bit on/off using the XOR bitwise operation
|
||||
NIBBLETYPE Meta = (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) | 0x08);
|
||||
|
||||
a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
|
||||
a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f);
|
||||
|
||||
// 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) & 0x07), m_BlockType == E_BLOCK_STONE_BUTTON ? 20 : 30);
|
||||
}
|
||||
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
@ -51,10 +65,10 @@ public:
|
||||
{
|
||||
switch (a_BlockFace)
|
||||
{
|
||||
case BLOCK_FACE_ZM: { return 0x4; }
|
||||
case BLOCK_FACE_ZP: { return 0x3; }
|
||||
case BLOCK_FACE_XM: { return 0x2; }
|
||||
case BLOCK_FACE_XP: { 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!");
|
||||
|
@ -1,53 +0,0 @@
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BlockComparator.h"
|
||||
#include "BlockRedstoneRepeater.h"
|
||||
#include "../Entities/Player.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBlockComparatorHandler::cBlockComparatorHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockComparatorHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Nothing needed yet
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockComparatorHandler::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)
|
||||
{
|
||||
NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
|
||||
Meta ^= 0x04; // Toggle 3rd (addition/subtraction) bit with XOR
|
||||
a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBlockComparatorHandler::GetPlacementBlockTypeMeta(
|
||||
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,
|
||||
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
|
||||
)
|
||||
{
|
||||
a_BlockType = m_BlockType;
|
||||
a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetRotation());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "BlockRedstoneRepeater.h"
|
||||
|
||||
|
||||
|
||||
@ -11,10 +12,18 @@ class cBlockComparatorHandler :
|
||||
public cBlockHandler
|
||||
{
|
||||
public:
|
||||
cBlockComparatorHandler(BLOCKTYPE a_BlockType);
|
||||
virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override;
|
||||
cBlockComparatorHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
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 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
|
||||
{
|
||||
NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
|
||||
Meta ^= 0x04; // Toggle 3rd (addition/subtraction) bit with XOR
|
||||
a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
|
||||
}
|
||||
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
@ -38,10 +47,15 @@ public:
|
||||
|
||||
virtual bool GetPlacementBlockTypeMeta(
|
||||
cWorld * a_World, cPlayer * a_Player,
|
||||
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
|
||||
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
|
||||
int a_CursorX, int a_CursorY, int a_CursorZ,
|
||||
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
|
||||
) override;
|
||||
) override
|
||||
{
|
||||
a_BlockType = m_BlockType;
|
||||
a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetRotation());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "BlockSugarcane.h"
|
||||
#include "BlockTallGrass.h"
|
||||
#include "BlockTorch.h"
|
||||
#include "BlockTrapdoor.h"
|
||||
#include "BlockVine.h"
|
||||
#include "BlockWood.h"
|
||||
#include "BlockWorkbench.h"
|
||||
@ -193,6 +194,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
|
||||
case E_BLOCK_SUGARCANE: return new cBlockSugarcaneHandler (a_BlockType);
|
||||
case E_BLOCK_TALL_GRASS: return new cBlockTallGrassHandler (a_BlockType);
|
||||
case E_BLOCK_TORCH: return new cBlockTorchHandler (a_BlockType);
|
||||
case E_BLOCK_TRAPDOOR: return new cBlockTrapdoorHandler (a_BlockType);
|
||||
case E_BLOCK_VINES: return new cBlockVineHandler (a_BlockType);
|
||||
case E_BLOCK_WALLSIGN: return new cBlockSignHandler (a_BlockType);
|
||||
case E_BLOCK_WATER: return new cBlockFluidHandler (a_BlockType);
|
||||
|
@ -98,7 +98,10 @@ public:
|
||||
*/
|
||||
virtual bool DoesIgnoreBuildCollision(void);
|
||||
|
||||
/// Does this block drop if it gets destroyed by an unsuitable situation? Default: true
|
||||
/// <summary>Similar to DoesIgnoreBuildCollision(void), but is used for cases where block meta/player item-in-hand is needed to determine collision (thin snow)</summary>
|
||||
virtual bool DoesIgnoreBuildCollision(cPlayer * a_Player, NIBBLETYPE a_Meta) { return DoesIgnoreBuildCollision(); }
|
||||
|
||||
/// <summary>Returns if this block drops if it gets destroyed by an unsuitable situation. Default: true</summary>
|
||||
virtual bool DoesDropOnUnsuitable(void);
|
||||
|
||||
/** Called when one of the neighbors gets set; equivalent to MC block update.
|
||||
@ -107,26 +110,30 @@ public:
|
||||
*/
|
||||
virtual void Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk);
|
||||
|
||||
/// Returns the meta for a block after rotating it counter-clockwise from the specified meta. Default: no change
|
||||
/// <summary>Rotates a given block meta counter-clockwise. Default: no change</summary>
|
||||
/// <returns>Block meta following rotation</returns>
|
||||
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) { return a_Meta; }
|
||||
|
||||
/// Returns the meta for a block after rotating it clockwise from the specified meta. Default: no change
|
||||
/// <summary>Rotates a given block meta clockwise. Default: no change</summary>
|
||||
/// <returns>Block meta following rotation</returns>
|
||||
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) { return a_Meta; }
|
||||
|
||||
/// Returns the meta for a block after mirroring it around the XY plane. Default: no change
|
||||
/// <summary>Mirros a given block meta around the XY plane. Default: no change</summary>
|
||||
/// <returns>Block meta following mirroring</returns>
|
||||
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) { return a_Meta; }
|
||||
|
||||
/// Returns the meta for a block after mirroring it around the XZ plane. Default: no change
|
||||
/// <summary>Mirros a given block meta around the XZ plane. Default: no change</summary>
|
||||
/// <returns>Block meta following mirroring</returns>
|
||||
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) { return a_Meta; }
|
||||
|
||||
/// Returns the meta for a block after mirroring it around the YZ plane. Default: no change
|
||||
/// <summary>Mirros a given block meta around the YZ plane. Default: no change</summary>
|
||||
/// <returns>Block meta following mirroring</returns>
|
||||
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) { return a_Meta; }
|
||||
|
||||
|
||||
/// Get the blockhandler for a specific block id
|
||||
|
||||
/// <summary>Get the blockhandler for a specific block id</summary>
|
||||
static cBlockHandler * GetBlockHandler(BLOCKTYPE a_BlockType);
|
||||
|
||||
/// Deletes all initialised block handlers
|
||||
/// <summary>Deletes all initialised block handlers</summary>
|
||||
static void Deinit();
|
||||
|
||||
protected:
|
||||
|
@ -1,31 +0,0 @@
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BlockLever.h"
|
||||
#include "../Entities/Player.h"
|
||||
#include "../Simulator/RedstoneSimulator.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBlockLeverHandler::cBlockLeverHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(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 the XOR bitwise operation
|
||||
NIBBLETYPE Meta = (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -10,9 +10,19 @@ class cBlockLeverHandler :
|
||||
public cBlockHandler
|
||||
{
|
||||
public:
|
||||
cBlockLeverHandler(BLOCKTYPE a_BlockType);
|
||||
cBlockLeverHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
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 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
|
||||
{
|
||||
// Flip the ON bit on/off using the XOR bitwise operation
|
||||
NIBBLETYPE Meta = (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08);
|
||||
|
||||
a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
|
||||
a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f);
|
||||
}
|
||||
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
|
@ -1,27 +0,0 @@
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BlockRedstone.h"
|
||||
#include "../Item.h"
|
||||
#include "../World.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBlockRedstoneHandler::cBlockRedstoneHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockRedstoneHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Nothing needed yet
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -12,9 +12,10 @@ class cBlockRedstoneHandler :
|
||||
public cBlockHandler
|
||||
{
|
||||
public:
|
||||
cBlockRedstoneHandler(BLOCKTYPE a_BlockType);
|
||||
|
||||
virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override;
|
||||
cBlockRedstoneHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
|
||||
|
@ -1,50 +0,0 @@
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BlockRedstoneRepeater.h"
|
||||
#include "../Entities/Player.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBlockRedstoneRepeaterHandler::cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockRedstoneRepeaterHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Nothing needed yet
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockRedstoneRepeaterHandler::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)
|
||||
{
|
||||
a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) + 0x04) & 0x0f));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBlockRedstoneRepeaterHandler::GetPlacementBlockTypeMeta(
|
||||
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,
|
||||
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
|
||||
)
|
||||
{
|
||||
a_BlockType = m_BlockType;
|
||||
a_BlockMeta = RepeaterRotationToMetaData(a_Player->GetRotation());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -11,10 +11,29 @@ class cBlockRedstoneRepeaterHandler :
|
||||
public cBlockHandler
|
||||
{
|
||||
public:
|
||||
cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType);
|
||||
virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override;
|
||||
cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual bool GetPlacementBlockTypeMeta(
|
||||
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,
|
||||
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
|
||||
) override
|
||||
{
|
||||
a_BlockType = m_BlockType;
|
||||
a_BlockMeta = RepeaterRotationToMetaData(a_Player->GetRotation());
|
||||
return true;
|
||||
}
|
||||
|
||||
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 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
|
||||
{
|
||||
a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) + 0x04) & 0x0f));
|
||||
}
|
||||
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
@ -34,14 +53,6 @@ public:
|
||||
{
|
||||
return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR));
|
||||
}
|
||||
|
||||
|
||||
virtual bool GetPlacementBlockTypeMeta(
|
||||
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,
|
||||
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
|
||||
) override;
|
||||
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
|
@ -25,21 +25,37 @@ public:
|
||||
) override
|
||||
{
|
||||
a_BlockType = m_BlockType;
|
||||
NIBBLETYPE Meta = a_World->GetBlockMeta(Vector3i(a_BlockX, a_BlockY, a_BlockZ));
|
||||
|
||||
if ((Meta < 7) && (Meta != 0)) // Is height at maximum (7) or at mininum (0)? Don't do anything if so
|
||||
BLOCKTYPE BlockBeforePlacement;
|
||||
NIBBLETYPE MetaBeforePlacement;
|
||||
a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockBeforePlacement, MetaBeforePlacement);
|
||||
|
||||
if ((BlockBeforePlacement == E_BLOCK_SNOW) && (MetaBeforePlacement < 7))
|
||||
{
|
||||
Meta++;
|
||||
// Only increment if:
|
||||
// A snow block was already there (not first time placement) AND
|
||||
// Height is smaller than 7, the maximum possible height
|
||||
MetaBeforePlacement++;
|
||||
}
|
||||
|
||||
a_BlockMeta = Meta;
|
||||
a_BlockMeta = MetaBeforePlacement;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
virtual bool DoesIgnoreBuildCollision(void) override
|
||||
virtual bool DoesIgnoreBuildCollision(cPlayer * a_Player, NIBBLETYPE a_Meta) override
|
||||
{
|
||||
return true;
|
||||
if ((a_Player->GetEquippedItem().m_ItemType == E_BLOCK_SNOW) && (a_Meta < 7))
|
||||
{
|
||||
return true; // If a player is holding a (thin) snow block and it's size can be increased, return collision ignored
|
||||
}
|
||||
|
||||
if (a_Meta == 0)
|
||||
{
|
||||
return true; // If at normal snowfall height (lowest), we ignore collision
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -51,7 +67,19 @@ public:
|
||||
|
||||
virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
|
||||
{
|
||||
return (a_RelY > 0) && g_BlockIsSnowable[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)];
|
||||
if (a_RelY > 0)
|
||||
{
|
||||
BLOCKTYPE BlockBelow = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ);
|
||||
NIBBLETYPE MetaBelow = a_Chunk.GetMeta(a_RelX, a_RelY - 1, a_RelZ);
|
||||
|
||||
if (g_BlockIsSnowable[BlockBelow] || ((BlockBelow == E_BLOCK_SNOW) && (MetaBelow == 7)))
|
||||
{
|
||||
// If block below is snowable, or it is a thin slow block and has a meta of 7 (full thin snow block), say yay
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,8 +47,28 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: step sound
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
if (
|
||||
(m_BlockType == E_BLOCK_WOODEN_STAIRS) ||
|
||||
(m_BlockType == E_BLOCK_SPRUCE_WOOD_STAIRS) ||
|
||||
(m_BlockType == E_BLOCK_JUNGLE_WOOD_STAIRS) ||
|
||||
(m_BlockType == E_BLOCK_ACACIA_WOOD_STAIRS) ||
|
||||
(m_BlockType == E_BLOCK_BIRCH_WOOD_STAIRS) ||
|
||||
(m_BlockType == E_BLOCK_DARK_OAK_WOOD_STAIRS)
|
||||
)
|
||||
{
|
||||
return "step.wood";
|
||||
}
|
||||
|
||||
return "step.stone";
|
||||
}
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// Reset meta to 0
|
||||
a_Pickups.push_back(cItem(m_BlockType, 1, 0));
|
||||
}
|
||||
|
||||
static NIBBLETYPE RotationToMetaData(double a_Rotation)
|
||||
{
|
||||
|
@ -2,7 +2,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "../MersenneTwister.h"
|
||||
#include "../World.h"
|
||||
|
||||
|
||||
|
108
src/Blocks/BlockTrapdoor.h
Normal file
108
src/Blocks/BlockTrapdoor.h
Normal file
@ -0,0 +1,108 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockTrapdoorHandler :
|
||||
public cBlockHandler
|
||||
{
|
||||
public:
|
||||
cBlockTrapdoorHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.wood";
|
||||
}
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// Reset meta to 0
|
||||
a_Pickups.push_back(cItem(m_BlockType, 1, 0));
|
||||
}
|
||||
|
||||
virtual bool IsUseable(void) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// Flip the ON bit on/off using the XOR bitwise operation
|
||||
NIBBLETYPE Meta = (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x04);
|
||||
|
||||
a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
|
||||
}
|
||||
|
||||
virtual bool GetPlacementBlockTypeMeta(
|
||||
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,
|
||||
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
|
||||
) override
|
||||
{
|
||||
a_BlockType = m_BlockType;
|
||||
a_BlockMeta = BlockFaceToMetaData(a_BlockFace);
|
||||
|
||||
/* TODO: fix CursorY issues and uncomment this
|
||||
if (a_CursorY > 7)
|
||||
{
|
||||
a_BlockMeta |= 0x8;
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
inline static NIBBLETYPE BlockFaceToMetaData(char a_BlockFace)
|
||||
{
|
||||
switch (a_BlockFace)
|
||||
{
|
||||
case BLOCK_FACE_ZP: return 0x1;
|
||||
case BLOCK_FACE_ZM: return 0x0;
|
||||
case BLOCK_FACE_XP: return 0x3;
|
||||
case BLOCK_FACE_XM: return 0x2;
|
||||
default:
|
||||
{
|
||||
ASSERT(!"Unhandled block face!");
|
||||
return 0x0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline static NIBBLETYPE BlockMetaDataToBlockFace(NIBBLETYPE a_Meta)
|
||||
{
|
||||
switch (a_Meta & 0x3)
|
||||
{
|
||||
case 0x0: return BLOCK_FACE_ZM;
|
||||
case 0x1: return BLOCK_FACE_ZP;
|
||||
case 0x2: return BLOCK_FACE_XM;
|
||||
case 0x3: return BLOCK_FACE_XP;
|
||||
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.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta);
|
||||
|
||||
AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true);
|
||||
BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
|
||||
|
||||
return (a_RelY > 0) && (g_BlockIsSolid[BlockIsOn]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -891,14 +891,14 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, c
|
||||
else
|
||||
{
|
||||
// Check if the block ignores build collision (water, grass etc.):
|
||||
cBlockHandler * Handler = cBlockHandler::GetBlockHandler(ClickedBlock);
|
||||
if (Handler->DoesIgnoreBuildCollision())
|
||||
if (
|
||||
BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision() ||
|
||||
BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision(m_Player, ClickedBlockMeta)
|
||||
)
|
||||
{
|
||||
Handler->OnDestroyedByPlayer(World, m_Player, a_BlockX, a_BlockY, a_BlockZ);
|
||||
BlockHandler(ClickedBlock)->OnDestroyedByPlayer(World, m_Player, a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
|
||||
BLOCKTYPE PlaceBlock = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
|
||||
if (!BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision())
|
||||
else
|
||||
{
|
||||
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
|
||||
|
||||
@ -908,7 +908,9 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, c
|
||||
return;
|
||||
}
|
||||
|
||||
BLOCKTYPE PlaceBlock = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
|
||||
NIBBLETYPE PlaceMeta;
|
||||
BLOCKTYPE PlaceBlock;
|
||||
World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, PlaceBlock, PlaceMeta);
|
||||
|
||||
// Clicked on side of block, make sure that placement won't be cancelled if there is a slab able to be double slabbed.
|
||||
// No need to do combinability (dblslab) checks, client will do that here.
|
||||
@ -918,10 +920,13 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, c
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision())
|
||||
if (
|
||||
!BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision() &&
|
||||
!BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision(m_Player, PlaceMeta)
|
||||
)
|
||||
{
|
||||
// Tried to place a block *into* another?
|
||||
// Happens when you place a block aiming at side of block like torch or stem
|
||||
// Happens when you place a block aiming at side of block with a torch on it or stem beside it
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -76,6 +76,90 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
|
||||
int BaseX = a_Chunk->GetPosX() * cChunkDef::Width;
|
||||
int BaseZ = a_Chunk->GetPosZ() * cChunkDef::Width;
|
||||
|
||||
// Check to see if PoweredBlocks have invalid items (source is air or unpowered)
|
||||
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end();)
|
||||
{
|
||||
sPoweredBlocks & Change = *itr;
|
||||
|
||||
int RelX = Change.a_SourcePos.x - a_ChunkX * cChunkDef::Width;
|
||||
int RelZ = Change.a_SourcePos.z - a_ChunkZ * cChunkDef::Width;
|
||||
|
||||
BLOCKTYPE SourceBlockType;
|
||||
NIBBLETYPE SourceBlockMeta;
|
||||
if (!a_Chunk->UnboundedRelGetBlock(RelX, Change.a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (SourceBlockType != Change.a_SourceBlock)
|
||||
{
|
||||
itr = m_PoweredBlocks.erase(itr);
|
||||
LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past block type mismatch", ItemToFullString(Change.a_SourceBlock));
|
||||
}
|
||||
else if (
|
||||
// Changeable sources
|
||||
((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (SourceBlockMeta == 0)) ||
|
||||
((SourceBlockType == E_BLOCK_LEVER) && !IsLeverOn(SourceBlockMeta)) ||
|
||||
((SourceBlockType == E_BLOCK_DETECTOR_RAIL) && (SourceBlockMeta & 0x08) == 0x08) ||
|
||||
(((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta)))
|
||||
)
|
||||
{
|
||||
itr = m_PoweredBlocks.erase(itr);
|
||||
LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past metadata mismatch", ItemToFullString(Change.a_SourceBlock));
|
||||
}
|
||||
else
|
||||
{
|
||||
itr++;
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if LinkedPoweredBlocks have invalid items: source, block powered through, or power destination block has changed
|
||||
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end();)
|
||||
{
|
||||
sLinkedPoweredBlocks & Change = *itr;
|
||||
|
||||
int RelX = Change.a_SourcePos.x - a_ChunkX * cChunkDef::Width;
|
||||
int RelZ = Change.a_SourcePos.z - a_ChunkZ * cChunkDef::Width;
|
||||
int MidRelX = Change.a_MiddlePos.x - a_ChunkX * cChunkDef::Width;
|
||||
int MidRelZ = Change.a_MiddlePos.z - a_ChunkZ * cChunkDef::Width;
|
||||
|
||||
BLOCKTYPE SourceBlockType;
|
||||
NIBBLETYPE SourceBlockMeta;
|
||||
BLOCKTYPE MiddleBlockType;
|
||||
if (
|
||||
!a_Chunk->UnboundedRelGetBlock(RelX, Change.a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta) ||
|
||||
!a_Chunk->UnboundedRelGetBlockType(MidRelX, Change.a_MiddlePos.y, MidRelZ, MiddleBlockType)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (SourceBlockType != Change.a_SourceBlock)
|
||||
{
|
||||
itr = m_LinkedPoweredBlocks.erase(itr);
|
||||
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past block type mismatch", ItemToFullString(Change.a_SourceBlock));
|
||||
}
|
||||
else if (MiddleBlockType != Change.a_MiddleBlock)
|
||||
{
|
||||
itr = m_LinkedPoweredBlocks.erase(itr);
|
||||
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past middle block mismatch", ItemToFullString(Change.a_SourceBlock));
|
||||
}
|
||||
else if (
|
||||
// Things that can send power through a block but which depends on meta
|
||||
((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (SourceBlockMeta == 0)) ||
|
||||
((SourceBlockType == E_BLOCK_LEVER) && !IsLeverOn(SourceBlockMeta)) ||
|
||||
(((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta)))
|
||||
)
|
||||
{
|
||||
itr = m_LinkedPoweredBlocks.erase(itr);
|
||||
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past metadata mismatch", ItemToFullString(Change.a_SourceBlock));
|
||||
}
|
||||
else
|
||||
{
|
||||
itr++;
|
||||
}
|
||||
}
|
||||
|
||||
for (cRedstoneSimulatorChunkData::iterator dataitr = ChunkData.begin(), end = ChunkData.end(); dataitr != end;)
|
||||
{
|
||||
BLOCKTYPE BlockType = a_Chunk->GetBlock(dataitr->x, dataitr->y, dataitr->z);
|
||||
@ -85,83 +169,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check to see if PoweredBlocks have invalid items (source is air or unpowered)
|
||||
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end();)
|
||||
{
|
||||
sPoweredBlocks & Change = *itr;
|
||||
|
||||
int RelX = Change.a_SourcePos.x - a_ChunkX * cChunkDef::Width;
|
||||
int RelZ = Change.a_SourcePos.z - a_ChunkZ * cChunkDef::Width;
|
||||
|
||||
BLOCKTYPE SourceBlockType;
|
||||
NIBBLETYPE SourceBlockMeta;
|
||||
a_Chunk->UnboundedRelGetBlock(RelX, Change.a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta);
|
||||
|
||||
if (SourceBlockType != Change.a_SourceBlock)
|
||||
{
|
||||
itr = m_PoweredBlocks.erase(itr);
|
||||
LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past block type mismatch", ItemToFullString(Change.a_SourceBlock));
|
||||
}
|
||||
else if (
|
||||
// Changeable sources
|
||||
((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (SourceBlockMeta == 0)) ||
|
||||
((SourceBlockType == E_BLOCK_LEVER) && !IsLeverOn(SourceBlockMeta)) ||
|
||||
((SourceBlockType == E_BLOCK_DETECTOR_RAIL) && (SourceBlockMeta & 0x08) == 0x08) ||
|
||||
(((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta)))
|
||||
)
|
||||
{
|
||||
itr = m_PoweredBlocks.erase(itr);
|
||||
LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past metadata mismatch", ItemToFullString(Change.a_SourceBlock));
|
||||
}
|
||||
else
|
||||
{
|
||||
itr++;
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if LinkedPoweredBlocks have invalid items: source, block powered through, or power destination block has changed
|
||||
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end();)
|
||||
{
|
||||
sLinkedPoweredBlocks & Change = *itr;
|
||||
|
||||
int RelX = Change.a_SourcePos.x - a_ChunkX * cChunkDef::Width;
|
||||
int RelZ = Change.a_SourcePos.z - a_ChunkZ * cChunkDef::Width;
|
||||
int MidRelX = Change.a_MiddlePos.x - a_ChunkX * cChunkDef::Width;
|
||||
int MidRelZ = Change.a_MiddlePos.z - a_ChunkZ * cChunkDef::Width;
|
||||
|
||||
BLOCKTYPE SourceBlockType;
|
||||
NIBBLETYPE SourceBlockMeta;
|
||||
BLOCKTYPE MiddleBlockType;
|
||||
a_Chunk->UnboundedRelGetBlock(RelX, Change.a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta);
|
||||
a_Chunk->UnboundedRelGetBlockType(MidRelX, Change.a_MiddlePos.y, MidRelZ, MiddleBlockType);
|
||||
|
||||
if (SourceBlockType != Change.a_SourceBlock)
|
||||
{
|
||||
itr = m_LinkedPoweredBlocks.erase(itr);
|
||||
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past block type mismatch", ItemToFullString(Change.a_SourceBlock));
|
||||
}
|
||||
else if (MiddleBlockType != Change.a_MiddleBlock)
|
||||
{
|
||||
itr = m_LinkedPoweredBlocks.erase(itr);
|
||||
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past middle block mismatch", ItemToFullString(Change.a_SourceBlock));
|
||||
}
|
||||
else if (
|
||||
// Things that can send power through a block but which depends on meta
|
||||
((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (SourceBlockMeta == 0)) ||
|
||||
((SourceBlockType == E_BLOCK_LEVER) && !IsLeverOn(SourceBlockMeta)) ||
|
||||
(((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta)))
|
||||
)
|
||||
{
|
||||
itr = m_LinkedPoweredBlocks.erase(itr);
|
||||
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past metadata mismatch", ItemToFullString(Change.a_SourceBlock));
|
||||
}
|
||||
else
|
||||
{
|
||||
itr++;
|
||||
}
|
||||
}
|
||||
|
||||
// PoweredBlock list was fine, now to the actual handling
|
||||
// PoweredBlock and LinkedPoweredBlock list was fine, now to the actual handling
|
||||
int a_X = BaseX + dataitr->x;
|
||||
int a_Z = BaseZ + dataitr->z;
|
||||
switch (BlockType)
|
||||
@ -169,6 +177,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
|
||||
case E_BLOCK_BLOCK_OF_REDSTONE: HandleRedstoneBlock(a_X, dataitr->y, a_Z); break;
|
||||
case E_BLOCK_LEVER: HandleRedstoneLever(a_X, dataitr->y, a_Z); break;
|
||||
case E_BLOCK_TNT: HandleTNT(a_X, dataitr->y, a_Z); break;
|
||||
case E_BLOCK_TRAPDOOR: HandleTrapdoor(a_X, dataitr->y, a_Z); break;
|
||||
case E_BLOCK_REDSTONE_WIRE: HandleRedstoneWire(a_X, dataitr->y, a_Z); break;
|
||||
|
||||
case E_BLOCK_REDSTONE_TORCH_OFF:
|
||||
@ -406,7 +415,9 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl
|
||||
|
||||
if (SurroundMeta > 1) // Wires of power 1 or 0 cannot transfer power TO ME, don't bother checking
|
||||
{
|
||||
if (SurroundMeta > MyMeta) // Does surrounding wire have a higher power level than self?
|
||||
// Does surrounding wire have a higher power level than self?
|
||||
// >= to fix a bug where wires bordering each other with the same power level will appear (in terms of meta) to power each other, when they aren't actually in the powered list
|
||||
if (SurroundMeta >= MyMeta)
|
||||
{
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, SurroundMeta - 1);
|
||||
}
|
||||
@ -555,7 +566,7 @@ void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int
|
||||
void cRedstoneSimulator::HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
cPiston Piston(&m_World);
|
||||
if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ))
|
||||
if (IsPistonPowered(a_BlockX, a_BlockY, a_BlockZ, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x7)) // We only want the bottom three bits (4th controls extended-ness)
|
||||
{
|
||||
Piston.ExtendPiston(a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
@ -717,6 +728,22 @@ void cRedstoneSimulator::HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BL
|
||||
|
||||
|
||||
|
||||
void cRedstoneSimulator::HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) | 0x4);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0xB); // Take into account that the fourth bit is needed for trapdoors too
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cRedstoneSimulator::AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list
|
||||
@ -747,7 +774,8 @@ bool cRedstoneSimulator::AreCoordsPowered(int a_BlockX, int a_BlockY, int a_Bloc
|
||||
|
||||
bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta)
|
||||
{
|
||||
// Check through powered blocks list
|
||||
// Repeaters cannot be powered by any face except their back; verify that this is true for a source
|
||||
|
||||
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr)
|
||||
{
|
||||
sPoweredBlocks & Change = *itr;
|
||||
@ -780,7 +808,6 @@ bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_Blo
|
||||
}
|
||||
}
|
||||
|
||||
// Check linked powered list, 'middle' blocks
|
||||
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr)
|
||||
{
|
||||
sLinkedPoweredBlocks & Change = *itr;
|
||||
@ -817,6 +844,53 @@ bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_Blo
|
||||
|
||||
|
||||
|
||||
bool cRedstoneSimulator::IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta)
|
||||
{
|
||||
// Pistons cannot be powered through their front face; this function verifies that a source meets this requirement
|
||||
|
||||
int OldX = a_BlockX, OldY = a_BlockY, OldZ = a_BlockZ;
|
||||
|
||||
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr)
|
||||
{
|
||||
sPoweredBlocks & Change = *itr;
|
||||
|
||||
if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
|
||||
|
||||
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_Meta); // Piston meta is based on what direction they face, so we can do this
|
||||
|
||||
if (!Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
a_BlockX = OldX;
|
||||
a_BlockY = OldY;
|
||||
a_BlockZ = OldZ;
|
||||
}
|
||||
|
||||
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr)
|
||||
{
|
||||
sLinkedPoweredBlocks & Change = *itr;
|
||||
|
||||
if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
|
||||
|
||||
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_Meta);
|
||||
|
||||
if (!Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
a_BlockX = OldX;
|
||||
a_BlockY = OldY;
|
||||
a_BlockZ = OldZ;
|
||||
}
|
||||
return false; // Source was in front of the piston's front face
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceType)
|
||||
{
|
||||
@ -1086,7 +1160,6 @@ void cRedstoneSimulator::SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_B
|
||||
void cRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock)
|
||||
{
|
||||
if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_AIR) { return; } // Don't set air, fixes some bugs (wires powering themselves)
|
||||
if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) { return; } // Check for duplicates
|
||||
|
||||
sPoweredBlocks RC;
|
||||
RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
|
||||
@ -1107,7 +1180,6 @@ void cRedstoneSimulator::SetBlockLinkedPowered(int a_BlockX, int a_BlockY, int a
|
||||
)
|
||||
{
|
||||
if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_AIR) { return; } // Don't set air, fixes some bugs (wires powering themselves)
|
||||
if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) { return; } // Check for duplicates
|
||||
if (!IsViableMiddleBlock(m_World.GetBlock(a_MiddleX, a_MiddleY, a_MiddleZ))) { return; } // See if middle block is viable
|
||||
|
||||
sLinkedPoweredBlocks RC;
|
||||
|
@ -93,6 +93,8 @@ private:
|
||||
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);
|
||||
/// <summary>Handles trapdoors</summary>
|
||||
void HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/* ===================== */
|
||||
|
||||
/* ====== Helper functions ====== */
|
||||
@ -109,6 +111,8 @@ private:
|
||||
bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/// <summary>Returns if a repeater is powered</summary>
|
||||
bool IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
|
||||
/// <summary>Returns if a piston is powered</summary>
|
||||
bool IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
|
||||
|
||||
/// <summary>Returns if lever metadata marks it as emitting power</summary>
|
||||
bool IsLeverOn(NIBBLETYPE a_BlockMeta);
|
||||
|
Loading…
Reference in New Issue
Block a user