diff options
author | Tycho <work.tycho+git@gmail.com> | 2014-03-17 17:44:34 +0100 |
---|---|---|
committer | Tycho <work.tycho+git@gmail.com> | 2014-03-17 17:44:34 +0100 |
commit | 90ab055eab62b35a8ddc681e6d79aa1d42afae9f (patch) | |
tree | b71798809ca05c1d904a18083a8c652a4954306a /src/Blocks | |
parent | Made buffers static const (diff) | |
parent | Fixed double to float conversions. (diff) | |
download | cuberite-90ab055eab62b35a8ddc681e6d79aa1d42afae9f.tar cuberite-90ab055eab62b35a8ddc681e6d79aa1d42afae9f.tar.gz cuberite-90ab055eab62b35a8ddc681e6d79aa1d42afae9f.tar.bz2 cuberite-90ab055eab62b35a8ddc681e6d79aa1d42afae9f.tar.lz cuberite-90ab055eab62b35a8ddc681e6d79aa1d42afae9f.tar.xz cuberite-90ab055eab62b35a8ddc681e6d79aa1d42afae9f.tar.zst cuberite-90ab055eab62b35a8ddc681e6d79aa1d42afae9f.zip |
Diffstat (limited to 'src/Blocks')
-rw-r--r-- | src/Blocks/BlockAnvil.h | 63 | ||||
-rw-r--r-- | src/Blocks/BlockBed.cpp | 73 | ||||
-rw-r--r-- | src/Blocks/BlockCake.h | 55 | ||||
-rw-r--r-- | src/Blocks/BlockHandler.cpp | 4 | ||||
-rw-r--r-- | src/Blocks/BlockLeaves.h | 1 | ||||
-rw-r--r-- | src/Blocks/BlockMushroom.h | 1 | ||||
-rw-r--r-- | src/Blocks/BlockVine.h | 2 | ||||
-rw-r--r-- | src/Blocks/BroadcastInterface.h | 5 | ||||
-rw-r--r-- | src/Blocks/WorldInterface.h | 8 |
9 files changed, 201 insertions, 11 deletions
diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h new file mode 100644 index 000000000..9f5f84be0 --- /dev/null +++ b/src/Blocks/BlockAnvil.h @@ -0,0 +1,63 @@ + +#pragma once + +#include "BlockHandler.h" +#include "../World.h" +#include "../Entities/Player.h" + + + + + +class cBlockAnvilHandler : + public cBlockHandler +{ +public: + cBlockAnvilHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem(E_BLOCK_ANVIL, 1, a_BlockMeta >> 2)); + } + + 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; + + int Direction = (int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 0.5) & 0x3; + int RawMeta = a_BlockMeta >> 2; + + Direction++; + Direction %= 4; + switch (Direction) + { + case 0: a_BlockMeta = 0x2 | RawMeta << 2; break; + case 1: a_BlockMeta = 0x3 | RawMeta << 2; break; + case 2: a_BlockMeta = 0x0 | RawMeta << 2; break; + case 3: a_BlockMeta = 0x1 | RawMeta << 2; break; + default: + { + return false; + } + } + + return true; + } + + virtual bool IsUseable() override + { + return true; + } +} ; + + + + diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp index 3dad4feba..6a3c6a55b 100644 --- a/src/Blocks/BlockBed.cpp +++ b/src/Blocks/BlockBed.cpp @@ -51,6 +51,49 @@ void cBlockBedHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInt +class cTimeFastForwardTester : + public cPlayerListCallback +{ + virtual bool Item(cPlayer * a_Player) override + { + if (!a_Player->IsInBed()) + { + return true; + } + + return false; + } +}; + + + + + +class cPlayerBedStateUnsetter : + public cPlayerListCallback +{ +public: + cPlayerBedStateUnsetter(Vector3i a_Position, cWorldInterface & a_WorldInterface) : + m_Position(a_Position), m_WorldInterface(a_WorldInterface) + { + } + + virtual bool Item(cPlayer * a_Player) override + { + a_Player->SetIsInBed(false); + m_WorldInterface.GetBroadcastManager().BroadcastEntityAnimation(*a_Player, 2); + return false; + } + +private: + Vector3i m_Position; + cWorldInterface & m_WorldInterface; +}; + + + + + void cBlockBedHandler::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) { if (a_WorldInterface.GetDimension() != dimOverworld) @@ -69,6 +112,8 @@ void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface } else { + Vector3i PillowDirection(0, 0, 0); + if (Meta & 0x8) { // Is pillow @@ -77,16 +122,30 @@ void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface else { // Is foot end - Vector3i Direction = MetaDataToDirection( Meta & 0x7 ); - if (a_ChunkInterface.GetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z) == E_BLOCK_BED) // Must always use pillow location for sleeping + VERIFY((Meta & 0x4) != 0x4); // Occupied flag should never be set, else our compilator (intended) is broken + + PillowDirection = MetaDataToDirection(Meta & 0x7); + if (a_ChunkInterface.GetBlock(a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z) == E_BLOCK_BED) // Must always use pillow location for sleeping { - a_WorldInterface.GetBroadcastManager().BroadcastUseBed(*a_Player, a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z); + a_WorldInterface.GetBroadcastManager().BroadcastUseBed(*a_Player, a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z); } } - a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, (Meta | (1 << 2))); - } - - } else { + + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x4); // Where 0x4 = occupied bit + a_Player->SetIsInBed(true); + + cTimeFastForwardTester Tester; + if (a_WorldInterface.ForEachPlayer(Tester)) + { + cPlayerBedStateUnsetter Unsetter(Vector3i(a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z), a_WorldInterface); + a_WorldInterface.ForEachPlayer(Unsetter); + a_WorldInterface.SetTimeOfDay(0); + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0xB); // Where 0xB = 1011, and zero is to make sure 'occupied' bit is always unset + } + } + } + else + { a_Player->SendMessageFailure("You can only sleep at night"); } } diff --git a/src/Blocks/BlockCake.h b/src/Blocks/BlockCake.h new file mode 100644 index 000000000..36e133388 --- /dev/null +++ b/src/Blocks/BlockCake.h @@ -0,0 +1,55 @@ +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockCakeHandler : + public cBlockHandler +{ +public: + cBlockCakeHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + 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 + { + NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + + if (!a_Player->Feed(2, 0.1)) + { + return; + } + + if (Meta >= 5) + { + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + } + else + { + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta + 1); + } + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Give nothing + } + + virtual bool IsUseable(void) override + { + return true; + } + + virtual const char * GetStepSound(void) override + { + return "step.cloth"; + } +} ; + + + + diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index aa97b2ca9..4f74e2f45 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -6,10 +6,12 @@ #include "../Root.h" #include "../Bindings/PluginManager.h" #include "../Chunk.h" +#include "BlockAnvil.h" #include "BlockBed.h" #include "BlockBrewingStand.h" #include "BlockButton.h" #include "BlockCactus.h" +#include "BlockCake.h" #include "BlockCarpet.h" #include "BlockCauldron.h" #include "BlockChest.h" @@ -85,12 +87,14 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) // Block handlers, alphabetically sorted: case E_BLOCK_ACACIA_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_ACTIVATOR_RAIL: return new cBlockRailHandler (a_BlockType); + case E_BLOCK_ANVIL: return new cBlockAnvilHandler (a_BlockType); case E_BLOCK_BED: return new cBlockBedHandler (a_BlockType); case E_BLOCK_BIRCH_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_BREWING_STAND: return new cBlockBrewingStandHandler (a_BlockType); case E_BLOCK_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_BROWN_MUSHROOM: return new cBlockMushroomHandler (a_BlockType); case E_BLOCK_CACTUS: return new cBlockCactusHandler (a_BlockType); + case E_BLOCK_CAKE: return new cBlockCakeHandler (a_BlockType); case E_BLOCK_CARROTS: return new cBlockCropsHandler (a_BlockType); case E_BLOCK_CARPET: return new cBlockCarpetHandler (a_BlockType); case E_BLOCK_CAULDRON: return new cBlockCauldronHandler (a_BlockType); diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h index 7b8f0b378..a6d3373c1 100644 --- a/src/Blocks/BlockLeaves.h +++ b/src/Blocks/BlockLeaves.h @@ -16,6 +16,7 @@ { \ case E_BLOCK_LEAVES: a_Area.SetBlockType(x, y, z, (BLOCKTYPE)(E_BLOCK_SPONGE + i + 1)); break; \ case E_BLOCK_LOG: return true; \ + case E_BLOCK_NEW_LOG: return true; \ } bool HasNearLog(cBlockArea &a_Area, int a_BlockX, int a_BlockY, int a_BlockZ); diff --git a/src/Blocks/BlockMushroom.h b/src/Blocks/BlockMushroom.h index 623cfda64..c30c1a401 100644 --- a/src/Blocks/BlockMushroom.h +++ b/src/Blocks/BlockMushroom.h @@ -39,6 +39,7 @@ public: case E_BLOCK_CACTUS: case E_BLOCK_ICE: case E_BLOCK_LEAVES: + case E_BLOCK_NEW_LEAVES: case E_BLOCK_AIR: { return false; diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 708583e70..8041d9359 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -73,7 +73,7 @@ public: /// Returns true if the specified block type is good for vines to attach to static bool IsBlockAttachable(BLOCKTYPE a_BlockType) { - return (a_BlockType == E_BLOCK_LEAVES) || cBlockInfo::IsSolid(a_BlockType); + return (a_BlockType == E_BLOCK_LEAVES) || (a_BlockType == E_BLOCK_NEW_LEAVES) || cBlockInfo::IsSolid(a_BlockType); } diff --git a/src/Blocks/BroadcastInterface.h b/src/Blocks/BroadcastInterface.h index f6ccd580b..01966ffbd 100644 --- a/src/Blocks/BroadcastInterface.h +++ b/src/Blocks/BroadcastInterface.h @@ -5,6 +5,7 @@ class cBroadcastInterface { public: - virtual void BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) = 0; - virtual void BroadcastSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL) = 0; + virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) = 0; + virtual void BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL) = 0; + virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) = 0; }; diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index e59b00eff..580339d32 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -27,7 +27,13 @@ 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; - + /** 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; + + /** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */ + virtual bool ForEachPlayer(cItemCallback<cPlayer> & a_Callback) = 0; + + virtual void SetTimeOfDay(Int64 a_TimeOfDay) = 0; + }; |