diff options
author | Mattes D <github@xoft.cz> | 2020-04-21 22:19:22 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-21 22:19:22 +0200 |
commit | 487f9a2aa9b5497495cef1ac3b9c7a603e69f862 (patch) | |
tree | 054a846942f414060e29c72f4a717c8a89e70893 /src/Items/ItemFishingRod.h | |
parent | Delet SpawnObject params (diff) | |
download | cuberite-487f9a2aa9b5497495cef1ac3b9c7a603e69f862.tar cuberite-487f9a2aa9b5497495cef1ac3b9c7a603e69f862.tar.gz cuberite-487f9a2aa9b5497495cef1ac3b9c7a603e69f862.tar.bz2 cuberite-487f9a2aa9b5497495cef1ac3b9c7a603e69f862.tar.lz cuberite-487f9a2aa9b5497495cef1ac3b9c7a603e69f862.tar.xz cuberite-487f9a2aa9b5497495cef1ac3b9c7a603e69f862.tar.zst cuberite-487f9a2aa9b5497495cef1ac3b9c7a603e69f862.zip |
Diffstat (limited to 'src/Items/ItemFishingRod.h')
-rw-r--r-- | src/Items/ItemFishingRod.h | 370 |
1 files changed, 209 insertions, 161 deletions
diff --git a/src/Items/ItemFishingRod.h b/src/Items/ItemFishingRod.h index 48568ed69..8817c8c38 100644 --- a/src/Items/ItemFishingRod.h +++ b/src/Items/ItemFishingRod.h @@ -63,197 +63,245 @@ public: + + 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 + cWorld * a_World, + cPlayer * a_Player, + cBlockPluginInterface & a_PluginInterface, + const cItem & a_HeldItem, + const Vector3i a_ClickedBlockPos, + eBlockFace a_ClickedBlockFace ) override { - if (a_BlockFace != BLOCK_FACE_NONE) + if (a_ClickedBlockFace != 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()) + ReelIn(*a_World, *a_Player); + } + else + { + // Cast a hook: + auto & Random = GetRandomProvider(); + auto CountDownTime = Random.RandInt(100, 900) - static_cast<int>(a_Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchLure) * 100); + auto Floater = cpp14::make_unique<cFloater>( + a_Player->GetEyePosition(), a_Player->GetLookVector() * 15, + a_Player->GetUniqueID(), + CountDownTime + ); + auto FloaterPtr = Floater.get(); + if (!FloaterPtr->Initialize(std::move(Floater), *a_World)) { - 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); + return false; } - else if (FloaterInfo.CanPickup()) + a_Player->SetIsFishing(true, FloaterPtr->GetUniqueID()); + } + return true; + } + + + + + + /** Reels back the fishing line, reeling any attached mob, or creating fished loot, or just breaking the fishing rod. */ + void ReelIn(cWorld & a_World, cPlayer & a_Player) + { + cFloaterCallback FloaterInfo; + a_World.DoWithEntityByID(a_Player.GetFloaterID(), FloaterInfo); + a_Player.SetIsFishing(false); + + // If attached to an entity, reel it in: + if (FloaterInfo.IsAttached()) + { + ReelInEntity(a_World, a_Player, FloaterInfo.GetAttachedMobID()); + return; + } + + // If loot can be caught, get it: + if (FloaterInfo.CanPickup()) + { + ReelInLoot(a_World, a_Player, FloaterInfo.GetBitePos()); + return; + } + + // Empty fishing rod, just damage it: + auto BlockType = a_World.GetBlock(FloaterInfo.GetPos() - Vector3d(0, 0.1, 0)); + if ((BlockType != E_BLOCK_AIR) && !IsBlockWater(BlockType)) + { + a_Player.UseEquippedItem(2); + } + } + + + + + /** Reels back the entity, specified by the ID, and damages the fishing rod accordingly. */ + void ReelInEntity(cWorld & a_World, cPlayer & a_Player, UInt32 a_EntityID) + { + auto PlayerPos = a_Player.GetPosition(); + a_World.DoWithEntityByID(a_EntityID, [=](cEntity & a_Entity) { - UInt32 LotSLevel = std::min(a_Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchLuckOfTheSea), 3u); + auto Speed = PlayerPos - a_Entity.GetPosition(); + a_Entity.AddSpeed(Speed); + return true; + } + ); + a_Player.UseEquippedItem(5); + } + + + + - // 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% + void ReelInLoot(cWorld & a_World, cPlayer & a_Player, const Vector3d a_FloaterBitePos) + { + auto 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]) + cItems Drops; + auto & Random = GetRandomProvider(); + 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: { - 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); - Drops.Add(Book); - break; - } - case 2: - { - cItem Rod(E_ITEM_FISHING_ROD, 1, Random.RandInt<short>(50)); - Rod.EnchantByXPLevels(Random.RandInt(22, 30)); - Drops.Add(Rod); - break; - } - case 3: - { - Drops.Add(cItem(E_ITEM_NAME_TAG)); - break; - } - case 4: - { - Drops.Add(cItem(E_ITEM_SADDLE)); - break; - } - case 5: - { - Drops.Add(cItem(E_BLOCK_LILY_PAD)); - break; - } - } - - a_Player->GetStatManager().AddValue(statTreasureFished, 1); + cItem Bow(E_ITEM_BOW, 1, Random.RandInt<short>(50)); + Bow.EnchantByXPLevels(Random.RandInt(22, 30)); + Drops.Add(Bow); + break; } - else if (ItemCategory < JunkChances[LotSLevel]) + case 1: { - int Junk = Random.RandInt(82); - if (Junk < 10) // 10 / 83 chance of spawning a bowl - { - Drops.Add(cItem(E_ITEM_BOWL)); - } - else if (Junk < 12) // 2 / 83 chance of spawning a fishing rod - { - // Fishing Rods caught from the Junk category will be 10%-100% damaged, and always unenchanted. - Drops.Add(cItem(E_ITEM_FISHING_ROD, 1, Random.RandInt<short>(7, 65))); - } - else if (Junk < 22) // 10 / 83 chance of spawning leather - { - Drops.Add(cItem(E_ITEM_LEATHER)); - } - else if (Junk < 32) // 10 / 83 chance of spawning leather boots - { - // Leather boots caught from the Junk category will be 10%-100% damaged, and always unenchanted. - Drops.Add(cItem(E_ITEM_LEATHER_BOOTS, 1, Random.RandInt<short>(7, 66))); - } - else if (Junk < 42) // 10 / 83 chance of spawning rotten flesh - { - Drops.Add(cItem(E_ITEM_ROTTEN_FLESH)); - } - else if (Junk < 47) // 5 / 83 chance of spawning a stick - { - Drops.Add(cItem(E_ITEM_STICK)); - } - else if (Junk < 52) // 5 / 83 chance of spawning string - { - Drops.Add(cItem(E_ITEM_STRING)); - } - else if (Junk < 62) // 10 / 83 chance of spawning a water bottle - { - Drops.Add(cItem(E_ITEM_POTION)); - } - else if (Junk < 72) // 10 / 83 chance of spawning a bone - { - Drops.Add(cItem(E_ITEM_BONE)); - } - else if (Junk < 73) // 1 / 83 chance of spawning an ink sac - { - Drops.Add(cItem(E_ITEM_DYE)); - } - else // 10 / 83 chance of spawning a tripwire hook - { - Drops.Add(cItem(E_BLOCK_TRIPWIRE_HOOK)); - } - - a_Player->GetStatManager().AddValue(statJunkFished, 1); + cItem Book(E_ITEM_BOOK); + Book.EnchantByXPLevels(30); + Drops.Add(Book); + break; } - else + case 2: { - int FishType = Random.RandInt(99); - if (FishType <= 1) // Clownfish has a 2% chance of spawning - { - Drops.Add(cItem(E_ITEM_RAW_FISH, 1, E_META_RAW_FISH_CLOWNFISH)); - } - else if (FishType <= 12) // Pufferfish has a 13% chance of spawning - { - Drops.Add(cItem(E_ITEM_RAW_FISH, 1, E_META_RAW_FISH_PUFFERFISH)); - } - else if (FishType <= 24) // Raw salmon has a 25% chance of spawning - { - Drops.Add(cItem(E_ITEM_RAW_FISH, 1, E_META_RAW_FISH_SALMON)); - } - else // Raw fish has a 60% chance of spawning - { - Drops.Add(cItem(E_ITEM_RAW_FISH, 1, E_META_RAW_FISH_FISH)); - } - - a_Player->GetStatManager().AddValue(statFishCaught, 1); + cItem Rod(E_ITEM_FISHING_ROD, 1, Random.RandInt<short>(50)); + Rod.EnchantByXPLevels(Random.RandInt(22, 30)); + Drops.Add(Rod); + break; } - - if (cRoot::Get()->GetPluginManager()->CallHookPlayerFishing(*a_Player, Drops)) + case 3: { - return true; + Drops.Add(cItem(E_ITEM_NAME_TAG)); + break; } - Vector3d FloaterPos = FloaterInfo.GetBitePos(); - FloaterPos.y += 0.5f; - const float FISH_SPEED_MULT = 2.25f; - - Vector3d FlyDirection = (a_Player->GetEyePosition() - FloaterPos).addedY(1.0f) * FISH_SPEED_MULT; - a_World->SpawnItemPickups(Drops, FloaterPos, FlyDirection); - a_World->SpawnExperienceOrb(a_Player->GetPosition(), Random.RandInt(1, 6)); - a_Player->UseEquippedItem(1); - cRoot::Get()->GetPluginManager()->CallHookPlayerFished(*a_Player, Drops); - } - else - { - BLOCKTYPE Block = a_World->GetBlock(FloaterInfo.GetPos() - Vector3d(0, 0.1, 0)); - if ((Block != E_BLOCK_AIR) && !IsBlockWater(Block)) + case 4: + { + Drops.Add(cItem(E_ITEM_SADDLE)); + break; + } + case 5: { - a_Player->UseEquippedItem(2); + Drops.Add(cItem(E_BLOCK_LILY_PAD)); + break; } } + + a_Player.GetStatManager().AddValue(statTreasureFished, 1); + } + else if (ItemCategory < JunkChances[LotSLevel]) + { + int Junk = Random.RandInt(82); + if (Junk < 10) // 10 / 83 chance of spawning a bowl + { + Drops.Add(cItem(E_ITEM_BOWL)); + } + else if (Junk < 12) // 2 / 83 chance of spawning a fishing rod + { + // Fishing Rods caught from the Junk category will be 10% .. 100% damaged, and always unenchanted. + Drops.Add(cItem(E_ITEM_FISHING_ROD, 1, Random.RandInt<short>(7, 65))); + } + else if (Junk < 22) // 10 / 83 chance of spawning leather + { + Drops.Add(cItem(E_ITEM_LEATHER)); + } + else if (Junk < 32) // 10 / 83 chance of spawning leather boots + { + // Leather boots caught from the Junk category will be 10% .. 100% damaged, and always unenchanted. + Drops.Add(cItem(E_ITEM_LEATHER_BOOTS, 1, Random.RandInt<short>(7, 66))); + } + else if (Junk < 42) // 10 / 83 chance of spawning rotten flesh + { + Drops.Add(cItem(E_ITEM_ROTTEN_FLESH)); + } + else if (Junk < 47) // 5 / 83 chance of spawning a stick + { + Drops.Add(cItem(E_ITEM_STICK)); + } + else if (Junk < 52) // 5 / 83 chance of spawning string + { + Drops.Add(cItem(E_ITEM_STRING)); + } + else if (Junk < 62) // 10 / 83 chance of spawning a water bottle + { + Drops.Add(cItem(E_ITEM_POTION)); + } + else if (Junk < 72) // 10 / 83 chance of spawning a bone + { + Drops.Add(cItem(E_ITEM_BONE)); + } + else if (Junk < 73) // 1 / 83 chance of spawning an ink sac + { + Drops.Add(cItem(E_ITEM_DYE)); + } + else // 10 / 83 chance of spawning a tripwire hook + { + Drops.Add(cItem(E_BLOCK_TRIPWIRE_HOOK)); + } + + a_Player.GetStatManager().AddValue(statJunkFished, 1); } else { - auto Floater = cpp14::make_unique<cFloater>(a_Player->GetEyePosition(), a_Player->GetLookVector() * 15, a_Player->GetUniqueID(), (Random.RandInt(100, 900) - static_cast<int>(a_Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchLure) * 100))); - auto FloaterPtr = Floater.get(); - if (!FloaterPtr->Initialize(std::move(Floater), *a_World)) + int FishType = Random.RandInt(99); + if (FishType <= 1) // Clownfish has a 2% chance of spawning { - return false; + Drops.Add(cItem(E_ITEM_RAW_FISH, 1, E_META_RAW_FISH_CLOWNFISH)); } - a_Player->SetIsFishing(true, FloaterPtr->GetUniqueID()); + else if (FishType <= 12) // Pufferfish has a 13% chance of spawning + { + Drops.Add(cItem(E_ITEM_RAW_FISH, 1, E_META_RAW_FISH_PUFFERFISH)); + } + else if (FishType <= 24) // Raw salmon has a 25% chance of spawning + { + Drops.Add(cItem(E_ITEM_RAW_FISH, 1, E_META_RAW_FISH_SALMON)); + } + else // Raw fish has a 60% chance of spawning + { + Drops.Add(cItem(E_ITEM_RAW_FISH, 1, E_META_RAW_FISH_FISH)); + } + + a_Player.GetStatManager().AddValue(statFishCaught, 1); } - return true; + + // Check with plugins if this loot is acceptable: + if (cRoot::Get()->GetPluginManager()->CallHookPlayerFishing(a_Player, Drops)) + { + return; + } + + // Spawn the loot and the experience orb: + auto FloaterPos = a_FloaterBitePos.addedY(0.5); + const float FISH_SPEED_MULT = 2.25f; + Vector3d FlyDirection = (a_Player.GetEyePosition() - FloaterPos).addedY(1.0f) * FISH_SPEED_MULT; + a_World.SpawnItemPickups(Drops, FloaterPos, FlyDirection); + a_World.SpawnExperienceOrb(a_Player.GetPosition(), Random.RandInt(1, 6)); + a_Player.UseEquippedItem(1); + + // Notify plugins + cRoot::Get()->GetPluginManager()->CallHookPlayerFished(a_Player, Drops); } } ; |