diff options
Diffstat (limited to '')
-rw-r--r-- | src/Blocks/BlockButton.h | 3 | ||||
-rw-r--r-- | src/Blocks/BlockDoor.cpp | 7 | ||||
-rw-r--r-- | src/Blocks/BlockFenceGate.h | 1 | ||||
-rw-r--r-- | src/Blocks/BlockFire.h | 4 | ||||
-rw-r--r-- | src/Blocks/BlockHandler.cpp | 96 | ||||
-rw-r--r-- | src/Blocks/BlockHayBale.h | 29 | ||||
-rw-r--r-- | src/Blocks/BlockLever.h | 16 | ||||
-rw-r--r-- | src/Blocks/BlockMobHead.h | 108 | ||||
-rw-r--r-- | src/Blocks/BlockSign.h | 6 | ||||
-rw-r--r-- | src/Blocks/BlockSlab.h | 16 | ||||
-rw-r--r-- | src/Blocks/BlockStone.h | 2 | ||||
-rw-r--r-- | src/Blocks/BlockTorch.h | 4 | ||||
-rw-r--r-- | src/Blocks/BlockTripwire.h | 32 | ||||
-rw-r--r-- | src/Blocks/BlockTripwireHook.h | 82 | ||||
-rw-r--r-- | src/Blocks/WorldInterface.h | 12 |
15 files changed, 362 insertions, 56 deletions
diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h index 4b2f6f618..ada7d58f7 100644 --- a/src/Blocks/BlockButton.h +++ b/src/Blocks/BlockButton.h @@ -23,6 +23,7 @@ public: NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) | 0x08); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); + a_WorldInterface.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ); a_WorldInterface.GetBroadcastManager().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) @@ -102,7 +103,7 @@ public: 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) && (cBlockInfo::IsSolid(BlockIsOn)); + return (a_RelY > 0) && (cBlockInfo::FullyOccupiesVoxel(BlockIsOn)); } } ; diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index fb2d6f2dc..934a01994 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -45,9 +45,16 @@ void cBlockDoorHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldIn void cBlockDoorHandler::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) { + UNUSED(a_WorldInterface); + UNUSED(a_BlockFace); + UNUSED(a_CursorX); + UNUSED(a_CursorY); + UNUSED(a_CursorZ); + if (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_WOODEN_DOOR) { ChangeDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); + a_Player->GetWorld()->BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0, a_Player->GetClientHandle()); } } diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h index e202c6610..e992870d4 100644 --- a/src/Blocks/BlockFenceGate.h +++ b/src/Blocks/BlockFenceGate.h @@ -45,6 +45,7 @@ public: // Standing aside - use last direction a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, OldMetaData); } + a_Player->GetWorld()->BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0, a_Player->GetClientHandle()); } diff --git a/src/Blocks/BlockFire.h b/src/Blocks/BlockFire.h index f9f32eb50..147e4b53e 100644 --- a/src/Blocks/BlockFire.h +++ b/src/Blocks/BlockFire.h @@ -36,8 +36,8 @@ public: - Loop through boundary variables, and fill with portal blocks based on Dir with meta from Dir */ - a_BlockY--; // Because we want the block below the fire - FindAndSetPortalFrame(a_BlockX, a_BlockY, a_BlockZ, a_ChunkInterface, a_WorldInterface); + // a_BlockY - 1: Because we want the block below the fire + FindAndSetPortalFrame(a_BlockX, a_BlockY - 1, a_BlockZ, a_ChunkInterface, a_WorldInterface); } virtual void OnDigging(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 6b08ec9ba..3ddb7531d 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -38,6 +38,7 @@ #include "BlockGlass.h" #include "BlockGlowstone.h" #include "BlockGravel.h" +#include "BlockHayBale.h" #include "BlockMobHead.h" #include "BlockHopper.h" #include "BlockIce.h" @@ -64,6 +65,8 @@ #include "BlockRedstoneRepeater.h" #include "BlockRedstoneTorch.h" #include "BlockTNT.h" +#include "BlockTripwire.h" +#include "BlockTripwireHook.h" #include "BlockSand.h" #include "BlockSapling.h" #include "BlockSideways.h" @@ -84,6 +87,91 @@ +/* +// Tests the meta rotation and mirroring. +// Note that the cMetaRotator needs to have its assert paths disabled for this test to work! +static class cBlockHandlerRotationTester +{ +public: + cBlockHandlerRotationTester(void) + { + printf("Performing block handlers test...\n"); + for (BLOCKTYPE Type = 0; Type < E_BLOCK_MAX_TYPE_ID; Type++) + { + cBlockHandler * Handler = cBlockInfo::GetHandler(Type); + if (Handler == NULL) + { + printf("NULL handler for block type %d!\n", Type); + continue; + } + AString BlockName = ItemTypeToString(Type); + for (NIBBLETYPE Meta = 0; Meta < 16; Meta++) + { + // Test the CW / CCW rotations: + NIBBLETYPE TestMeta; + TestMeta = Handler->MetaRotateCW(Handler->MetaRotateCW(Handler->MetaRotateCW(Handler->MetaRotateCW(Meta)))); + if (TestMeta != Meta) + { + // 4 CW rotations should produce no change in the meta + printf("Handler for blocktype %d (%s) fails CW 4-rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta); + } + TestMeta = Handler->MetaRotateCCW(Handler->MetaRotateCCW(Handler->MetaRotateCCW(Handler->MetaRotateCCW(Meta)))); + if (TestMeta != Meta) + { + // 4 CCW rotations should produce no change in the meta + printf("Handler for blocktype %d (%s) fails CCW 4-rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta); + } + TestMeta = Handler->MetaRotateCCW(Handler->MetaRotateCW(Meta)); + if (TestMeta != Meta) + { + // CCW rotation of a CW rotation should produce no change in the meta + printf("Handler for blocktype %d (%s) fails CCW(CW) rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta); + } + TestMeta = Handler->MetaRotateCW(Handler->MetaRotateCCW(Meta)); + if (TestMeta != Meta) + { + // CW rotation of a CCW rotation should produce no change in the meta + printf("Handler for blocktype %d (%s) fails CW(CCW) rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta); + } + + // Test the mirroring: + TestMeta = Handler->MetaMirrorXY(Handler->MetaMirrorXY(Meta)); + if (TestMeta != Meta) + { + // Double-mirroring should produce the same meta: + printf("Handler for blocktype %d (%s) fails XY mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta); + } + TestMeta = Handler->MetaMirrorXZ(Handler->MetaMirrorXZ(Meta)); + if (TestMeta != Meta) + { + // Double-mirroring should produce the same meta: + printf("Handler for blocktype %d (%s) fails XZ mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta); + } + TestMeta = Handler->MetaMirrorYZ(Handler->MetaMirrorYZ(Meta)); + if (TestMeta != Meta) + { + // Double-mirroring should produce the same meta: + printf("Handler for blocktype %d (%s) fails YZ mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta); + } + + // Test mirror-rotating: + TestMeta = Handler->MetaRotateCW(Handler->MetaRotateCW(Handler->MetaMirrorXY(Handler->MetaMirrorYZ(Meta)))); + if (TestMeta != Meta) + { + // 2 CW rotations should be the same as XY, YZ mirroring: + printf("Handler for blocktype %d (%s) fails rotation-mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta); + } + } + } // for Type + printf("Block handlers test complete.\n"); + } +} g_BlockHandlerRotationTester; +//*/ + + + + + cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) { switch(a_BlockType) @@ -134,7 +222,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_GLASS_PANE: return new cBlockGlassHandler (a_BlockType); case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType); case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType); - case E_BLOCK_HAY_BALE: return new cBlockSidewaysHandler (a_BlockType); + case E_BLOCK_HAY_BALE: return new cBlockHayBaleHandler (a_BlockType); case E_BLOCK_HEAD: return new cBlockMobHeadHandler (a_BlockType); case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType); case E_BLOCK_HOPPER: return new cBlockHopperHandler (a_BlockType); @@ -174,7 +262,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_QUARTZ_BLOCK: return new cBlockQuartzHandler (a_BlockType); case E_BLOCK_QUARTZ_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_RAIL: return new cBlockRailHandler (a_BlockType); - case E_BLOCK_REDSTONE_LAMP_ON: return new cBlockRedstoneLampHandler (a_BlockType); // We need this to change pickups to an off lamp; else 1.7+ clients crash + case E_BLOCK_REDSTONE_LAMP_ON: return new cBlockRedstoneLampHandler (a_BlockType); case E_BLOCK_REDSTONE_ORE: return new cBlockOreHandler (a_BlockType); case E_BLOCK_REDSTONE_ORE_GLOWING: return new cBlockOreHandler (a_BlockType); case E_BLOCK_REDSTONE_REPEATER_OFF: return new cBlockRedstoneRepeaterHandler(a_BlockType); @@ -205,8 +293,10 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_TORCH: return new cBlockTorchHandler (a_BlockType); case E_BLOCK_TRAPDOOR: return new cBlockTrapdoorHandler (a_BlockType); case E_BLOCK_TNT: return new cBlockTNTHandler (a_BlockType); + case E_BLOCK_TRIPWIRE: return new cBlockTripwireHandler (a_BlockType); + case E_BLOCK_TRIPWIRE_HOOK: return new cBlockTripwireHookHandler (a_BlockType); case E_BLOCK_VINES: return new cBlockVineHandler (a_BlockType); - case E_BLOCK_WALLSIGN: return new cBlockSignHandler (a_BlockType); + case E_BLOCK_WALLSIGN: return new cBlockSignHandler (a_BlockType); // TODO: This needs a special handler case E_BLOCK_WATER: return new cBlockFluidHandler (a_BlockType); case E_BLOCK_WOODEN_BUTTON: return new cBlockButtonHandler (a_BlockType); case E_BLOCK_WOODEN_DOOR: return new cBlockDoorHandler (a_BlockType); diff --git a/src/Blocks/BlockHayBale.h b/src/Blocks/BlockHayBale.h new file mode 100644 index 000000000..5b646e264 --- /dev/null +++ b/src/Blocks/BlockHayBale.h @@ -0,0 +1,29 @@ + +#pragma once + +#include "BlockHandler.h" +#include "BlockSideways.h" + + + + + +class cBlockHayBaleHandler : + public cBlockSidewaysHandler +{ +public: + cBlockHayBaleHandler(BLOCKTYPE a_BlockType) + : cBlockSidewaysHandler(a_BlockType) + { + } + + + virtual const char * GetStepSound(void) override + { + return "step.grass"; + } +} ; + + + + diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h index ad2ae29e5..4e745d413 100644 --- a/src/Blocks/BlockLever.h +++ b/src/Blocks/BlockLever.h @@ -7,12 +7,13 @@ class cBlockLeverHandler : - public cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false> + public cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, false> { - typedef cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false> super; + typedef cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, false> super; + public: - cBlockLeverHandler(BLOCKTYPE a_BlockType) - : cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false>(a_BlockType) + cBlockLeverHandler(BLOCKTYPE a_BlockType) : + super(a_BlockType) { } @@ -21,7 +22,8 @@ public: // Flip the ON bit on/off using the XOR bitwise operation NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08); - a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LEVER, Meta); // SetMeta doesn't work for unpowering levers, so setblock + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); + a_WorldInterface.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ); a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f); } @@ -103,7 +105,7 @@ public: 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) && cBlockInfo::IsSolid(BlockIsOn); + return (a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn); } @@ -132,7 +134,7 @@ public: case 0x05: return 0x06; // Ground rotation case 0x06: return 0x05; - default: return super::MetaRotateCCW(a_Meta); // Wall Rotation + default: return super::MetaRotateCW(a_Meta); // Wall Rotation } } } ; diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 9855574ad..301386568 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -19,24 +19,69 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - a_Pickups.push_back(cItem(E_ITEM_HEAD, 1, 0)); + // The drop spawn is in OnDestroyed method } + + virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + if (a_Player->IsGameModeCreative()) + { + // No drops in creative mode + return; + } + + class cCallback : public cBlockEntityCallback + { + virtual bool Item(cBlockEntity * a_BlockEntity) + { + if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD) + { + return false; + } + cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity); + + cItems Pickups; + Pickups.Add(E_ITEM_HEAD, 1, (short) MobHeadEntity->GetType()); + MTRand r1; + + // Mid-block position first + double MicroX, MicroY, MicroZ; + MicroX = MobHeadEntity->GetPosX() + 0.5; + MicroY = MobHeadEntity->GetPosY() + 0.5; + MicroZ = MobHeadEntity->GetPosZ() + 0.5; + + // Add random offset second + MicroX += r1.rand(1) - 0.5; + MicroZ += r1.rand(1) - 0.5; - bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) + MobHeadEntity->GetWorld()->SpawnItemPickups(Pickups, MicroX, MicroY, MicroZ); + return false; + } + } Callback; + + a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback); + } + + bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { if (a_BlockY < 2) { return false; } - class cCallback : public cMobHeadCallback + class cCallback : public cBlockEntityCallback { bool m_IsWither; - virtual bool Item (cMobHeadEntity * a_MobHeadEntity) + virtual bool Item(cBlockEntity * a_BlockEntity) { - m_IsWither = (a_MobHeadEntity->GetType() == SKULL_TYPE_WITHER); + if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD) + { + return false; + } + cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity); + m_IsWither = (MobHeadEntity->GetType() == SKULL_TYPE_WITHER); return false; } @@ -70,7 +115,7 @@ public: } PlayerCallback(Vector3f((float)a_BlockX, (float)a_BlockY, (float)a_BlockZ)); - a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA); + a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA); if (!CallbackA.IsWither()) { @@ -87,8 +132,8 @@ public: return false; } - a_World->DoWithMobHeadAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA); - a_World->DoWithMobHeadAt(a_BlockX + 1, a_BlockY, a_BlockZ, CallbackB); + a_WorldInterface.DoWithBlockEntityAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA); + a_WorldInterface.DoWithBlockEntityAt(a_BlockX + 1, a_BlockY, a_BlockZ, CallbackB); BLOCKTYPE Block1 = a_ChunkInterface.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ); BLOCKTYPE Block2 = a_ChunkInterface.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ); @@ -101,15 +146,15 @@ public: a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0); // Block entities - a_World->SetBlock(a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); - a_World->SetBlock(a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); // Spawn the wither: - a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); + a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); // Award Achievement - a_World->ForEachPlayer(PlayerCallback); + a_WorldInterface.ForEachPlayer(PlayerCallback); return true; } @@ -117,8 +162,8 @@ public: CallbackA.Reset(); CallbackB.Reset(); - a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ - 1, CallbackA); - a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ + 1, CallbackB); + a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ - 1, CallbackA); + a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ + 1, CallbackB); Block1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1); Block2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1); @@ -131,15 +176,15 @@ public: a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0); // Block entities - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0); - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0); + a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0); + a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0); // Spawn the wither: - a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); + a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); // Award Achievement - a_World->ForEachPlayer(PlayerCallback); + a_WorldInterface.ForEachPlayer(PlayerCallback); return true; } @@ -154,23 +199,29 @@ public: BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) override { - class cCallback : public cMobHeadCallback + class cCallback : public cBlockEntityCallback { cPlayer * m_Player; NIBBLETYPE m_OldBlockMeta; NIBBLETYPE m_NewBlockMeta; - virtual bool Item (cMobHeadEntity * a_MobHeadEntity) + virtual bool Item(cBlockEntity * a_BlockEntity) { + if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD) + { + return false; + } + cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity); + int Rotation = 0; if (m_NewBlockMeta == 1) { Rotation = (int) floor(m_Player->GetYaw() * 16.0F / 360.0F + 0.5) & 0xF; } - - a_MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta)); - a_MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation)); - a_MobHeadEntity->GetWorld()->BroadcastBlockEntity(a_MobHeadEntity->GetPosX(), a_MobHeadEntity->GetPosY(), a_MobHeadEntity->GetPosZ(), m_Player->GetClientHandle()); + + MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta)); + MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation)); + MobHeadEntity->GetWorld()->BroadcastBlockEntity(MobHeadEntity->GetPosX(), MobHeadEntity->GetPosY(), MobHeadEntity->GetPosZ()); return false; } @@ -184,8 +235,7 @@ public: cCallback Callback(a_Player, a_BlockMeta, static_cast<NIBBLETYPE>(a_BlockFace)); a_BlockMeta = (NIBBLETYPE)a_BlockFace; - cWorld * World = (cWorld *) &a_WorldInterface; - World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback); + a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta); if (a_BlockMeta == SKULL_TYPE_WITHER) @@ -200,7 +250,7 @@ public: }; for (size_t i = 0; i < ARRAYCOUNT(Coords); ++i) { - if (TrySpawnWither(a_ChunkInterface, World, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z)) + if (TrySpawnWither(a_ChunkInterface, a_WorldInterface, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z)) { break; } diff --git a/src/Blocks/BlockSign.h b/src/Blocks/BlockSign.h index 9d6fede21..f5630bdb0 100644 --- a/src/Blocks/BlockSign.h +++ b/src/Blocks/BlockSign.h @@ -75,13 +75,13 @@ public: virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override { - return (++a_Meta) & 0x0F; + return (a_Meta + 4) & 0x0f; } virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override { - return (--a_Meta) & 0x0F; + return (a_Meta + 12) & 0x0f; } virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override @@ -90,7 +90,7 @@ public: // There are 16 meta values which correspond to different directions. // These values are equated to angles on a circle; 0x08 = 180 degrees. - return (a_Meta < 0x08) ? 0x08 + a_Meta : 0x08 - a_Meta; + return (a_Meta < 0x08) ? (0x08 + a_Meta) : (0x08 - a_Meta); } diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index 80841b094..6c861be86 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -80,6 +80,7 @@ public: if (IsAnySlabType(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ))) { a_BlockType = GetDoubleSlabType(m_BlockType); + a_BlockMeta = a_BlockMeta & 0x7; } return true; @@ -123,6 +124,12 @@ public: return E_BLOCK_AIR; } + + virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override + { + // Toggle the 4th bit - up / down: + return (a_Meta ^ 0x08); + } } ; @@ -166,15 +173,6 @@ public: ASSERT(!"Unhandled double slab type!"); return ""; } - - - virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override - { - NIBBLETYPE OtherMeta = a_Meta & 0x07; // Contains unrelated meta data. - - // 8th bit is up/down. 1 right-side-up, 0 is up-side-down. - return (a_Meta & 0x08) ? 0x00 + OtherMeta : 0x01 + OtherMeta; - } } ; diff --git a/src/Blocks/BlockStone.h b/src/Blocks/BlockStone.h index af4c6509a..cd5230f49 100644 --- a/src/Blocks/BlockStone.h +++ b/src/Blocks/BlockStone.h @@ -2,8 +2,6 @@ #pragma once #include "BlockHandler.h" -#include "../MersenneTwister.h" -#include "../World.h" diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index 8ddec8de1..44c33c429 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -154,7 +154,11 @@ public: if ( (BlockInQuestion == E_BLOCK_GLASS) || + (BlockInQuestion == E_BLOCK_STAINED_GLASS) || (BlockInQuestion == E_BLOCK_FENCE) || + (BlockInQuestion == E_BLOCK_SOULSAND) || + (BlockInQuestion == E_BLOCK_MOB_SPAWNER) || + (BlockInQuestion == E_BLOCK_END_PORTAL_FRAME) || // Actual vanilla behaviour (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) ) diff --git a/src/Blocks/BlockTripwire.h b/src/Blocks/BlockTripwire.h new file mode 100644 index 000000000..3ab17bf4a --- /dev/null +++ b/src/Blocks/BlockTripwire.h @@ -0,0 +1,32 @@ + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockTripwireHandler : + public cBlockHandler +{ +public: + cBlockTripwireHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem(E_ITEM_STRING, 1, 0)); + } + + virtual const char * GetStepSound(void) override + { + return ""; + } +}; + + + + diff --git a/src/Blocks/BlockTripwireHook.h b/src/Blocks/BlockTripwireHook.h new file mode 100644 index 000000000..f849fb8ad --- /dev/null +++ b/src/Blocks/BlockTripwireHook.h @@ -0,0 +1,82 @@ +#pragma once + +#include "BlockHandler.h" +#include "MetaRotator.h" + + + + + +class cBlockTripwireHookHandler : + public cMetaRotator<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01> +{ +public: + cBlockTripwireHookHandler(BLOCKTYPE a_BlockType) + : cMetaRotator<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01>(a_BlockType) + { + } + + virtual bool GetPlacementBlockTypeMeta( + cChunkInterface & a_ChunkInterface, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + a_BlockType = m_BlockType; + + a_BlockMeta = DirectionToMetadata(a_BlockFace); + + return true; + } + + inline static NIBBLETYPE DirectionToMetadata(eBlockFace a_Direction) + { + switch (a_Direction) + { + case BLOCK_FACE_XM: return 0x1; + case BLOCK_FACE_XP: return 0x3; + case BLOCK_FACE_ZM: return 0x2; + case BLOCK_FACE_ZP: return 0x0; + default: ASSERT(!"Unhandled tripwire hook direction!"); return 0x0; + } + } + + inline static eBlockFace MetadataToDirection(NIBBLETYPE a_Meta) + { + switch (a_Meta & 0x03) + { + case 0x1: return BLOCK_FACE_XM; + case 0x3: return BLOCK_FACE_XP; + case 0x2: return BLOCK_FACE_ZM; + case 0x0: return BLOCK_FACE_ZP; + default: ASSERT(!"Unhandled tripwire hook metadata!"); return BLOCK_FACE_NONE; + } + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Reset meta to 0 + a_Pickups.push_back(cItem(E_BLOCK_TRIPWIRE_HOOK, 1, 0)); + } + + virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, 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, MetadataToDirection(Meta), true); + BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); + + return (a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn); + } + + virtual const char * GetStepSound(void) override + { + return "step.wood"; + } +}; + + + + diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index bfbb053d9..251b28d03 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -6,6 +6,12 @@ class cItems; +typedef cItemCallback<cBlockEntity> cBlockEntityCallback; + + + + + class cWorldInterface { public: @@ -29,6 +35,9 @@ public: /** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */ virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0; + /** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */ + virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) = 0; + /** Sends the block on those coords to the player */ virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer * a_Player) = 0; @@ -37,4 +46,7 @@ public: virtual void SetTimeOfDay(Int64 a_TimeOfDay) = 0; + /** Wakes up the simulators for the specified block */ + virtual void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) = 0; + }; |