Cuberite
A lightweight, fast and extensible game server for Minecraft
TripwireHookHandler.h
Go to the documentation of this file.
1 
2 #pragma once
3 
4 #include "../../Blocks/BlockTripwireHook.h"
5 
6 
7 
8 
9 
11 {
12  static unsigned char GetPowerLevel(const cChunk & a_Chunk, Vector3i a_Position, NIBBLETYPE a_Meta)
13  {
14  bool FoundActivated = false;
15  const auto FaceToGoTowards = cBlockTripwireHookHandler::MetadataToDirection(a_Meta);
16 
17  for (int i = 0; i < 40; ++i) // Tripwires can be connected up to 40 blocks
18  {
20  NIBBLETYPE Meta;
21 
22  a_Position = AddFaceDirection(a_Position, FaceToGoTowards);
23  if (!a_Chunk.UnboundedRelGetBlock(a_Position, Type, Meta))
24  {
25  return 0;
26  }
27 
28  if (Type == E_BLOCK_TRIPWIRE)
29  {
30  if (FoundActivated)
31  {
32  continue;
33  }
34 
35  if (
36  !a_Chunk.ForEachEntityInBox(
37  cBoundingBox(Vector3d(0.5, 0, 0.5) + cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos()), 0.5, 0.5),
38  [](cEntity &) { return true; }
39  )
40  )
41  {
42  FoundActivated = true;
43  }
44 
45  continue;
46  }
47  else if (Type == E_BLOCK_TRIPWIRE_HOOK)
48  {
50  {
51  // Other hook facing in opposite direction - circuit completed!
52  return FoundActivated ? 15 : 1;
53  }
54  }
55 
56  // Tripwire hook not connected at all
57  return 0;
58  }
59 
60  return 0;
61  }
62 
63  static PowerLevel GetPowerDeliveredToPosition(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
64  {
65  UNUSED(a_BlockType);
66  UNUSED(a_QueryBlockType);
67  UNUSED(a_QueryPosition);
68 
69  return (GetPowerLevel(a_Chunk, a_Position, a_Chunk.GetMeta(a_Position)) == 15) ? 15 : 0;
70  }
71 
72  static void Update(cChunk & a_Chunk, cChunk & CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
73  {
74  // LOGD("Evaluating hooky the tripwire hook (%d %d %d)", a_Position.x, a_Position.y, a_Position.z);
75 
76  const auto PowerLevel = GetPowerLevel(a_Chunk, a_Position, a_Meta);
77  NIBBLETYPE Meta;
78  if (PowerLevel == 0)
79  {
80  Meta = (a_Meta & 0x3);
81  }
82  else if (PowerLevel == 1)
83  {
84  // Connected but not activated, AND away the highest bit
85  Meta = (a_Meta & 0x7) | 0x4;
86  }
87  else if (PowerLevel == 15)
88  {
89  // Connected and activated, set the 3rd and 4th highest bits
90  Meta = (a_Meta | 0xC);
91  }
92  else
93  {
94  UNREACHABLE("Unexpected tripwire hook power level!");
95  }
96 
97  if (Meta != a_Meta)
98  {
99  a_Chunk.SetMeta(a_Position, Meta);
100  UpdateAdjustedRelatives(a_Chunk, CurrentlyTicking, a_Position, RelativeAdjacents);
101  }
102  }
103 
104  static void ForValidSourcePositions(const cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback & Callback)
105  {
106  UNUSED(a_Chunk);
107  UNUSED(a_BlockType);
108  UNUSED(a_Meta);
109  UNUSED(a_Position);
110  UNUSED(Callback);
111  }
112 };
@ E_BLOCK_TRIPWIRE
Definition: BlockType.h:147
@ E_BLOCK_TRIPWIRE_HOOK
Definition: BlockType.h:146
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
eBlockFace ReverseBlockFace(eBlockFace a_BlockFace)
Returns a blockface opposite to the one specified.
Definition: Defines.cpp:121
void AddFaceDirection(int &a_BlockX, int &a_BlockY, int &a_BlockZ, eBlockFace a_BlockFace, bool a_bInverse)
Modifies the specified coords so that they point to the block adjacent to the one specified through i...
Definition: Defines.cpp:378
#define UNREACHABLE(x)
Definition: Globals.h:288
#define UNUSED
Definition: Globals.h:72
constexpr std::array< Vector3i, 6 > RelativeAdjacents
void UpdateAdjustedRelatives(const cChunk &a_Chunk, const cChunk &a_TickingChunk, const Vector3i a_Position, const ArrayType &a_Relative)
unsigned char PowerLevel
Vector3< double > Vector3d
Definition: Vector3.h:485
unsigned char Power(const BlockState Block)
static void Update(cChunk &a_Chunk, cChunk &CurrentlyTicking, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, const PowerLevel Power)
static unsigned char GetPowerLevel(const cChunk &a_Chunk, Vector3i a_Position, NIBBLETYPE a_Meta)
static void ForValidSourcePositions(const cChunk &a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, ForEachSourceCallback &Callback)
static PowerLevel GetPowerDeliveredToPosition(const cChunk &a_Chunk, Vector3i a_Position, BLOCKTYPE a_BlockType, Vector3i a_QueryPosition, BLOCKTYPE a_QueryBlockType, bool IsLinked)
static eBlockFace MetadataToDirection(NIBBLETYPE a_Meta)
Represents two sets of coords, minimum and maximum for each direction.
Definition: BoundingBox.h:24
Definition: Chunk.h:36
NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const
Definition: Chunk.h:279
cChunkCoords GetPos() const
Definition: Chunk.h:133
bool ForEachEntityInBox(const cBoundingBox &a_Box, cEntityCallback a_Callback) const
Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
Definition: Chunk.cpp:1674
bool UnboundedRelGetBlock(Vector3i a_RelCoords, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
Same as GetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in ...
Definition: Chunk.cpp:1008
void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta)
Definition: Chunk.h:286
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
Definition: Entity.h:76