<commit_before>
#pragma once

#include "../Entities/Floater.h"
#include "../Entities/Entity.h"
#include "../Item.h"
#include "../Root.h"





////////////////////////////////////////////////////////////////////////////////
// cFloaterCallback
class cFloaterCallback
{
public:
	cFloaterCallback(void) :
		m_CanPickup(false),
		m_AttachedMobID(cEntity::INVALID_ID)
	{
	}

	bool operator () (cEntity & a_Entity)
	{
		auto & Floater = static_cast<cFloater &>(a_Entity);
		m_CanPickup = Floater.CanPickup();
		m_Pos = Floater.GetPosition();
		m_BitePos = Floater.GetBitePos();
		m_AttachedMobID = Floater.GetAttachedMobID();
		Floater.Destroy();
		return true;
	}

	bool CanPickup(void)       const { return m_CanPickup; }
	bool IsAttached(void)      const { return (m_AttachedMobID != cEntity::INVALID_ID); }
	UInt32 GetAttachedMobID(void) const { return m_AttachedMobID; }
	Vector3d GetPos(void)      const { return m_Pos; }
	Vector3d GetBitePos(void)  const { return m_BitePos; }

protected:
	bool m_CanPickup;
	UInt32 m_AttachedMobID;
	Vector3d m_Pos;
	Vector3d m_BitePos;
} ;





class cItemFishingRodHandler :
	public cItemHandler
{
	typedef cItemHandler super;

public:
	cItemFishingRodHandler(int a_ItemType) :
		super(a_ItemType)
	{
	}



	virtual bool OnItemUse(
		cWorld * a_World, cPlayer * a_Player, cBlockPluginInterface & a_PluginInterface, const cItem & a_Item,
		int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace
	) override
	{
		if (a_BlockFace != BLOCK_FACE_NONE)
		{
			return false;
		}

		auto & Random = GetRandomProvider();

		if (a_Player->IsFishing())
		{
			cFloaterCallback FloaterInfo;
			a_World->DoWithEntityByID(a_Player->GetFloaterID(), FloaterInfo);
			a_Player->SetIsFishing(false);

			if (FloaterInfo.IsAttached())
			{
				a_World->DoWithEntityByID(FloaterInfo.GetAttachedMobID(), [=](cEntity & a_Entity)
					{
						Vector3d Speed = a_Player->GetPosition() - a_Entity.GetPosition();
						a_Entity.AddSpeed(Speed);
						return true;
					}
				);
				a_Player->UseEquippedItem(5);
			}
			else if (FloaterInfo.CanPickup())
			{
				UInt32 LotSLevel = std::min(a_Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchLuckOfTheSea), 3u);

				// Chances for getting an item from the category for each level of Luck of the Sea (0 - 3)
				const int TreasureChances[] = {50, 71, 92, 113};  // 5% | 7.1% | 9.2% | 11.3%
				const int JunkChances[] = {100, 81, 61, 42};  // 10% | 8.1% | 6.1% | 4.2%

				cItems Drops;
				int ItemCategory = Random.RandInt(999);
				if (ItemCategory < TreasureChances[LotSLevel])
				{
					switch (Random.RandInt(5))  // Each piece of treasure has an equal chance of 1 / 6
					{
						case 0:
						{
							cItem Bow(E_ITEM_BOW, 1, Random.RandInt<short>(50));
							Bow.EnchantByXPLevels(Random.RandInt(22, 30));
							Drops.Add(Bow);
							break;
						}
						case 1:
						{
							cItem Book(E_ITEM_ENCHANTED_BOOK);
							Book.EnchantByXPLevels(30);<commit_msg>Don't enchant an already enchanted book<commit_after>
#pragma once

#include "../Entities/Floater.h"
#include "../Entities/Entity.h"
#include "../Item.h"
#include "../Root.h"





////////////////////////////////////////////////////////////////////////////////
// cFloaterCallback
class cFloaterCallback
{
public:
	cFloaterCallback(void) :
		m_CanPickup(false),
		m_AttachedMobID(cEntity::INVALID_ID)
	{
	}

	bool operator () (cEntity & a_Entity)
	{
		auto & Floater = static_cast<cFloater &>(a_Entity);
		m_CanPickup = Floater.CanPickup();
		m_Pos = Floater.GetPosition();
		m_BitePos = Floater.GetBitePos();
		m_AttachedMobID = Floater.GetAttachedMobID();
		Floater.Destroy();
		return true;
	}

	bool CanPickup(void)       const { return m_CanPickup; }
	bool IsAttached(void)      const { return (m_AttachedMobID != cEntity::INVALID_ID); }
	UInt32 GetAttachedMobID(void) const { return m_AttachedMobID; }
	Vector3d GetPos(void)      const { return m_Pos; }
	Vector3d GetBitePos(void)  const { return m_BitePos; }

protected:
	bool m_CanPickup;
	UInt32 m_AttachedMobID;
	Vector3d m_Pos;
	Vector3d m_BitePos;
} ;





class cItemFishingRodHandler :
	public cItemHandler
{
	typedef cItemHandler super;

public:
	cItemFishingRodHandler(int a_ItemType) :
		super(a_ItemType)
	{
	}



	virtual bool OnItemUse(
		cWorld * a_World, cPlayer * a_Player, cBlockPluginInterface & a_PluginInterface, const cItem & a_Item,
		int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace
	) override
	{
		if (a_BlockFace != BLOCK_FACE_NONE)
		{
			return false;
		}

		auto & Random = GetRandomProvider();

		if (a_Player->IsFishing())
		{
			cFloaterCallback FloaterInfo;
			a_World->DoWithEntityByID(a_Player->GetFloaterID(), FloaterInfo);
			a_Player->SetIsFishing(false);

			if (FloaterInfo.IsAttached())
			{
				a_World->DoWithEntityByID(FloaterInfo.GetAttachedMobID(), [=](cEntity & a_Entity)
					{
						Vector3d Speed = a_Player->GetPosition() - a_Entity.GetPosition();
						a_Entity.AddSpeed(Speed);
						return true;
					}
				);
				a_Player->UseEquippedItem(5);
			}
			else if (FloaterInfo.CanPickup())
			{
				UInt32 LotSLevel = std::min(a_Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchLuckOfTheSea), 3u);

				// Chances for getting an item from the category for each level of Luck of the Sea (0 - 3)
				const int TreasureChances[] = {50, 71, 92, 113};  // 5% | 7.1% | 9.2% | 11.3%
				const int JunkChances[] = {100, 81, 61, 42};  // 10% | 8.1% | 6.1% | 4.2%

				cItems Drops;
				int ItemCategory = Random.RandInt(999);
				if (ItemCategory < TreasureChances[LotSLevel])
				{
					switch (Random.RandInt(5))  // Each piece of treasure has an equal chance of 1 / 6
					{
						case 0:
						{
							cItem Bow(E_ITEM_BOW, 1, Random.RandInt<short>(50));
							Bow.EnchantByXPLevels(Random.RandInt(22, 30));
							Drops.Add(Bow);
							break;
						}
						case 1:
						{
							cItem Book(E_ITEM_BOOK);
							Book.EnchantByXPLevels(30);
{'fraction_non_alphanumeric': 0.14749411368987556, 'fraction_numerical': 0.022199798183652877, 'mean_word_length': 3.1241331484049932, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '634076', 'n_tokens_mistral': 2671, 'n_tokens_neox': 2185, 'n_words': 434}