Cuberite
A lightweight, fast and extensible game server for Minecraft
DoorHandler.h
Go to the documentation of this file.
1 
2 #pragma once
3 
4 #include "../../Blocks/BlockDoor.h"
5 
6 
7 
8 
9 
10 namespace DoorHandler
11 {
12  // "Doormammu, I've come to bargain"
13 
14  static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
15  {
16  UNUSED(a_Chunk);
17  UNUSED(a_Position);
18  UNUSED(a_BlockType);
19  UNUSED(a_QueryPosition);
20  UNUSED(a_QueryBlockType);
21  UNUSED(IsLinked);
22  return 0;
23  }
24 
25  static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
26  {
27  UNUSED(a_Chunk);
28  UNUSED(a_BlockType);
29  UNUSED(a_Meta);
30  InvokeForAdjustedRelatives(Callback, a_Position, RelativeAdjacents);
31  }
32 
33  static void Update(cChunk & a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PowerLevel Power)
34  {
35  // LOGD("Evaluating dori the door (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
36 
37  NIBBLETYPE TopMeta;
38  const bool IsTop = (a_Meta & 0x8) == 0x8;
39  const auto TopPosition = IsTop ? a_Position : a_Position.addedY(1);
40 
41  // Figure out the metadata of the top half, which stores the previous redstone power state:
42  if (IsTop)
43  {
44  TopMeta = a_Meta;
45  }
46  else
47  {
48  if (TopPosition.y == cChunkDef::Height)
49  {
50  return;
51  }
52 
53  BLOCKTYPE AboveType;
54  a_Chunk.GetBlockTypeMeta(TopPosition, AboveType, TopMeta);
55  if (!cBlockDoorHandler::IsDoorBlockType(AboveType))
56  {
57  return;
58  }
59  }
60 
61  const auto OppositeHalfPosition = a_Position + (IsTop ? OffsetYM : OffsetYP);
62  ForEachSourceCallback Callback(a_Chunk, OppositeHalfPosition, a_BlockType);
63  ForValidSourcePositions(a_Chunk, OppositeHalfPosition, a_BlockType, a_Meta, Callback);
64 
65  // Factor in what the other half is getting:
66  Power = std::max(Power, Callback.Power);
67 
68  const bool ShouldBeOpen = Power != 0;
69  const bool PreviouslyPowered = (TopMeta & 0x2) == 0x2;
70 
71  // Allow players to override redstone control
72  // don't update if redstone power hasn't changed since we last saw it:
73  if (ShouldBeOpen == PreviouslyPowered)
74  {
75  return;
76  }
77 
78  // Update the previous redstone power:
79  if (ShouldBeOpen)
80  {
81  a_Chunk.SetMeta(TopPosition, TopMeta | 0x2);
82  }
83  else
84  {
85  a_Chunk.SetMeta(TopPosition, TopMeta & ~0x2);
86  }
87 
88  cChunkInterface ChunkInterface(a_Chunk.GetWorld()->GetChunkMap());
89  const auto AbsolutePosition = cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos());
90 
91  // Toggle the door, if it needs to be changed:
92  if (ShouldBeOpen != cBlockDoorHandler::IsOpen(ChunkInterface, AbsolutePosition))
93  {
94  cBlockDoorHandler::SetOpen(ChunkInterface, AbsolutePosition, ShouldBeOpen);
96  }
97  }
98 };
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:44
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:41
@ SFX_RANDOM_WOODEN_DOOR_OPEN
#define UNUSED
Definition: Globals.h:72
constexpr Vector3i OffsetYP
constexpr std::array< Vector3i, 6 > RelativeAdjacents
constexpr Vector3i OffsetYM
void InvokeForAdjustedRelatives(ForEachSourceCallback &Callback, const Vector3i Position, const ArrayType &Relative)
unsigned char PowerLevel
unsigned char Power(const BlockState Block)
static PowerLevel GetPowerDeliveredToPosition(const cChunk &a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
Definition: DoorHandler.h:14
static void ForValidSourcePositions(const cChunk &a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback &Callback)
Definition: DoorHandler.h:25
static void Update(cChunk &a_Chunk, cChunk &, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PowerLevel Power)
Definition: DoorHandler.h:33
static void SetOpen(cChunkInterface &a_ChunkInterface, const Vector3i a_BlockPos, bool a_Open)
Sets the door to the specified state.
Definition: BlockDoor.h:91
static bool IsOpen(cChunkInterface &a_ChunkInterface, const Vector3i a_BlockPos)
Returns true iff the door at the specified coords is open.
Definition: BlockDoor.h:84
static bool IsDoorBlockType(BLOCKTYPE a_Block)
Returns true if the specified blocktype is any kind of door.
Definition: BlockDoor.h:61
Definition: Chunk.h:36
cChunkCoords GetPos() const
Definition: Chunk.h:133
void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta)
Definition: Chunk.h:286
cWorld * GetWorld(void) const
Definition: Chunk.h:135
void GetBlockTypeMeta(Vector3i a_RelPos, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
Definition: Chunk.cpp:1757
static Vector3i RelativeToAbsolute(Vector3i a_RelBlockPosition, cChunkCoords a_ChunkCoords)
Converts relative block coordinates into absolute coordinates with a known chunk location.
Definition: ChunkDef.h:174
static const int Height
Definition: ChunkDef.h:125
Vector3< T > addedY(T a_AddY) const
Returns a copy of this vector moved by the specified amount on the y axis.
Definition: Vector3.h:314
virtual void BroadcastSoundParticleEffect(const EffectID a_EffectID, Vector3i a_SrcPos, int a_Data, const cClientHandle *a_Exclude=nullptr) override
cChunkMap * GetChunkMap(void)
Definition: World.h:852