diff --git a/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java b/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java index 6a5a0451..76984660 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java +++ b/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java @@ -36,7 +36,7 @@ import java.util.UUID; public class FishingListener implements Listener { private final Set fishing = new HashSet<>(); - private static final Random random = new Random(); + private static final Random RANDOM = new Random(); @EventHandler(priority = EventPriority.LOW) public void a(PlayerFishEvent event) { @@ -65,9 +65,9 @@ public class FishingListener implements Listener { private final Player player; private final FishHook hook; - private final int total, exp; + private final int fishStrength, experienceDropped; - private int pulls; + private int currentPulls; /** * Used to track the last time the player swung the fishing rod. @@ -84,16 +84,20 @@ public class FishingListener implements Listener { this.playerData = PlayerData.get(this.player = player); this.hook = hook; - this.total = (int) (caught.rollTugs() * (1 - PlayerData.get(player).getStats().getStat(StatType.FISHING_STRENGTH) / 100)); - this.exp = caught.rollExperience(); + this.fishStrength = (int) Math.floor(caught.rollTugs() * (1 - PlayerData.get(player).getStats().getStat(StatType.FISHING_STRENGTH) / 100)); + this.experienceDropped = caught.rollExperience(); fishing.add(player.getUniqueId()); runTaskTimer(MMOCore.plugin, 0, 2); Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); + + // Check for instant loot + if (fishStrength == 0) + lootFish(); } public void criticalFish() { - pulls = total + 2; + currentPulls = fishStrength + 2; } public boolean isTimedOut() { @@ -105,14 +109,15 @@ public class FishingListener implements Listener { */ public boolean pull() { last = System.currentTimeMillis(); - return pulls++ > total; + currentPulls++; + return currentPulls >= fishStrength; } /** * Critical fish's means you catch the fish on the very first try */ public boolean isCrit() { - return pulls > total + 1; + return currentPulls > fishStrength + 1; } private void close() { @@ -128,7 +133,7 @@ public class FishingListener implements Listener { if (isTimedOut()) close(); - location.getWorld().spawnParticle(Particle.CRIT, location, 0, 2 * (random.nextDouble() - .5), 3, 2 * (random.nextDouble() - .5), .6); + location.getWorld().spawnParticle(Particle.CRIT, location, 0, 2 * (RANDOM.nextDouble() - .5), 3, 2 * (RANDOM.nextDouble() - .5), .6); } @EventHandler @@ -143,54 +148,59 @@ public class FishingListener implements Listener { return; } - if (pulls == 0 && random.nextDouble() < PlayerData.get(player).getStats().getStat(StatType.CRITICAL_FISHING_CHANCE) / 100) + System.out.println("Pulls: " + currentPulls + " / " + fishStrength); + + if (currentPulls == 0 && RANDOM.nextDouble() < PlayerData.get(player).getStats().getStat(StatType.CRITICAL_FISHING_CHANCE) / 100) criticalFish(); // Check if enough pulls; if not, wait till the next fish event - if (!pull()) - return; - - // The fish is successfully looted from here - close(); - - ItemStack mainhand = player.getInventory().getItem(EquipmentSlot.HAND); - MMOCoreUtils.decreaseDurability(player, - (mainhand != null && mainhand.getType() == Material.FISHING_ROD) ? EquipmentSlot.HAND : EquipmentSlot.OFF_HAND, 1); - - if (!isCrit() && random.nextDouble() < PlayerData.get(player).getStats().getStat(StatType.CRITICAL_FISHING_FAILURE_CHANCE) / 100) { - player.setVelocity(hook.getLocation().subtract(player.getLocation()).toVector().setY(0).multiply(3).setY(.5)); - hook.getWorld().spawnParticle(Particle.SMOKE_NORMAL, location, 24, 0, 0, 0, .08); - return; - } - - ItemStack collect = caught.collect(new LootBuilder(playerData, 0)); - if (collect == null) { - hook.getWorld().spawnParticle(Particle.SMOKE_NORMAL, location, 24, 0, 0, 0, .08); - return; - } - - CustomPlayerFishEvent called = new CustomPlayerFishEvent(playerData, collect); - Bukkit.getPluginManager().callEvent(called); - if (called.isCancelled()) - return; - - // Calculate yeet velocity - Item item = hook.getWorld().dropItemNaturally(hook.getLocation(), collect); - MMOCoreUtils.displayIndicator(location.add(0, 1.25, 0), - MMOCore.plugin.configManager.getSimpleMessage("fish-out-water" + (isCrit() ? "-crit" : "")).message()); - Vector vec = player.getLocation().subtract(hook.getLocation()).toVector(); - vec.setY(vec.getY() * .031 + vec.length() * .05); - vec.setX(vec.getX() * .08); - vec.setZ(vec.getZ() * .08); - item.setVelocity(vec); - player.getWorld().playSound(player.getLocation(), VersionSound.BLOCK_NOTE_BLOCK_HAT.toSound(), 1, 0); - for (int j = 0; j < 16; j++) - location.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, location, 0, 4 * (random.nextDouble() - .5), 2, - 4 * (random.nextDouble() - .5), .05); - - if (MMOCore.plugin.fishingManager.hasLinkedProfession()) - playerData.getCollectionSkills().giveExperience(MMOCore.plugin.fishingManager.getLinkedProfession(), exp, EXPSource.FISHING, location); + if (pull()) + lootFish(); } } + + public void lootFish() { + close(); + + ItemStack mainhand = player.getInventory().getItem(EquipmentSlot.HAND); + MMOCoreUtils.decreaseDurability(player, + (mainhand != null && mainhand.getType() == Material.FISHING_ROD) ? EquipmentSlot.HAND : EquipmentSlot.OFF_HAND, 1); + + // Critical fishing failure + if (!isCrit() && RANDOM.nextDouble() < PlayerData.get(player).getStats().getStat(StatType.CRITICAL_FISHING_FAILURE_CHANCE) / 100) { + player.setVelocity(hook.getLocation().subtract(player.getLocation()).toVector().setY(0).multiply(3).setY(.5)); + hook.getWorld().spawnParticle(Particle.SMOKE_NORMAL, location, 24, 0, 0, 0, .08); + return; + } + + // Find looted item + ItemStack collect = caught.collect(new LootBuilder(playerData, 0)); + if (collect == null) { + hook.getWorld().spawnParticle(Particle.SMOKE_NORMAL, location, 24, 0, 0, 0, .08); + return; + } + + // Call Bukkit event + CustomPlayerFishEvent called = new CustomPlayerFishEvent(playerData, collect); + Bukkit.getPluginManager().callEvent(called); + if (called.isCancelled()) + return; + + // Calculate yeet velocity + Item item = hook.getWorld().dropItemNaturally(hook.getLocation(), collect); + MMOCoreUtils.displayIndicator(location.add(0, 1.25, 0), + MMOCore.plugin.configManager.getSimpleMessage("fish-out-water" + (isCrit() ? "-crit" : "")).message()); + Vector vec = player.getLocation().subtract(hook.getLocation()).toVector(); + vec.setY(vec.getY() * .031 + vec.length() * .05); + vec.setX(vec.getX() * .08); + vec.setZ(vec.getZ() * .08); + item.setVelocity(vec); + player.getWorld().playSound(player.getLocation(), VersionSound.BLOCK_NOTE_BLOCK_HAT.toSound(), 1, 0); + for (int j = 0; j < 8; j++) + location.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, location, 0, 4 * (RANDOM.nextDouble() - .5), RANDOM.nextDouble() + 1, 4 * (RANDOM.nextDouble() - .5), .08); + + if (MMOCore.plugin.fishingManager.hasLinkedProfession()) + playerData.getCollectionSkills().giveExperience(MMOCore.plugin.fishingManager.getLinkedProfession(), experienceDropped, EXPSource.FISHING, location); + } } } diff --git a/src/main/java/net/Indyuce/mmocore/manager/profession/SpecificProfessionManager.java b/src/main/java/net/Indyuce/mmocore/manager/profession/SpecificProfessionManager.java index 8ee2708a..04e7cdb9 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/profession/SpecificProfessionManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/profession/SpecificProfessionManager.java @@ -3,6 +3,9 @@ package net.Indyuce.mmocore.manager.profession; import net.Indyuce.mmocore.experience.Profession; import net.Indyuce.mmocore.manager.MMOCoreManager; import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; public abstract class SpecificProfessionManager implements MMOCoreManager { @@ -25,8 +28,9 @@ public abstract class SpecificProfessionManager implements MMOCoreManager { this.linkedProfession = linkedProfession; } + @NotNull public Profession getLinkedProfession() { - return linkedProfession; + return Objects.requireNonNull(linkedProfession, "No linked profession found"); } public boolean hasLinkedProfession() {