Cuberite
A lightweight, fast and extensible game server for Minecraft
ItemFishingRod.h
Go to the documentation of this file.
1 
2 #pragma once
3 
4 #include "../Entities/Floater.h"
5 #include "../Entities/Entity.h"
6 #include "../Item.h"
7 #include "../Root.h"
8 
9 
10 
11 
12 
14 // cFloaterCallback
16 {
17 public:
19  m_CanPickup(false),
20  m_AttachedMobID(cEntity::INVALID_ID)
21  {
22  }
23 
24  bool operator () (cEntity & a_Entity)
25  {
26  auto & Floater = static_cast<cFloater &>(a_Entity);
27  m_CanPickup = Floater.CanPickup();
28  m_Pos = Floater.GetPosition();
29  m_BitePos = Floater.GetBitePos();
30  m_AttachedMobID = Floater.GetAttachedMobID();
31  Floater.Destroy();
32  return true;
33  }
34 
35  bool CanPickup(void) const { return m_CanPickup; }
36  bool IsAttached(void) const { return (m_AttachedMobID != cEntity::INVALID_ID); }
37  UInt32 GetAttachedMobID(void) const { return m_AttachedMobID; }
38  Vector3d GetPos(void) const { return m_Pos; }
39  Vector3d GetBitePos(void) const { return m_BitePos; }
40 
41 protected:
46 } ;
47 
48 
49 
50 
51 
53  public cItemHandler
54 {
56 
57 public:
58 
59  using Super::Super;
60 
61 
62 
63 
64 
65  virtual bool OnItemUse(
66  cWorld * a_World,
67  cPlayer * a_Player,
68  cBlockPluginInterface & a_PluginInterface,
69  const cItem & a_HeldItem,
70  const Vector3i a_ClickedBlockPos,
71  eBlockFace a_ClickedBlockFace
72  ) const override
73  {
74  if (a_ClickedBlockFace != BLOCK_FACE_NONE)
75  {
76  return false;
77  }
78 
79  if (a_Player->IsFishing())
80  {
81  ReelIn(*a_World, *a_Player);
82  }
83  else
84  {
85  // Cast a hook:
86  auto & Random = GetRandomProvider();
87  auto CountDownTime = Random.RandInt(100, 900) - static_cast<int>(a_Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchLure) * 100);
88  auto Floater = std::make_unique<cFloater>(
89  a_Player->GetEyePosition(), a_Player->GetLookVector() * 15,
90  a_Player->GetUniqueID(),
91  CountDownTime
92  );
93  auto FloaterPtr = Floater.get();
94  if (!FloaterPtr->Initialize(std::move(Floater), *a_World))
95  {
96  return false;
97  }
98  a_Player->SetIsFishing(true, FloaterPtr->GetUniqueID());
99  }
100  return true;
101  }
102 
103 
104 
105 
106 
108  void ReelIn(cWorld & a_World, cPlayer & a_Player) const
109  {
110  cFloaterCallback FloaterInfo;
111  a_World.DoWithEntityByID(a_Player.GetFloaterID(), FloaterInfo);
112  a_Player.SetIsFishing(false);
113 
114  // If attached to an entity, reel it in:
115  if (FloaterInfo.IsAttached())
116  {
117  ReelInEntity(a_World, a_Player, FloaterInfo.GetAttachedMobID());
118  return;
119  }
120 
121  // If loot can be caught, get it:
122  if (FloaterInfo.CanPickup())
123  {
124  ReelInLoot(a_World, a_Player, FloaterInfo.GetBitePos());
125  return;
126  }
127 
128  // Empty fishing rod, just damage it:
129  auto BlockType = a_World.GetBlock(FloaterInfo.GetPos() - Vector3d(0, 0.1, 0));
131  {
132  a_Player.UseEquippedItem(2);
133  }
134  }
135 
136 
137 
138 
140  void ReelInEntity(cWorld & a_World, cPlayer & a_Player, UInt32 a_EntityID) const
141  {
142  auto PlayerPos = a_Player.GetPosition();
143  a_World.DoWithEntityByID(a_EntityID, [=](cEntity & a_Entity)
144  {
145  auto Speed = PlayerPos - a_Entity.GetPosition();
146  a_Entity.AddSpeed(Speed);
147  return true;
148  }
149  );
150  a_Player.UseEquippedItem(5);
151  }
152 
153 
154 
155 
156 
157  void ReelInLoot(cWorld & a_World, cPlayer & a_Player, const Vector3d a_FloaterBitePos) const
158  {
159  auto LotSLevel = std::min(a_Player.GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchLuckOfTheSea), 3u);
160 
161  // Chances for getting an item from the category for each level of Luck of the Sea (0 - 3)
162  const int TreasureChances[] = {50, 71, 92, 113}; // 5% | 7.1% | 9.2% | 11.3%
163  const int JunkChances[] = {100, 81, 61, 42}; // 10% | 8.1% | 6.1% | 4.2%
164 
165  cItems Drops;
166  auto & Random = GetRandomProvider();
167  int ItemCategory = Random.RandInt(999);
168  if (ItemCategory < TreasureChances[LotSLevel])
169  {
170  switch (Random.RandInt(5)) // Each piece of treasure has an equal chance of 1 / 6
171  {
172  case 0:
173  {
174  cItem Bow(E_ITEM_BOW, 1, Random.RandInt<short>(50));
175  Bow.EnchantByXPLevels(Random.RandInt(22U, 30U), GetRandomProvider());
176  Drops.Add(Bow);
177  break;
178  }
179  case 1:
180  {
182  Book.EnchantByXPLevels(30, GetRandomProvider());
183  Drops.Add(Book);
184  break;
185  }
186  case 2:
187  {
188  cItem Rod(E_ITEM_FISHING_ROD, 1, Random.RandInt<short>(50));
189  Rod.EnchantByXPLevels(Random.RandInt(22U, 30U), GetRandomProvider());
190  Drops.Add(Rod);
191  break;
192  }
193  case 3:
194  {
195  Drops.Add(cItem(E_ITEM_NAME_TAG));
196  break;
197  }
198  case 4:
199  {
200  Drops.Add(cItem(E_ITEM_SADDLE));
201  break;
202  }
203  case 5:
204  {
205  Drops.Add(cItem(E_BLOCK_LILY_PAD));
206  break;
207  }
208  }
209 
211  }
212  else if (ItemCategory < JunkChances[LotSLevel])
213  {
214  int Junk = Random.RandInt(82);
215  if (Junk < 10) // 10 / 83 chance of spawning a bowl
216  {
217  Drops.Add(cItem(E_ITEM_BOWL));
218  }
219  else if (Junk < 12) // 2 / 83 chance of spawning a fishing rod
220  {
221  // Fishing Rods caught from the Junk category will be 10% .. 100% damaged, and always unenchanted.
222  Drops.Add(cItem(E_ITEM_FISHING_ROD, 1, Random.RandInt<short>(7, 65)));
223  }
224  else if (Junk < 22) // 10 / 83 chance of spawning leather
225  {
226  Drops.Add(cItem(E_ITEM_LEATHER));
227  }
228  else if (Junk < 32) // 10 / 83 chance of spawning leather boots
229  {
230  // Leather boots caught from the Junk category will be 10% .. 100% damaged, and always unenchanted.
231  Drops.Add(cItem(E_ITEM_LEATHER_BOOTS, 1, Random.RandInt<short>(7, 66)));
232  }
233  else if (Junk < 42) // 10 / 83 chance of spawning rotten flesh
234  {
235  Drops.Add(cItem(E_ITEM_ROTTEN_FLESH));
236  }
237  else if (Junk < 47) // 5 / 83 chance of spawning a stick
238  {
239  Drops.Add(cItem(E_ITEM_STICK));
240  }
241  else if (Junk < 52) // 5 / 83 chance of spawning string
242  {
243  Drops.Add(cItem(E_ITEM_STRING));
244  }
245  else if (Junk < 62) // 10 / 83 chance of spawning a water bottle
246  {
247  Drops.Add(cItem(E_ITEM_POTION));
248  }
249  else if (Junk < 72) // 10 / 83 chance of spawning a bone
250  {
251  Drops.Add(cItem(E_ITEM_BONE));
252  }
253  else if (Junk < 73) // 1 / 83 chance of spawning an ink sac
254  {
255  Drops.Add(cItem(E_ITEM_DYE));
256  }
257  else // 10 / 83 chance of spawning a tripwire hook
258  {
260  }
261 
263  }
264  else
265  {
266  int FishType = Random.RandInt(99);
267  if (FishType <= 1) // Clownfish has a 2% chance of spawning
268  {
270  }
271  else if (FishType <= 12) // Pufferfish has a 13% chance of spawning
272  {
274  }
275  else if (FishType <= 24) // Raw salmon has a 25% chance of spawning
276  {
278  }
279  else // Raw fish has a 60% chance of spawning
280  {
282  }
283 
285  }
286 
287  auto Experience = Random.RandInt(1, 6);
288 
289  // Check with plugins if this loot is acceptable:
290  if (cRoot::Get()->GetPluginManager()->CallHookPlayerFishing(a_Player, Drops, Experience))
291  {
292  return;
293  }
294 
295  // Spawn the loot and the experience orb:
296  auto FloaterPos = a_FloaterBitePos.addedY(0.5);
297  const float FISH_SPEED_MULT = 2.25f;
298  Vector3d FlyDirection = (a_Player.GetEyePosition() - FloaterPos).addedY(1.0f) * FISH_SPEED_MULT;
299  a_World.SpawnItemPickups(Drops, FloaterPos, FlyDirection);
300  a_World.SpawnExperienceOrb(a_Player.GetPosition(), Experience);
301  a_Player.UseEquippedItem(1);
302 
303  // Notify plugins
304  cRoot::Get()->GetPluginManager()->CallHookPlayerFished(a_Player, Drops, Experience);
305  }
306 } ;
bool IsBlockWater(BLOCKTYPE a_BlockType)
Definition: BlockInfo.cpp:10
@ E_BLOCK_AIR
Definition: BlockType.h:10
@ E_BLOCK_LILY_PAD
Definition: BlockType.h:126
@ E_BLOCK_TRIPWIRE_HOOK
Definition: BlockType.h:146
@ E_ITEM_POTION
Definition: BlockType.h:418
@ E_ITEM_ROTTEN_FLESH
Definition: BlockType.h:412
@ E_ITEM_DYE
Definition: BlockType.h:396
@ E_ITEM_FISHING_ROD
Definition: BlockType.h:391
@ E_ITEM_BOWL
Definition: BlockType.h:325
@ E_ITEM_STICK
Definition: BlockType.h:324
@ E_ITEM_BOOK
Definition: BlockType.h:385
@ E_ITEM_STRING
Definition: BlockType.h:331
@ E_ITEM_LEATHER
Definition: BlockType.h:378
@ E_ITEM_SADDLE
Definition: BlockType.h:373
@ E_ITEM_RAW_FISH
Definition: BlockType.h:394
@ E_ITEM_BONE
Definition: BlockType.h:397
@ E_ITEM_NAME_TAG
Definition: BlockType.h:468
@ E_ITEM_LEATHER_BOOTS
Definition: BlockType.h:345
@ E_ITEM_BOW
Definition: BlockType.h:305
@ E_META_RAW_FISH_PUFFERFISH
Definition: BlockType.h:1078
@ E_META_RAW_FISH_FISH
Definition: BlockType.h:1075
@ E_META_RAW_FISH_SALMON
Definition: BlockType.h:1076
@ E_META_RAW_FISH_CLOWNFISH
Definition: BlockType.h:1077
eBlockFace
Block face constants, used in PlayerDigging and PlayerBlockPlacement packets and bbox collision calc.
Definition: Defines.h:38
@ BLOCK_FACE_NONE
Definition: Defines.h:39
MTRand & GetRandomProvider()
Returns the current thread's random number source.
Definition: FastRandom.cpp:12
unsigned int UInt32
Definition: Globals.h:157
BlockType
Definition: BlockTypes.h:4
bool CallHookPlayerFished(cPlayer &a_Player, const cItems &a_Reward, const int ExperienceAmount)
This interface is used to decouple block handlers from the cPluginManager dependency through cWorld.
unsigned int GetLevel(int a_EnchantmentID) const
Returns the level for the specified enchantment; 0 if not stored.
Definition: Entity.h:76
void AddSpeed(double a_AddSpeedX, double a_AddSpeedY, double a_AddSpeedZ)
Definition: Entity.cpp:2194
static const UInt32 INVALID_ID
Special ID that is considered an "invalid value", signifying no entity.
Definition: Entity.h:128
UInt32 GetUniqueID(void) const
Definition: Entity.h:253
const Vector3d & GetPosition(void) const
Exported in ManualBindings.
Definition: Entity.h:297
Vector3d GetLookVector(void) const
Definition: Entity.cpp:2267
Definition: Player.h:29
StatisticsManager & GetStatistics()
Return the associated statistic and achievement manager.
Definition: Player.h:237
const cItem & GetEquippedItem(void) const
Definition: Player.h:162
void SetIsFishing(bool a_IsFishing, UInt32 a_FloaterID=cEntity::INVALID_ID)
Definition: Player.h:388
bool IsFishing(void) const
Returns true if the player has thrown out a floater.
Definition: Player.h:386
UInt32 GetFloaterID(void) const
Definition: Player.h:390
Vector3d GetEyePosition(void) const
Definition: Player.cpp:1001
void UseEquippedItem(short a_Damage=1)
Damage the player's equipped item by a_Damage, possibly less if the equipped item is enchanted.
Definition: Player.cpp:2033
Definition: Item.h:37
cEnchantments m_Enchantments
Definition: Item.h:166
bool EnchantByXPLevels(unsigned a_NumXPLevels, MTRand &a_Random)
Randomly enchants the item using the specified number of XP levels.
Definition: Item.cpp:431
This class bridges a vector of cItem for safe access via Lua.
Definition: Item.h:215
void Add(const cItem &a_Item)
Definition: Item.h:233
Vector3d GetPos(void) const
bool CanPickup(void) const
bool operator()(cEntity &a_Entity)
bool IsAttached(void) const
Vector3d GetBitePos(void) const
UInt32 GetAttachedMobID(void) const
void ReelInEntity(cWorld &a_World, cPlayer &a_Player, UInt32 a_EntityID) const
Reels back the entity, specified by the ID, and damages the fishing rod accordingly.
virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cBlockPluginInterface &a_PluginInterface, const cItem &a_HeldItem, const Vector3i a_ClickedBlockPos, eBlockFace a_ClickedBlockFace) const override
Called when the player tries to use the item (right mouse button).
void ReelIn(cWorld &a_World, cPlayer &a_Player) const
Reels back the fishing line, reeling any attached mob, or creating fished loot, or just breaking the ...
void ReelInLoot(cWorld &a_World, cPlayer &a_Player, const Vector3d a_FloaterBitePos) const
constexpr cItemHandler(int a_ItemType)
Definition: ItemHandler.h:37
friend class cItem
Definition: ItemHandler.h:25
static cRoot * Get()
Definition: Root.h:52
cPluginManager * GetPluginManager(void)
Definition: Root.h:111
std::unordered_map< CustomStatistic, StatValue > Custom
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
Definition: World.h:53
UInt32 SpawnExperienceOrb(Vector3d a_Pos, int a_Reward)
Spawns an experience orb at the given location with the given reward.
Definition: World.cpp:1894
BLOCKTYPE GetBlock(Vector3i a_BlockPos) const
Returns the block type at the specified position.
Definition: World.h:363
bool DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback a_Callback)
Calls the callback if the entity with the specified ID is found, with the entity object as the callba...
Definition: World.cpp:2464
void SpawnItemPickups(const cItems &a_Pickups, Vector3i a_BlockPos, double a_FlyAwaySpeed=1.0, bool a_IsPlayerCreated=false)
Spawns item pickups for each item in the list.
Definition: World.cpp:1806