From 07baf9bdd3b04e3aec6e77f367eb38c0547f54ca Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 20 May 2014 15:52:59 +0300 Subject: Cleaned up cPlayer::UpdateMovementStats; Wither achievements --- src/Blocks/BlockMobHead.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src/Blocks') diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index acd1c88fb..552c0491c 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -46,8 +46,29 @@ public: bool IsWither(void) const { return m_IsWither; } void Reset(void) { m_IsWither = false; } + } CallbackA, CallbackB; + class cPlayerCallback : public cPlayerListCallback + { + Vector3f m_Pos; + + virtual bool Item(cPlayer * a_Player) + { + double Dist = (a_Player->GetPosition() - m_Pos).Length(); + if (Dist < 50.0) + { + // If player is close, award achievement + a_Player->AwardAchievement(achSpawnWither); + } + return false; + } + + public: + cPlayerCallback(const Vector3f & a_Pos) : m_Pos(a_Pos) {} + + } PlayerCallback(Vector3f(a_BlockX, a_BlockY, a_BlockZ)); + a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA); if (!CallbackA.IsWither()) @@ -86,6 +107,9 @@ public: // Spawn the wither: a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); + // Award Achievement + a_World->ForEachPlayer(PlayerCallback); + return true; } @@ -113,6 +137,9 @@ public: // Spawn the wither: a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); + // Award Achievement + a_World->ForEachPlayer(PlayerCallback); + return true; } -- cgit v1.2.3 From 7aeb8ce9936e8ebd203d67100de8635d391bd8a1 Mon Sep 17 00:00:00 2001 From: andrew Date: Wed, 21 May 2014 10:59:14 +0300 Subject: Fixed cWither::KilledBy --- src/Blocks/BlockMobHead.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/Blocks') diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 552c0491c..b7629b07c 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -55,6 +55,7 @@ public: virtual bool Item(cPlayer * a_Player) { + // TODO 2014-05-21 xdot: Vanilla minecraft uses an AABB check instead of a radius one double Dist = (a_Player->GetPosition() - m_Pos).Length(); if (Dist < 50.0) { -- cgit v1.2.3 From ee929793f09c431693e1bef7edd77213ba412f60 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 25 May 2014 13:46:34 +0100 Subject: Hopefully fixed piston duplication issues * Fixes #879 * Fixes #714 --- src/Blocks/BlockDropSpenser.h | 4 +- src/Blocks/BlockFurnace.h | 4 +- src/Blocks/BlockMobHead.h | 2 +- src/Blocks/BlockPiston.cpp | 166 ++++++++++++++++++++++++++++++++++++++++-- src/Blocks/BlockPiston.h | 129 +++++++++++++++++++++++++++++++- 5 files changed, 294 insertions(+), 11 deletions(-) (limited to 'src/Blocks') diff --git a/src/Blocks/BlockDropSpenser.h b/src/Blocks/BlockDropSpenser.h index 88b61a418..e2b3039fd 100644 --- a/src/Blocks/BlockDropSpenser.h +++ b/src/Blocks/BlockDropSpenser.h @@ -5,7 +5,7 @@ #pragma once -#include "../Piston.h" +#include "../Blocks/BlockPiston.h" #include "MetaRotator.h" @@ -32,7 +32,7 @@ public: a_BlockType = m_BlockType; // FIXME: Do not use cPiston class for dispenser placement! - a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetYaw(), a_Player->GetPitch()); + a_BlockMeta = cBlockPistonHandler::RotationPitchToMetaData(a_Player->GetYaw(), a_Player->GetPitch()); return true; } diff --git a/src/Blocks/BlockFurnace.h b/src/Blocks/BlockFurnace.h index a7a807957..74582c3b3 100644 --- a/src/Blocks/BlockFurnace.h +++ b/src/Blocks/BlockFurnace.h @@ -3,7 +3,7 @@ #include "BlockEntity.h" #include "../World.h" -#include "../Piston.h" +#include "../Blocks/BlockPiston.h" #include "MetaRotator.h" @@ -35,7 +35,7 @@ public: a_BlockType = m_BlockType; // FIXME: Do not use cPiston class for furnace placement! - a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetYaw(), 0); + a_BlockMeta = cBlockPistonHandler::RotationPitchToMetaData(a_Player->GetYaw(), 0); return true; } diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index b7629b07c..9855574ad 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -68,7 +68,7 @@ public: public: cPlayerCallback(const Vector3f & a_Pos) : m_Pos(a_Pos) {} - } PlayerCallback(Vector3f(a_BlockX, a_BlockY, a_BlockZ)); + } PlayerCallback(Vector3f((float)a_BlockX, (float)a_BlockY, (float)a_BlockZ)); a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA); diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index 542eb33b5..f758013dc 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -4,14 +4,14 @@ #include "../Item.h" #include "../World.h" #include "../Entities/Player.h" -#include "../Piston.h" +#include "BlockInServerPluginInterface.h" #define AddPistonDir(x, y, z, dir, amount) \ - switch (dir) \ + switch (dir & 0x07) \ { \ case 0: (y) -= (amount); break; \ case 1: (y) += (amount); break; \ @@ -19,8 +19,15 @@ case 3: (z) += (amount); break; \ case 4: (x) -= (amount); break; \ case 5: (x) += (amount); break; \ + default: \ + { \ + LOGWARNING("%s: invalid direction %d, ignoring", __FUNCTION__, dir & 0x07); \ + break; \ + } \ } +#define PISTON_TICK_DELAY 1 + @@ -40,7 +47,7 @@ void cBlockPistonHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorld int newX = a_BlockX; int newY = a_BlockY; int newZ = a_BlockZ; - AddPistonDir(newX, newY, newZ, OldMeta & ~(8), 1); + AddPistonDir(newX, newY, newZ, OldMeta, 1); if (a_ChunkInterface.GetBlock(newX, newY, newZ) == E_BLOCK_PISTON_EXTENSION) { @@ -60,7 +67,7 @@ bool cBlockPistonHandler::GetPlacementBlockTypeMeta( ) { a_BlockType = m_BlockType; - a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetYaw(), a_Player->GetPitch()); + a_BlockMeta = RotationPitchToMetaData(a_Player->GetYaw(), a_Player->GetPitch()); return true; } @@ -68,6 +75,155 @@ bool cBlockPistonHandler::GetPlacementBlockTypeMeta( +int cBlockPistonHandler::FirstPassthroughBlock(int pistonX, int pistonY, int pistonZ, NIBBLETYPE pistonmeta, cWorld * a_World) +{ + // Examine each of the 12 blocks ahead of the piston: + for (int ret = 0; ret < 12; ret++) + { + BLOCKTYPE currBlock; + NIBBLETYPE currMeta; + AddPistonDir(pistonX, pistonY, pistonZ, pistonmeta, 1); + a_World->GetBlockTypeMeta(pistonX, pistonY, pistonZ, currBlock, currMeta); + if (CanBreakPush(currBlock)) + { + // This block breaks when pushed, extend up to here + return ret; + } + if (!CanPush(currBlock, currMeta)) + { + // This block cannot be pushed at all, the piston can't extend + return -1; + } + } + // There is no space for the blocks to move, piston can't extend + return -1; +} + + + + + +void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) +{ + BLOCKTYPE pistonBlock; + NIBBLETYPE pistonMeta; + a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta); + + if (IsExtended(pistonMeta)) + { + // Already extended, bail out + return; + } + + int dist = FirstPassthroughBlock(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, a_World); + if (dist < 0) + { + // FirstPassthroughBlock says piston can't push anything, bail out + return; + } + + a_World->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, 0, pistonMeta, pistonBlock); + a_World->BroadcastSoundEffect("tile.piston.out", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.7f); + + // Drop the breakable block in the line, if appropriate: + AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, dist + 1); // "a_Block" now at the breakable / empty block + BLOCKTYPE currBlock; + NIBBLETYPE currMeta; + a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, currBlock, currMeta); + if (currBlock != E_BLOCK_AIR) + { + cBlockHandler * Handler = BlockHandler(currBlock); + if (Handler->DoesDropOnUnsuitable()) + { + cChunkInterface ChunkInterface(a_World->GetChunkMap()); + cBlockInServerPluginInterface PluginInterface(*a_World); + Handler->DropBlock(ChunkInterface, *a_World, PluginInterface, NULL, a_BlockX, a_BlockY, a_BlockZ); + } + } + + // Push blocks, from the furthest to the nearest: + int oldx = a_BlockX, oldy = a_BlockY, oldz = a_BlockZ; + NIBBLETYPE currBlockMeta; + for (int i = dist + 1; i > 1; i--) + { + AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1); + a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, currBlock, currBlockMeta); + a_World->SetBlock(oldx, oldy, oldz, currBlock, currBlockMeta, false); + a_World->ScheduleTask(PISTON_TICK_DELAY, new cWorld::cTaskSendBlockToAllPlayers(oldx, oldy, oldz)); + oldx = a_BlockX; + oldy = a_BlockY; + oldz = a_BlockZ; + } + + int extx = a_BlockX; + int exty = a_BlockY; + int extz = a_BlockZ; + AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1); + // "a_Block" now at piston body, "ext" at future extension + + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta | 0x8); + a_World->SetBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0), false); + a_World->ScheduleTask(PISTON_TICK_DELAY, new cWorld::cTaskSendBlockToAllPlayers(extx, exty, extz)); +} + + + + + +void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) +{ + BLOCKTYPE pistonBlock; + NIBBLETYPE pistonMeta; + a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta); + + if (!IsExtended(pistonMeta)) + { + // Already retracted, bail out + return; + } + + // Check the extension: + AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, 1); + if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_PISTON_EXTENSION) + { + LOGD("%s: Piston without an extension - still extending, or just in an invalid state?", __FUNCTION__); + return; + } + + AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1); + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta & ~(8)); + a_World->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, 1, pistonMeta & ~(8), pistonBlock); + a_World->BroadcastSoundEffect("tile.piston.in", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.7f); + AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, 1); + + // Retract the extension, pull block if appropriate + if (IsSticky(pistonBlock)) + { + int tempx = a_BlockX, tempy = a_BlockY, tempz = a_BlockZ; + AddPistonDir(tempx, tempy, tempz, pistonMeta, 1); + BLOCKTYPE tempBlock; + NIBBLETYPE tempMeta; + a_World->GetBlockTypeMeta(tempx, tempy, tempz, tempBlock, tempMeta); + if (CanPull(tempBlock, tempMeta)) + { + // Pull the block + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, tempBlock, tempMeta, false); + a_World->SetBlock(tempx, tempy, tempz, E_BLOCK_AIR, 0, false); + a_World->ScheduleTask(PISTON_TICK_DELAY + 1, new cWorld::cTaskSendBlockToAllPlayers(a_BlockX, a_BlockY, a_BlockZ)); + a_World->ScheduleTask(PISTON_TICK_DELAY, new cWorld::cTaskSendBlockToAllPlayers(tempx, tempy, tempz)); + return; + } + } + + // Retract without pulling + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0, false); + a_World->ScheduleTask(PISTON_TICK_DELAY + 1, new cWorld::cTaskSendBlockToAllPlayers(a_BlockX, a_BlockY, a_BlockZ)); +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cBlockPistonHeadHandler: @@ -87,7 +243,7 @@ void cBlockPistonHeadHandler::OnDestroyedByPlayer(cChunkInterface & a_ChunkInter int newX = a_BlockX; int newY = a_BlockY; int newZ = a_BlockZ; - AddPistonDir(newX, newY, newZ, OldMeta & ~(8), -1); + AddPistonDir(newX, newY, newZ, OldMeta, -1); BLOCKTYPE Block = a_ChunkInterface.GetBlock(newX, newY, newZ); if ((Block == E_BLOCK_STICKY_PISTON) || (Block == E_BLOCK_PISTON)) diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index 7632b5e5a..d7c92925b 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -21,6 +21,133 @@ public: int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta ) override; + + static NIBBLETYPE RotationPitchToMetaData(double a_Rotation, double a_Pitch) + { + if (a_Pitch >= 50) + { + return 0x1; + } + else if (a_Pitch <= -50) + { + return 0x0; + } + else + { + 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 0x4; + } + else if ((a_Rotation >= 180) && (a_Rotation < 270)) + { + return 0x5; + } + else if ((a_Rotation >= 90) && (a_Rotation < 180)) + { + return 0x2; + } + else + { + return 0x3; + } + } + } + + static eBlockFace MetaDataToDirection(NIBBLETYPE a_MetaData) + { + switch (a_MetaData) + { + case 0x0: return BLOCK_FACE_YM; + case 0x1: return BLOCK_FACE_YP; + case 0x2: return BLOCK_FACE_ZM; + case 0x3: return BLOCK_FACE_ZP; + case 0x4: return BLOCK_FACE_XM; + case 0x5: return BLOCK_FACE_XP; + default: + { + ASSERT(!"Invalid Metadata"); + return BLOCK_FACE_NONE; + } + } + } + + static void ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); + static void RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); + +private: + + /// Returns true if the piston (specified by blocktype) is a sticky piston + static inline bool IsSticky(BLOCKTYPE a_BlockType) { return (a_BlockType == E_BLOCK_STICKY_PISTON); } + + /// Returns true if the piston (with the specified meta) is extended + static inline bool IsExtended(NIBBLETYPE a_PistonMeta) { return ((a_PistonMeta & 0x8) != 0x0); } + + /// Returns true if the specified block can be pushed by a piston (and left intact) + static inline bool CanPush(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) + { + switch (a_BlockType) + { + case E_BLOCK_ANVIL: + case E_BLOCK_BED: + case E_BLOCK_BEDROCK: + case E_BLOCK_BREWING_STAND: + case E_BLOCK_CHEST: + case E_BLOCK_COMMAND_BLOCK: + case E_BLOCK_DISPENSER: + case E_BLOCK_DROPPER: + case E_BLOCK_ENCHANTMENT_TABLE: + case E_BLOCK_END_PORTAL: + case E_BLOCK_END_PORTAL_FRAME: + case E_BLOCK_FURNACE: + case E_BLOCK_LIT_FURNACE: + case E_BLOCK_HOPPER: + case E_BLOCK_JUKEBOX: + case E_BLOCK_MOB_SPAWNER: + case E_BLOCK_NETHER_PORTAL: + case E_BLOCK_NOTE_BLOCK: + case E_BLOCK_OBSIDIAN: + case E_BLOCK_PISTON_EXTENSION: + { + return false; + } + case E_BLOCK_STICKY_PISTON: + case E_BLOCK_PISTON: + { + // A piston can only be pushed if retracted: + return !IsExtended(a_BlockMeta); + } + } + return true; + } + + /// Returns true if the specified block can be pushed by a piston and broken / replaced + static inline bool CanBreakPush(BLOCKTYPE a_BlockType) { return cBlockInfo::IsPistonBreakable(a_BlockType); } + + /// Returns true if the specified block can be pulled by a sticky piston + static inline bool CanPull(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) + { + switch (a_BlockType) + { + case E_BLOCK_LAVA: + case E_BLOCK_STATIONARY_LAVA: + case E_BLOCK_STATIONARY_WATER: + case E_BLOCK_WATER: + { + return false; + } + } + + return CanBreakPush(a_BlockType) ? false /* CanBreakPush returns true, but we need false to prevent pulling */ : CanPush(a_BlockType, a_BlockMeta); + } + + /// Returns how many blocks the piston has to push (where the first free space is); < 0 when unpushable + static int FirstPassthroughBlock(int a_PistonX, int a_PistonY, int a_PistonZ, NIBBLETYPE a_PistonMeta, cWorld * a_World); } ; @@ -40,7 +167,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // No pickups - // Also with 1.7, the item forms of these tecnical blocks have been removed, so giving someone this will crash their client... + // Also with 1.7, the item forms of these technical blocks have been removed, so giving someone this will crash their client... } } ; -- cgit v1.2.3 From 365c6f50bd057eb62c66b9b222a07ca6efcb2c47 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 29 May 2014 11:57:06 +0100 Subject: Changed block send queue to use vectors As suggested by @worktycho. --- src/Blocks/BlockPiston.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'src/Blocks') diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index f758013dc..1f8e0d9e0 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -27,6 +27,7 @@ } #define PISTON_TICK_DELAY 1 +#define PISTON_MAX_PUSH_DISTANCE 12 @@ -78,7 +79,7 @@ bool cBlockPistonHandler::GetPlacementBlockTypeMeta( int cBlockPistonHandler::FirstPassthroughBlock(int pistonX, int pistonY, int pistonZ, NIBBLETYPE pistonmeta, cWorld * a_World) { // Examine each of the 12 blocks ahead of the piston: - for (int ret = 0; ret < 12; ret++) + for (int ret = 0; ret < PISTON_MAX_PUSH_DISTANCE; ret++) { BLOCKTYPE currBlock; NIBBLETYPE currMeta; @@ -144,12 +145,15 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, // Push blocks, from the furthest to the nearest: int oldx = a_BlockX, oldy = a_BlockY, oldz = a_BlockZ; NIBBLETYPE currBlockMeta; + std::vector ScheduledBlocks; + ScheduledBlocks.reserve(PISTON_MAX_PUSH_DISTANCE); + for (int i = dist + 1; i > 1; i--) { AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1); a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, currBlock, currBlockMeta); a_World->SetBlock(oldx, oldy, oldz, currBlock, currBlockMeta, false); - a_World->ScheduleTask(PISTON_TICK_DELAY, new cWorld::cTaskSendBlockToAllPlayers(oldx, oldy, oldz)); + ScheduledBlocks.push_back(Vector3i(oldx, oldy, oldz)); oldx = a_BlockX; oldy = a_BlockY; oldz = a_BlockZ; @@ -158,12 +162,13 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, int extx = a_BlockX; int exty = a_BlockY; int extz = a_BlockZ; + ScheduledBlocks.push_back(Vector3i(extx, exty, extz)); AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1); // "a_Block" now at piston body, "ext" at future extension a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta | 0x8); a_World->SetBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0), false); - a_World->ScheduleTask(PISTON_TICK_DELAY, new cWorld::cTaskSendBlockToAllPlayers(extx, exty, extz)); + a_World->ScheduleTask(PISTON_TICK_DELAY, new cWorld::cTaskSendBlockToAllPlayers(ScheduledBlocks)); } @@ -209,15 +214,21 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ // Pull the block a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, tempBlock, tempMeta, false); a_World->SetBlock(tempx, tempy, tempz, E_BLOCK_AIR, 0, false); - a_World->ScheduleTask(PISTON_TICK_DELAY + 1, new cWorld::cTaskSendBlockToAllPlayers(a_BlockX, a_BlockY, a_BlockZ)); - a_World->ScheduleTask(PISTON_TICK_DELAY, new cWorld::cTaskSendBlockToAllPlayers(tempx, tempy, tempz)); + + std::vector ScheduledBlocks; + ScheduledBlocks.push_back(Vector3i(a_BlockX, a_BlockY, a_BlockZ)); + ScheduledBlocks.push_back(Vector3i(tempx, tempy, tempz)); + a_World->ScheduleTask(PISTON_TICK_DELAY + 1, new cWorld::cTaskSendBlockToAllPlayers(ScheduledBlocks)); return; } } // Retract without pulling a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0, false); - a_World->ScheduleTask(PISTON_TICK_DELAY + 1, new cWorld::cTaskSendBlockToAllPlayers(a_BlockX, a_BlockY, a_BlockZ)); + + std::vector ScheduledBlocks; + ScheduledBlocks.push_back(Vector3i(a_BlockX, a_BlockY, a_BlockZ)); + a_World->ScheduleTask(PISTON_TICK_DELAY + 1, new cWorld::cTaskSendBlockToAllPlayers(ScheduledBlocks)); } -- cgit v1.2.3 From aa4477822ab0f1cdba904fd39e065bf8e86f9aec Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 29 May 2014 16:03:41 +0100 Subject: Suggestions --- src/Blocks/BlockPiston.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/Blocks') diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index d7c92925b..e6fa48e54 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -143,7 +143,12 @@ private: } } - return CanBreakPush(a_BlockType) ? false /* CanBreakPush returns true, but we need false to prevent pulling */ : CanPush(a_BlockType, a_BlockMeta); + if (CanBreakPush(a_BlockType)) + { + return false; // CanBreakPush returns true, but we need false to prevent pulling + } + + return CanPush(a_BlockType, a_BlockMeta); } /// Returns how many blocks the piston has to push (where the first free space is); < 0 when unpushable -- cgit v1.2.3 From b4ba2209342d536e83b3461db00e9f9fd811120e Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 29 May 2014 19:21:56 +0200 Subject: Add SetOpen() and IsOpen() to BlockDoor.h and fix door redstone bug. --- src/Blocks/BlockDoor.h | 89 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 9 deletions(-) (limited to 'src/Blocks') diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index 797fe484c..b5bfe4082 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -20,12 +20,12 @@ public: virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override; virtual const char * GetStepSound(void) override; - + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override; virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override; virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override; virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override; - + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, @@ -52,7 +52,7 @@ public: return true; } - + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { a_Pickups.push_back(cItem((m_BlockType == E_BLOCK_WOODEN_DOOR) ? E_ITEM_WOODEN_DOOR : E_ITEM_IRON_DOOR, 1, 0)); @@ -77,8 +77,8 @@ public: { return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR)); } - - + + bool CanReplaceBlock(BLOCKTYPE a_BlockType) { switch (a_BlockType) @@ -99,7 +99,7 @@ public: } - /// Converts the player's yaw to placed door's blockmeta + /** Converts the player's yaw to placed door's blockmeta */ inline static NIBBLETYPE PlayerYawToMetaData(double a_Yaw) { ASSERT((a_Yaw >= -180) && (a_Yaw < 180)); @@ -128,21 +128,92 @@ public: } - /// Returns true if the specified blocktype is any kind of door + /** Returns true if the specified blocktype is any kind of door */ inline static bool IsDoor(BLOCKTYPE a_Block) { return (a_Block == E_BLOCK_WOODEN_DOOR) || (a_Block == E_BLOCK_IRON_DOOR); } - /// Returns the metadata for the opposite door state (open vs closed) + /** Returns the metadata for the opposite door state (open vs closed) */ static NIBBLETYPE ChangeStateMetaData(NIBBLETYPE a_MetaData) { return a_MetaData ^ 4; } - /// Changes the door at the specified coords from open to close or vice versa + static bool IsOpen(cChunkInterface & a_ChunkInterface, int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) + { + BLOCKTYPE Block; + NIBBLETYPE Meta; + a_ChunkInterface.GetBlockTypeMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Block, Meta); + + if (!IsDoor(Block)) + { + return false; + } + + return ((Meta & 0x4) == 4); + } + + + static void SetOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Open) + { + BLOCKTYPE Block; + NIBBLETYPE Meta; + a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, Block, Meta); + + if (!IsDoor(Block) || ((Meta & 0x4) == a_Open)) + { + return; + } + + // Change the door + if (a_Open) + { + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x4); + } + else + { + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0xFFFFFFFB); + } + + int OtherPartY = a_BlockY; + if (Meta & 0x8) + { + // Current block is top of the door + a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY - 1, a_BlockZ, Block, Meta); + if (IsDoor(Block) && !(Meta & 0x8)) + { + OtherPartY--; + } + } + else + { + // Current block is bottom of the door + a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY + 1, a_BlockZ, Block, Meta); + if (IsDoor(Block) && (Meta & 0x8)) + { + OtherPartY++; + } + } + + // Change the other door part + if (a_BlockY != OtherPartY) + { + if (a_Open) + { + a_ChunkInterface.SetBlockMeta(a_BlockX, OtherPartY, a_BlockZ, Meta | 0x4); + } + else + { + a_ChunkInterface.SetBlockMeta(a_BlockX, OtherPartY, a_BlockZ, Meta & 0xFFFFFFFB); + } + } + } + + + /** Changes the door at the specified coords from open to close or vice versa */ static void ChangeDoor(cChunkInterface & a_ChunkInterface, int a_X, int a_Y, int a_Z) { NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_X, a_Y, a_Z); -- cgit v1.2.3 From d8e16f8c1fa771f77ef7505b45b9114b1f75aa61 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 30 May 2014 22:22:42 +0200 Subject: Better SetOpen() and IsOpen() function from the doors. --- src/Blocks/BlockDoor.cpp | 2 +- src/Blocks/BlockDoor.h | 102 ++++++++++++----------------------------------- 2 files changed, 27 insertions(+), 77 deletions(-) (limited to 'src/Blocks') diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index 479c68153..fb2d6f2dc 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -62,7 +62,7 @@ void cBlockDoorHandler::OnCancelRightClick(cChunkInterface & a_ChunkInterface, c a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - if (Meta & 8) + if (Meta & 0x8) { // Current block is top of the door a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY - 1, a_BlockZ, a_Player); diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index b5bfe4082..c1e4de9d4 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -135,113 +135,63 @@ public: } - /** Returns the metadata for the opposite door state (open vs closed) */ - static NIBBLETYPE ChangeStateMetaData(NIBBLETYPE a_MetaData) + static NIBBLETYPE IsOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { - return a_MetaData ^ 4; + NIBBLETYPE Meta = GetMetaFromRightDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); + return ((Meta & 0x4) != 0); } - static bool IsOpen(cChunkInterface & a_ChunkInterface, int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) + static NIBBLETYPE GetMetaFromRightDoor(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { - BLOCKTYPE Block; - NIBBLETYPE Meta; - a_ChunkInterface.GetBlockTypeMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Block, Meta); + NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - if (!IsDoor(Block)) + if ((Meta & 0x8) != 0) { - return false; + NIBBLETYPE DownMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ); + return (DownMeta & 0x7) | 0x8 | (((Meta & 0x1) != 0) ? 16 : 0); + } + else + { + NIBBLETYPE UpMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY + 1, a_BlockZ); + return (Meta & 0x7) | (((UpMeta & 0x1) != 0) ? 16 : 0); } - - return ((Meta & 0x4) == 4); } static void SetOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Open) { - BLOCKTYPE Block; - NIBBLETYPE Meta; - a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, Block, Meta); + BLOCKTYPE Block = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ); + NIBBLETYPE Meta = GetMetaFromRightDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); - if (!IsDoor(Block) || ((Meta & 0x4) == a_Open)) + if (!IsDoor(Block)) { return; } - // Change the door - if (a_Open) + bool Opened = (Meta & 0x4) != 0; + if (Opened == a_Open) { - a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x4); - } - else - { - a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0xFFFFFFFB); + return; } - int OtherPartY = a_BlockY; - if (Meta & 0x8) + // Change the door + NIBBLETYPE NewMeta = (Meta & 0x7) ^ 0x4; + if ((Meta & 0x8) == 0) { - // Current block is top of the door - a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY - 1, a_BlockZ, Block, Meta); - if (IsDoor(Block) && !(Meta & 0x8)) - { - OtherPartY--; - } + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, NewMeta); } else { - // Current block is bottom of the door - a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY + 1, a_BlockZ, Block, Meta); - if (IsDoor(Block) && (Meta & 0x8)) - { - OtherPartY++; - } - } - - // Change the other door part - if (a_BlockY != OtherPartY) - { - if (a_Open) - { - a_ChunkInterface.SetBlockMeta(a_BlockX, OtherPartY, a_BlockZ, Meta | 0x4); - } - else - { - a_ChunkInterface.SetBlockMeta(a_BlockX, OtherPartY, a_BlockZ, Meta & 0xFFFFFFFB); - } + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ, NewMeta); } } /** Changes the door at the specified coords from open to close or vice versa */ - static void ChangeDoor(cChunkInterface & a_ChunkInterface, int a_X, int a_Y, int a_Z) + static void ChangeDoor(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { - NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_X, a_Y, a_Z); - - a_ChunkInterface.SetBlockMeta(a_X, a_Y, a_Z, ChangeStateMetaData(OldMetaData)); - - if (OldMetaData & 8) - { - // Current block is top of the door - BLOCKTYPE BottomBlock = a_ChunkInterface.GetBlock(a_X, a_Y - 1, a_Z); - NIBBLETYPE BottomMeta = a_ChunkInterface.GetBlockMeta(a_X, a_Y - 1, a_Z); - - if (IsDoor(BottomBlock) && !(BottomMeta & 8)) - { - a_ChunkInterface.SetBlockMeta(a_X, a_Y - 1, a_Z, ChangeStateMetaData(BottomMeta)); - } - } - else - { - // Current block is bottom of the door - BLOCKTYPE TopBlock = a_ChunkInterface.GetBlock(a_X, a_Y + 1, a_Z); - NIBBLETYPE TopMeta = a_ChunkInterface.GetBlockMeta(a_X, a_Y + 1, a_Z); - - if (IsDoor(TopBlock) && (TopMeta & 8)) - { - a_ChunkInterface.SetBlockMeta(a_X, a_Y + 1, a_Z, ChangeStateMetaData(TopMeta)); - } - } + SetOpen(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, !IsOpen(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ)); } } ; -- cgit v1.2.3 From 0b7ed0f4934b75f959d13ce7b8a4c73cb88ce318 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 31 May 2014 11:47:03 +0200 Subject: Add doxy-comment --- src/Blocks/BlockDoor.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/Blocks') diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index c1e4de9d4..d8ce916fa 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -137,12 +137,13 @@ public: static NIBBLETYPE IsOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { - NIBBLETYPE Meta = GetMetaFromRightDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); + NIBBLETYPE Meta = GetTrueDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); return ((Meta & 0x4) != 0); } - static NIBBLETYPE GetMetaFromRightDoor(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) + /** Read the meta from the true part of the door and returns a meta with all infos include. */ + static NIBBLETYPE GetTrueDoorMeta(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); @@ -162,7 +163,7 @@ public: static void SetOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Open) { BLOCKTYPE Block = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ); - NIBBLETYPE Meta = GetMetaFromRightDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); + NIBBLETYPE Meta = GetTrueDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); if (!IsDoor(Block)) { -- cgit v1.2.3 From 683da71c0fa33c2542e28bed5d2f106ddfc68b64 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 31 May 2014 11:48:54 +0200 Subject: Moved the IsDoor check before the meta get. --- src/Blocks/BlockDoor.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/Blocks') diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index d8ce916fa..eaa039c50 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -163,13 +163,12 @@ public: static void SetOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Open) { BLOCKTYPE Block = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ); - NIBBLETYPE Meta = GetTrueDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); - if (!IsDoor(Block)) { return; } + NIBBLETYPE Meta = GetTrueDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); bool Opened = (Meta & 0x4) != 0; if (Opened == a_Open) { -- cgit v1.2.3 From a84f107400a326b0be27c290359220b8bf0e6635 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 1 Jun 2014 20:00:11 +0100 Subject: Suggestions two --- src/Blocks/BlockPiston.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/Blocks') diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index 1f8e0d9e0..faf639312 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -76,15 +76,15 @@ bool cBlockPistonHandler::GetPlacementBlockTypeMeta( -int cBlockPistonHandler::FirstPassthroughBlock(int pistonX, int pistonY, int pistonZ, NIBBLETYPE pistonmeta, cWorld * a_World) +int cBlockPistonHandler::FirstPassthroughBlock(int a_PistonX, int a_PistonY, int a_PistonZ, NIBBLETYPE pistonmeta, cWorld * a_World) { // Examine each of the 12 blocks ahead of the piston: for (int ret = 0; ret < PISTON_MAX_PUSH_DISTANCE; ret++) { BLOCKTYPE currBlock; NIBBLETYPE currMeta; - AddPistonDir(pistonX, pistonY, pistonZ, pistonmeta, 1); - a_World->GetBlockTypeMeta(pistonX, pistonY, pistonZ, currBlock, currMeta); + AddPistonDir(a_PistonX, a_PistonY, a_PistonZ, pistonmeta, 1); + a_World->GetBlockTypeMeta(a_PistonX, a_PistonY, a_PistonZ, currBlock, currMeta); if (CanBreakPush(currBlock)) { // This block breaks when pushed, extend up to here -- cgit v1.2.3 From 2b45e720adc801ece3dc562772747791efc3567e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 9 Jun 2014 21:35:46 +0200 Subject: Added Y coord checks and documentation to cBlockDoorHandler. --- src/Blocks/BlockDoor.h | 59 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 19 deletions(-) (limited to 'src/Blocks') diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index eaa039c50..bc59051c3 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -111,19 +111,19 @@ public: } if ((a_Yaw >= 0) && (a_Yaw < 90)) { - return 0x0; + return 0x00; } else if ((a_Yaw >= 180) && (a_Yaw < 270)) { - return 0x2; + return 0x02; } else if ((a_Yaw >= 90) && (a_Yaw < 180)) { - return 0x1; + return 0x01; } else { - return 0x3; + return 0x03; } } @@ -137,29 +137,45 @@ public: static NIBBLETYPE IsOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { - NIBBLETYPE Meta = GetTrueDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); - return ((Meta & 0x4) != 0); + NIBBLETYPE Meta = GetCompleteDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); + return ((Meta & 0x04) != 0); } - /** Read the meta from the true part of the door and returns a meta with all infos include. */ - static NIBBLETYPE GetTrueDoorMeta(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) + /** Returns the complete meta composed from the both parts of the door as (TopMeta << 4) | BottomMeta + The coords may point to either part of the door. + The returned value has bit 3 (0x08) set iff the coords point to the top part of the door. + Fails gracefully for (invalid) doors on the world's top and bottom. */ + static NIBBLETYPE GetCompleteDoorMeta(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - if ((Meta & 0x8) != 0) + if ((Meta & 0x08) != 0) { - NIBBLETYPE DownMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ); - return (DownMeta & 0x7) | 0x8 | (((Meta & 0x1) != 0) ? 16 : 0); + // The coords are pointing at the top part of the door + if (a_BlockX > 0) + { + NIBBLETYPE DownMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ); + return (DownMeta & 0x07) | 0x08 | (Meta << 4); + } + // This is the top part of the door at the bottommost layer of the world, there's no bottom: + return 0x08 | (Meta << 4); } else { - NIBBLETYPE UpMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY + 1, a_BlockZ); - return (Meta & 0x7) | (((UpMeta & 0x1) != 0) ? 16 : 0); + // The coords are pointing at the bottom part of the door + if (a_BlockY < cChunkDef::Height - 1) + { + NIBBLETYPE UpMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY + 1, a_BlockZ); + return Meta | (UpMeta << 4); + } + // This is the bottom part of the door at the topmost layer of the world, there's no top: + return Meta; } } + /** Sets the door to the specified state. If the door is already in that state, does nothing. */ static void SetOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Open) { BLOCKTYPE Block = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ); @@ -168,22 +184,27 @@ public: return; } - NIBBLETYPE Meta = GetTrueDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); - bool Opened = (Meta & 0x4) != 0; - if (Opened == a_Open) + NIBBLETYPE Meta = GetCompleteDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); + bool IsOpened = ((Meta & 0x04) != 0); + if (IsOpened == a_Open) { return; } // Change the door - NIBBLETYPE NewMeta = (Meta & 0x7) ^ 0x4; - if ((Meta & 0x8) == 0) + NIBBLETYPE NewMeta = (Meta & 0x07) ^ 0x04; // Flip the "IsOpen" bit (0x04) + if ((Meta & 0x08) == 0) { + // The block is the bottom part of the door a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, NewMeta); } else { - a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ, NewMeta); + // The block is the top part of the door, set the meta to the corresponding top part + if (a_BlockY > 0) + { + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ, NewMeta); + } } } -- cgit v1.2.3