Cuberite
A lightweight, fast and extensible game server for Minecraft
BlockOre.h
Go to the documentation of this file.
1 
2 #pragma once
3 
4 #include "Blocks/BlockHandler.h"
5 #include "Items/ItemHandler.h"
6 
7 
8 
9 
10 
12  public cBlockHandler
13 {
15 
16 public:
17 
18  using Super::Super;
19 
20 protected:
21 
22  ~cBlockOreHandler() = default;
23 
24 private:
25 
26  virtual cItems ConvertToPickups(const NIBBLETYPE a_BlockMeta, const cItem * const a_Tool) const override
27  {
28  // If using silk-touch, drop self rather than the resource:
29  if (ToolHasSilkTouch(a_Tool))
30  {
31  switch (m_BlockType)
32  {
33  // If it was a glowing redstone ore, drop a normal redstone ore:
35  default: return cItem(m_BlockType);
36  }
37  }
38 
39  const auto FortuneLevel = ToolFortuneLevel(a_Tool);
40 
42  { // Redstone follows the discrete random distribution, unlike other ores
43  const auto DropNum = FortuneDiscreteRandom(4, 5, FortuneLevel);
44  return cItem(E_ITEM_REDSTONE_DUST, DropNum);
45  }
46 
47  auto & Random = GetRandomProvider();
48  const auto DropMult = std::max(static_cast<char>(1), FloorC<char>(Random.RandReal(FortuneLevel + 2.0)));
49  switch (m_BlockType)
50  {
51  case E_BLOCK_LAPIS_ORE: return cItem(E_ITEM_DYE, DropMult * Random.RandInt<char>(4, 9), 4);
52  case E_BLOCK_DIAMOND_ORE: return cItem(E_ITEM_DIAMOND, DropMult);
53  case E_BLOCK_EMERALD_ORE: return cItem(E_ITEM_EMERALD, DropMult);
54  case E_BLOCK_COAL_ORE: return cItem(E_ITEM_COAL, DropMult);
56  case E_BLOCK_CLAY: return cItem(E_ITEM_CLAY, 4);
57  default:
58  {
59  return cItem(m_BlockType);
60  }
61  }
62  }
63 
64 
65 
66 
67 
68  virtual void OnBroken(
69  cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface,
70  Vector3i a_BlockPos,
71  BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta,
72  const cEntity * a_Digger
73  ) const override
74  {
75  if (a_Digger == nullptr)
76  {
77  return;
78  }
79  if (!a_Digger->IsPlayer())
80  {
81  return;
82  }
83 
84  const auto Player = static_cast<const cPlayer *>(a_Digger);
85  if (!Player->IsGameModeSurvival())
86  {
87  // Don't drop XP unless the player is in survival mode.
88  return;
89  }
90 
91  if (Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchSilkTouch) != 0)
92  {
93  // Don't drop XP when the ore is mined with the Silk Touch enchantment
94  return;
95  }
96 
97  if (!Player->GetEquippedItem().GetHandler().CanHarvestBlock(m_BlockType))
98  {
99  return;
100  }
101 
102  auto & Random = GetRandomProvider();
103  int Reward = 0;
104 
105  switch (a_OldBlockType)
106  {
108  case E_BLOCK_LAPIS_ORE:
109  {
110  // Lapis and nether quartz get 2 - 5 experience
111  Reward = Random.RandInt(2, 5);
112  break;
113  }
116  {
117  // Redstone gets 1 - 5 experience
118  Reward = Random.RandInt(1, 5);
119  break;
120  }
121  case E_BLOCK_DIAMOND_ORE:
122  case E_BLOCK_EMERALD_ORE:
123  {
124  // Diamond and emerald get 3 - 7 experience
125  Reward = Random.RandInt(3, 7);
126  break;
127  }
128  case E_BLOCK_COAL_ORE:
129  {
130  // Coal gets 0 - 2 experience
131  Reward = Random.RandInt(2);
132  break;
133  }
134 
135  default: break;
136  }
137 
138  if (Reward > 0)
139  {
140  a_WorldInterface.SpawnSplitExperienceOrbs(Vector3d(0.5, 0.5, 0.5) + a_BlockPos, Reward);
141  }
142  }
143 } ;
144 
145 
146 
147 
148 
149 class cDefaultOreHandler final :
150  public cBlockOreHandler
151 {
152 public:
153 
154  using cBlockOreHandler::cBlockOreHandler;
155 };
@ E_BLOCK_CLAY
Definition: BlockType.h:96
@ E_BLOCK_REDSTONE_ORE
Definition: BlockType.h:87
@ E_BLOCK_COAL_ORE
Definition: BlockType.h:26
@ E_BLOCK_DIAMOND_ORE
Definition: BlockType.h:66
@ E_BLOCK_REDSTONE_ORE_GLOWING
Definition: BlockType.h:88
@ E_BLOCK_LAPIS_ORE
Definition: BlockType.h:31
@ E_BLOCK_EMERALD_ORE
Definition: BlockType.h:144
@ E_BLOCK_NETHER_QUARTZ_ORE
Definition: BlockType.h:170
@ E_ITEM_EMERALD
Definition: BlockType.h:434
@ E_ITEM_COAL
Definition: BlockType.h:307
@ E_ITEM_DYE
Definition: BlockType.h:396
@ E_ITEM_REDSTONE_DUST
Definition: BlockType.h:375
@ E_ITEM_DIAMOND
Definition: BlockType.h:308
@ E_ITEM_CLAY
Definition: BlockType.h:381
@ E_ITEM_NETHER_QUARTZ
Definition: BlockType.h:452
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
MTRand & GetRandomProvider()
Returns the current thread's random number source.
Definition: FastRandom.cpp:12
Vector3< double > Vector3d
Definition: Vector3.h:485
static unsigned char ToolFortuneLevel(const cItem *a_Tool)
Returns the fortune level of a tool, if it is a valid tool.
static char FortuneDiscreteRandom(char a_MinDrop, char a_DefaultMax, unsigned char a_BonusMax, char a_DropCap=25)
Returns a random number of drops taking into account fortune.
static bool ToolHasSilkTouch(const cItem *a_Tool)
Returns true if the specified tool is valid and has a non-zero silk-touch enchantment.
constexpr cBlockHandler(BLOCKTYPE a_BlockType)
Definition: BlockHandler.h:29
const BLOCKTYPE m_BlockType
Definition: BlockHandler.h:205
virtual cItems ConvertToPickups(const NIBBLETYPE a_BlockMeta, const cItem *const a_Tool) const override
Returns the pickups that would result if the block was mined by a_Digger using a_Tool.
Definition: BlockOre.h:26
~cBlockOreHandler()=default
virtual void OnBroken(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta, const cEntity *a_Digger) const override
Called after a block gets broken (replaced with air), by natural means.
Definition: BlockOre.h:68
virtual std::vector< UInt32 > SpawnSplitExperienceOrbs(Vector3d a_Pos, int a_Reward)=0
Spawns experience orbs of the specified total value at the given location.
Definition: Entity.h:76
bool IsPlayer(void) const
Definition: Entity.h:160
Definition: Player.h:29
Definition: Item.h:37
This class bridges a vector of cItem for safe access via Lua.
Definition: Item.h:215