9
0
mirror of https://github.com/Xiao-MoMi/Custom-Fishing.git synced 2025-12-28 19:39:06 +00:00
Files
Custom-Fishing/src/main/java/net/momirealms/customfishing/manager/FishingManager.java
Xiao-MoMi 97fd04b017 1.2.17.2
2023-01-09 20:05:07 +08:00

1002 lines
42 KiB
Java

/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.manager;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTItem;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.momirealms.customfishing.CustomFishing;
import net.momirealms.customfishing.api.event.*;
import net.momirealms.customfishing.competition.Competition;
import net.momirealms.customfishing.data.PlayerBagData;
import net.momirealms.customfishing.integration.AntiGriefInterface;
import net.momirealms.customfishing.integration.MobInterface;
import net.momirealms.customfishing.integration.item.McMMOTreasure;
import net.momirealms.customfishing.listener.*;
import net.momirealms.customfishing.object.Function;
import net.momirealms.customfishing.object.action.ActionInterface;
import net.momirealms.customfishing.object.fishing.*;
import net.momirealms.customfishing.object.loot.DroppedItem;
import net.momirealms.customfishing.object.loot.Loot;
import net.momirealms.customfishing.object.loot.Mob;
import net.momirealms.customfishing.object.requirements.RequirementInterface;
import net.momirealms.customfishing.object.totem.ActivatedTotem;
import net.momirealms.customfishing.object.totem.Totem;
import net.momirealms.customfishing.util.AdventureUtil;
import net.momirealms.customfishing.util.FakeItemUtil;
import net.momirealms.customfishing.util.ItemStackUtil;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.*;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class FishingManager extends Function {
private final PlayerFishListener playerFishListener;
private final InteractListener interactListener;
private PickUpListener pickUpListener;
private MMOItemsListener mmoItemsListener;
private JobsRebornXPListener jobsRebornXPListener;
private final HashMap<Player, Long> coolDown;
private final HashMap<Player, FishHook> hooksCache;
private final HashMap<Player, Loot> nextLoot;
private final HashMap<Player, Bonus> nextBonus;
private final HashMap<Player, VanillaLoot> vanillaLoot;
private final ConcurrentHashMap<Player, FishingPlayer> fishingPlayerCache;
private final ConcurrentHashMap<Location, ActivatedTotem> totemCache;
private final ConcurrentHashMap<Player, BobberCheckTask> bobberTaskCache;
public FishingManager() {
this.playerFishListener = new PlayerFishListener(this);
this.interactListener = new InteractListener(this);
this.coolDown = new HashMap<>();
this.hooksCache = new HashMap<>();
this.nextLoot = new HashMap<>();
this.nextBonus = new HashMap<>();
this.vanillaLoot = new HashMap<>();
this.fishingPlayerCache = new ConcurrentHashMap<>();
this.totemCache = new ConcurrentHashMap<>();
this.bobberTaskCache = new ConcurrentHashMap<>();
load();
}
@Override
public void load() {
Bukkit.getPluginManager().registerEvents(this.playerFishListener, CustomFishing.plugin);
Bukkit.getPluginManager().registerEvents(this.interactListener, CustomFishing.plugin);
if (ConfigManager.preventPickUp) {
this.pickUpListener = new PickUpListener();
Bukkit.getPluginManager().registerEvents(this.pickUpListener, CustomFishing.plugin);
}
if (ConfigManager.convertMMOItems) {
this.mmoItemsListener = new MMOItemsListener(this);
Bukkit.getPluginManager().registerEvents(this.mmoItemsListener, CustomFishing.plugin);
}
if (ConfigManager.disableJobsXp) {
this.jobsRebornXPListener = new JobsRebornXPListener();
Bukkit.getPluginManager().registerEvents(this.jobsRebornXPListener, CustomFishing.plugin);
}
}
@Override
public void unload() {
HandlerList.unregisterAll(this.playerFishListener);
HandlerList.unregisterAll(this.interactListener);
if (this.pickUpListener != null) HandlerList.unregisterAll(this.pickUpListener);
if (this.mmoItemsListener != null) HandlerList.unregisterAll(this.mmoItemsListener);
if (this.jobsRebornXPListener != null) HandlerList.unregisterAll(this.jobsRebornXPListener);
for (BobberCheckTask bobberCheckTask : bobberTaskCache.values()) {
bobberCheckTask.stop();
}
}
public void onFishing(PlayerFishEvent event) {
final Player player = event.getPlayer();
final FishHook fishHook = event.getHook();
hooksCache.put(player, fishHook);
if (isCoolDown(player, 500)) return;
Bukkit.getScheduler().runTaskAsynchronously(CustomFishing.plugin, () -> {
PlayerInventory inventory = player.getInventory();
boolean noSpecialRod = true;
boolean noRod = true;
boolean noBait = true;
int lureLevel = 0;
ItemStack baitItem = null;
Bonus initialBonus = new Bonus();
initialBonus.setDifficulty(0);
initialBonus.setDoubleLoot(0);
initialBonus.setTime(1);
initialBonus.setScore(1);
initialBonus.setWeightMD(new HashMap<>());
initialBonus.setWeightAS(new HashMap<>());
ItemStack mainHandItem = inventory.getItemInMainHand();
Material mainHandItemType = mainHandItem.getType();
if (mainHandItemType != Material.AIR) {
if (mainHandItemType == Material.FISHING_ROD) {
noRod = false;
enchantBonus(initialBonus, mainHandItem);
lureLevel = mainHandItem.getEnchantmentLevel(Enchantment.LURE);
}
NBTItem mainHandNBTItem = new NBTItem(mainHandItem);
NBTCompound nbtCompound = mainHandNBTItem.getCompound("CustomFishing");
if (nbtCompound != null) {
if (nbtCompound.getString("type").equals("rod")) {
Bonus rodBonus = BonusManager.ROD.get(nbtCompound.getString("id"));
if (rodBonus != null){
initialBonus.addBonus(rodBonus);
noSpecialRod = false;
}
}
else if (nbtCompound.getString("type").equals("bait")) {
Bonus baitBonus = BonusManager.BAIT.get(nbtCompound.getString("id"));
if (baitBonus != null) {
initialBonus.addBonus(baitBonus);
baitItem = mainHandItem.clone();
mainHandItem.setAmount(mainHandItem.getAmount() - 1);
noBait = false;
}
}
}
}
ItemStack offHandItem = inventory.getItemInOffHand();
Material offHandItemType = offHandItem.getType();
if (offHandItemType != Material.AIR){
if (noRod && offHandItemType == Material.FISHING_ROD) {
enchantBonus(initialBonus, offHandItem);
lureLevel = offHandItem.getEnchantmentLevel(Enchantment.LURE);
}
NBTItem offHandNBTItem = new NBTItem(offHandItem);
NBTCompound nbtCompound = offHandNBTItem.getCompound("CustomFishing");
if (nbtCompound != null) {
if (noBait && nbtCompound.getString("type").equals("bait")) {
Bonus baitBonus = BonusManager.BAIT.get(nbtCompound.getString("id"));
if (baitBonus != null){
initialBonus.addBonus(baitBonus);
offHandItem.setAmount(offHandItem.getAmount() - 1);
baitItem = offHandItem.clone();
noBait = false;
}
}
else if (noSpecialRod && nbtCompound.getString("type").equals("rod")) {
Bonus rodBonus = BonusManager.ROD.get(nbtCompound.getString("id"));
if (rodBonus != null) {
initialBonus.addBonus(rodBonus);
noSpecialRod = false;
}
}
}
}
for (ActivatedTotem activatedTotem : totemCache.values()) {
if (activatedTotem.getNearbyPlayerSet().contains(player)) {
initialBonus.addBonus(activatedTotem.getTotem().getBonus());
break;
}
}
if (ConfigManager.enableFishingBag && noBait) {
PlayerBagData playerBagData = BagDataManager.dataCache.get(player.getUniqueId());
if (playerBagData != null) {
Inventory baitInv = playerBagData.getInventory();
for (int i = 0; i < baitInv.getSize(); i++) {
ItemStack itemStack = baitInv.getItem(i);
if (itemStack == null || itemStack.getType() == Material.AIR) continue;
NBTItem nbtItem = new NBTItem(itemStack);
NBTCompound cfCompound = nbtItem.getCompound("CustomFishing");
if (cfCompound == null) continue;
if (!cfCompound.getString("type").equals("bait")) continue;
Bonus baitBonus = BonusManager.BAIT.get(cfCompound.getString("id"));
if (baitBonus != null) {
initialBonus.addBonus(baitBonus);
baitItem = itemStack.clone();
itemStack.setAmount(itemStack.getAmount() - 1);
break;
}
}
}
}
RodCastEvent rodCastEvent = new RodCastEvent(player, initialBonus);
if (rodCastEvent.isCancelled()) {
event.setCancelled(true);
return;
}
fishHook.setMaxWaitTime((int) (fishHook.getMaxWaitTime() * initialBonus.getTime()));
fishHook.setMinWaitTime((int) (fishHook.getMinWaitTime() * initialBonus.getTime()));
nextBonus.put(player, initialBonus);
if (ConfigManager.needRodToFish && noSpecialRod) {
nextLoot.put(player, Loot.EMPTY);
return;
}
initialBonus.setHasSpecialRod(!noSpecialRod);
int entityID = 0;
if (baitItem != null) {
baitItem.setAmount(1);
entityID = new Random().nextInt(100000000);
CustomFishing.protocolManager.sendServerPacket(player, FakeItemUtil.getSpawnPacket(entityID, fishHook.getLocation()));
CustomFishing.protocolManager.sendServerPacket(player, FakeItemUtil.getMetaPacket(entityID, baitItem));
}
BobberCheckTask bobberCheckTask = new BobberCheckTask(player, initialBonus, fishHook, this, lureLevel, entityID);
bobberCheckTask.runTaskTimer(CustomFishing.plugin, 1, 1);
bobberTaskCache.put(player, bobberCheckTask);
});
}
public void getNextLoot(Player player, Bonus initialBonus, List<Loot> possibleLoots) {
List<Loot> availableLoots = new ArrayList<>();
if (possibleLoots.size() == 0){
nextLoot.put(player, null);
return;
}
HashMap<String, Integer> as = initialBonus.getWeightAS();
HashMap<String, Double> md = initialBonus.getWeightMD();
double[] weights = new double[possibleLoots.size()];
int index = 0;
for (Loot loot : possibleLoots){
double weight = loot.getWeight();
String group = loot.getGroup();
if (group != null){
if (as.get(group) != null){
weight += as.get(group);
}
if (md.get(group) != null){
weight *= md.get(group);
}
}
if (weight <= 0) continue;
availableLoots.add(loot);
weights[index++] = weight;
}
double total = Arrays.stream(weights).sum();
double[] weightRatios = new double[index];
for (int i = 0; i < index; i++){
weightRatios[i] = weights[i]/total;
}
double[] weightRange = new double[index];
double startPos = 0;
for (int i = 0; i < index; i++) {
weightRange[i] = startPos + weightRatios[i];
startPos += weightRatios[i];
}
double random = Math.random();
int pos = Arrays.binarySearch(weightRange, random);
if (pos < 0) {
pos = -pos - 1;
}
if (pos < weightRange.length && random < weightRange[pos]) {
nextLoot.put(player, availableLoots.get(pos));
return;
}
nextLoot.put(player, null);
}
public void onCaughtFish(PlayerFishEvent event) {
final Player player = event.getPlayer();
if (!(event.getCaught() instanceof Item item)) return;
if (ConfigManager.disableBar) {
noBarWaterReelIn(event);
return;
}
FishingPlayer fishingPlayer = fishingPlayerCache.remove(player);
if (fishingPlayer == null) {
Loot loot = nextLoot.get(player);
if (loot == Loot.EMPTY) return;
if (ConfigManager.enableVanillaLoot) {
// Not a vanilla loot
if (ConfigManager.vanillaLootRatio < Math.random()) {
event.setCancelled(true);
if (loot != null) {
vanillaLoot.remove(player);
}
else {
vanillaLoot.put(player, new VanillaLoot(item.getItemStack(), event.getExpToDrop()));
}
showPlayerBar(player, loot);
}
// Is vanilla loot
else {
if (ConfigManager.alwaysFishingBar) {
event.setCancelled(true);
vanillaLoot.put(player, new VanillaLoot(item.getItemStack(), event.getExpToDrop()));
showPlayerBar(player, null);
}
//else vanilla fishing mechanic
}
}
else {
// No custom loot
if (loot == null) {
item.remove();
event.setExpToDrop(0);
AdventureUtil.playerMessage(player, MessageManager.prefix + MessageManager.noLoot);
}
else {
event.setCancelled(true);
showPlayerBar(player, loot);
}
}
}
else {
item.remove();
event.setExpToDrop(0);
proceedReelIn(event, player, fishingPlayer);
}
}
private void noBarWaterReelIn(PlayerFishEvent event) {
Entity entity = event.getCaught();
if (!(entity instanceof Item item)) {
return;
}
entity.remove();
event.setExpToDrop(0);
final Player player = event.getPlayer();
Loot loot = nextLoot.remove(player);
VanillaLoot vanilla = vanillaLoot.remove(player);
Bonus bonus = nextBonus.remove(player);
if (vanilla != null) {
dropVanillaLoot(player, vanilla, item.getLocation(), bonus.getDoubleLoot() > Math.random());
return;
}
if (loot instanceof Mob mob) {
summonMob(player, loot, item.getLocation(), mob, bonus.getScore());
return;
}
if (loot instanceof DroppedItem droppedItem){
if (ConfigManager.enableMcMMOLoot && Math.random() < ConfigManager.mcMMOLootChance){
if (dropMcMMOLoot(player, item.getLocation(), bonus.getDoubleLoot() > Math.random())){
return;
}
}
dropCustomFishingLoot(player, item.getLocation(), droppedItem, bonus.getDoubleLoot() > Math.random(), bonus.getScore());
}
}
private void noBarLavaReelIn(PlayerFishEvent event) {
final Player player = event.getPlayer();
BobberCheckTask bobberCheckTask = bobberTaskCache.remove(player);
if (bobberCheckTask != null && bobberCheckTask.isHooked()) {
Loot loot = nextLoot.remove(player);
VanillaLoot vanilla = vanillaLoot.remove(player);
Bonus bonus = nextBonus.remove(player);
if (vanilla != null) {
dropVanillaLoot(player, vanilla, event.getHook().getLocation(), bonus.getDoubleLoot() > Math.random());
return;
}
if (loot instanceof Mob mob) {
summonMob(player, loot, event.getHook().getLocation(), mob, bonus.getScore());
return;
}
if (loot instanceof DroppedItem droppedItem) {
if (ConfigManager.enableMcMMOLoot && Math.random() < ConfigManager.mcMMOLootChance) {
if (dropMcMMOLoot(player, event.getHook().getLocation(), bonus.getDoubleLoot() > Math.random())){
return;
}
}
dropCustomFishingLoot(player, event.getHook().getLocation(), droppedItem, bonus.getDoubleLoot() > Math.random(), bonus.getScore());
}
}
}
private void proceedReelIn(PlayerFishEvent event, Player player, FishingPlayer fishingPlayer) {
fishingPlayer.cancel();
Loot loot = nextLoot.remove(player);
VanillaLoot vanilla = vanillaLoot.remove(player);
player.removePotionEffect(PotionEffectType.SLOW);
if (fishingPlayer.isSuccess()) {
if (ConfigManager.rodLoseDurability) loseDurability(player);
Location location = event.getHook().getLocation();
if (location.getBlock().getType() == Material.LAVA) {
location.add(0,0.3,0);
}
if (vanilla != null) {
dropVanillaLoot(player, vanilla, location, fishingPlayer.isDouble());
return;
}
if (loot instanceof Mob mob) {
summonMob(player, loot, location, mob, fishingPlayer.getScoreMultiplier());
return;
}
if (loot instanceof DroppedItem droppedItem){
if (ConfigManager.enableMcMMOLoot && Math.random() < ConfigManager.mcMMOLootChance){
if (dropMcMMOLoot(player, location, fishingPlayer.isDouble())){
return;
}
}
dropCustomFishingLoot(player, location, droppedItem, fishingPlayer.isDouble(), fishingPlayer.getScoreMultiplier());
}
}
else {
fail(player, loot, vanilla != null);
}
}
public void onReelIn(PlayerFishEvent event) {
final Player player = event.getPlayer();
if (ConfigManager.disableBar) {
noBarLavaReelIn(event);
return;
}
//in fishing
FishingPlayer fishingPlayer = fishingPlayerCache.remove(player);
if (fishingPlayer != null) {
proceedReelIn(event, player, fishingPlayer);
bobberTaskCache.remove(player);
return;
}
//not in fishing
BobberCheckTask bobberCheckTask = bobberTaskCache.get(player);
if (bobberCheckTask != null && bobberCheckTask.isHooked()) {
Loot loot = nextLoot.get(player);
if (loot == Loot.EMPTY) return;
showPlayerBar(player, loot);
event.setCancelled(true);
}
}
private void dropCustomFishingLoot(Player player, Location location, DroppedItem droppedItem, boolean isDouble, double scoreMultiplier) {
ItemStack drop = getCustomFishingLootItemStack(droppedItem, player);
FishResultEvent fishResultEvent = new FishResultEvent(player, FishResult.CAUGHT_LOOT, isDouble, drop, droppedItem.getKey());
Bukkit.getPluginManager().callEvent(fishResultEvent);
if (fishResultEvent.isCancelled()) {
return;
}
Bonus bonus = nextBonus.remove(player);
if (Competition.currentCompetition != null){
float score = (float) (droppedItem.getScore() * scoreMultiplier);
Competition.currentCompetition.refreshData(player, (float) (score * bonus.getScore()), isDouble);
Competition.currentCompetition.tryAddBossBarToPlayer(player);
}
dropItem(player, location, fishResultEvent.isDouble(), drop);
for (ActionInterface action : droppedItem.getSuccessActions())
action.doOn(player, null);
sendSuccessTitle(player, droppedItem.getNick());
}
private ItemStack getCustomFishingLootItemStack(DroppedItem droppedItem, Player player) {
String key = droppedItem.getMaterial();
ItemStack drop = CustomFishing.plugin.getIntegrationManager().build(key);
if (drop.getType() != Material.AIR) {
if (droppedItem.getRandomEnchants() != null)
ItemStackUtil.addRandomEnchants(drop, droppedItem.getRandomEnchants());
if (droppedItem.isRandomDurability())
ItemStackUtil.addRandomDamage(drop);
if (ConfigManager.preventPickUp)
ItemStackUtil.addOwner(drop, player.getName());
ItemStackUtil.addExtraMeta(drop, droppedItem);
if (ConfigManager.addTagToFish) ItemStackUtil.addIdentifier(drop, "loot", droppedItem.getKey());
}
return drop;
}
private boolean dropMcMMOLoot(Player player, Location location, boolean isDouble) {
ItemStack itemStack = McMMOTreasure.getTreasure(player);
if (itemStack == null) return false;
FishResultEvent fishResultEvent = new FishResultEvent(player, FishResult.CAUGHT_VANILLA, isDouble, itemStack, "mcmmo");
Bukkit.getPluginManager().callEvent(fishResultEvent);
if (fishResultEvent.isCancelled()) {
return true;
}
nextBonus.remove(player);
if (Competition.currentCompetition != null){
Competition.currentCompetition.refreshData(player, 0, isDouble);
Competition.currentCompetition.tryAddBossBarToPlayer(player);
}
player.giveExp(new Random().nextInt(24), true);
dropItem(player, location, fishResultEvent.isDouble(), itemStack);
sendSuccessTitle(player, itemStack);
return true;
}
private void dropItem(Player player, Location location, boolean isDouble, ItemStack itemStack) {
if (itemStack.getType() == Material.AIR) return;
Entity item = location.getWorld().dropItem(location, itemStack);
Vector vector = player.getLocation().subtract(location).toVector().multiply(0.1);
vector = vector.setY((vector.getY()+0.18) * 1.15);
item.setVelocity(vector);
if (isDouble) {
Entity item2 = location.getWorld().dropItem(location, itemStack);
item2.setVelocity(vector);
}
}
private void dropVanillaLoot(Player player, VanillaLoot vanillaLoot, Location location, boolean isDouble) {
ItemStack itemStack;
itemStack = vanillaLoot.getItemStack();
if (ConfigManager.enableMcMMOLoot && Math.random() < ConfigManager.mcMMOLootChance){
ItemStack mcMMOItemStack = McMMOTreasure.getTreasure(player);
if (mcMMOItemStack != null){
itemStack = mcMMOItemStack;
}
}
FishResultEvent fishResultEvent = new FishResultEvent(player, FishResult.CAUGHT_VANILLA, isDouble, itemStack, "vanilla");
Bukkit.getPluginManager().callEvent(fishResultEvent);
if (fishResultEvent.isCancelled()) {
return;
}
nextBonus.remove(player);
if (Competition.currentCompetition != null){
Competition.currentCompetition.refreshData(player, 0, isDouble);
Competition.currentCompetition.tryAddBossBarToPlayer(player);
}
player.giveExp(vanillaLoot.getXp(), true);
AdventureUtil.playerSound(player, Sound.Source.PLAYER, Key.key("minecraft:entity.experience_orb.pickup"), 1, 1);
dropItem(player, location, isDouble, itemStack);
sendSuccessTitle(player, itemStack);
}
private void summonMob(Player player, Loot loot, Location location, Mob mob, double scoreMultiplier) {
MobInterface mobInterface = CustomFishing.plugin.getIntegrationManager().getMobInterface();
if (mobInterface == null) return;
FishResultEvent fishResultEvent = new FishResultEvent(player, FishResult.CAUGHT_MOB, false, null, loot.getKey());
if (fishResultEvent.isCancelled()) {
return;
}
Bonus bonus = nextBonus.remove(player);
if (Competition.currentCompetition != null) {
float score = (float) (loot.getScore() * scoreMultiplier);
Competition.currentCompetition.refreshData(player, (float) (score * bonus.getScore()), false);
Competition.currentCompetition.tryAddBossBarToPlayer(player);
}
mobInterface.summon(player.getLocation(), location, mob);
for (ActionInterface action : loot.getSuccessActions())
action.doOn(player, null);
sendSuccessTitle(player, loot.getNick());
}
@NotNull
private Component getTitleComponent(ItemStack itemStack, String text) {
Component component;
if (text.contains("{loot}")){
text = text.replace("{loot}","|");
if (text.startsWith("|")){
component = getDisplayName(itemStack).append(MiniMessage.miniMessage().deserialize(AdventureUtil.replaceLegacy(text.substring(1))));
}
else if (text.endsWith("|")){
component = MiniMessage.miniMessage().deserialize(AdventureUtil.replaceLegacy(text.substring(0,text.length() - 1))).append(getDisplayName(itemStack));
}
else {
String[] titleSplit = StringUtils.split(text, "|");
component = MiniMessage.miniMessage().deserialize(AdventureUtil.replaceLegacy(titleSplit[0])).append(getDisplayName(itemStack)).append(MiniMessage.miniMessage().deserialize(AdventureUtil.replaceLegacy(titleSplit[1])));
}
}
else {
component = MiniMessage.miniMessage().deserialize(AdventureUtil.replaceLegacy(text));
}
return component;
}
private void sendSuccessTitle(Player player, String loot) {
AdventureUtil.playerTitle(
player,
ConfigManager.successTitle[new Random().nextInt(ConfigManager.successTitle.length)]
.replace("{loot}", loot)
.replace("{player}", player.getName()),
ConfigManager.successSubTitle[new Random().nextInt(ConfigManager.successSubTitle.length)]
.replace("{loot}", loot)
.replace("{player}", player.getName()),
ConfigManager.successFadeIn,
ConfigManager.successFadeStay,
ConfigManager.successFadeOut
);
}
private void sendSuccessTitle(Player player, ItemStack itemStack) {
String title = ConfigManager.successTitle[new Random().nextInt(ConfigManager.successTitle.length)];
Component titleComponent = getTitleComponent(itemStack, title);
String subTitle = ConfigManager.successSubTitle[new Random().nextInt(ConfigManager.successSubTitle.length)];
Component subtitleComponent = getTitleComponent(itemStack, subTitle);
AdventureUtil.playerTitle(
player,
titleComponent,
subtitleComponent,
ConfigManager.successFadeIn,
ConfigManager.successFadeStay,
ConfigManager.successFadeOut
);
}
private void loseDurability(Player player) {
if (player.getGameMode() == GameMode.CREATIVE) return;
Bukkit.getScheduler().runTaskLater(CustomFishing.plugin, () -> {
PlayerInventory inventory = player.getInventory();
ItemStack mainHand = inventory.getItemInMainHand();
if (mainHand.getType() == Material.FISHING_ROD){
CustomFishing.plugin.getIntegrationManager().loseCustomDurability(mainHand, player);
}
else {
ItemStack offHand = inventory.getItemInOffHand();
if (offHand.getType() == Material.FISHING_ROD){
CustomFishing.plugin.getIntegrationManager().loseCustomDurability(offHand, player);
}
}
}, 1);
}
private void fail(Player player, Loot loot, boolean isVanilla) {
FishResultEvent fishResultEvent = new FishResultEvent(player, FishResult.FAILURE, false, null, "null");
Bukkit.getServer().getPluginManager().callEvent(fishResultEvent);
if (fishResultEvent.isCancelled()) {
return;
}
if (!isVanilla && loot != null){
for (ActionInterface action : loot.getFailureActions())
action.doOn(player, null);
}
nextBonus.remove(player);
AdventureUtil.playerTitle(
player,
ConfigManager.failureTitle[new Random().nextInt(ConfigManager.failureTitle.length)],
ConfigManager.failureSubTitle[new Random().nextInt(ConfigManager.failureSubTitle.length)],
ConfigManager.failureFadeIn,
ConfigManager.failureFadeStay,
ConfigManager.failureFadeOut
);
}
public void onCaughtEntity(PlayerFishEvent event) {
final Player player = event.getPlayer();
FishingPlayer fishingPlayer = fishingPlayerCache.remove(player);
if (fishingPlayer != null) {
Entity entity = event.getCaught();
if (entity != null && entity.getType() == EntityType.ARMOR_STAND) {
proceedReelIn(event, player, fishingPlayer);
}
else {
fishingPlayer.cancel();
nextBonus.remove(player);
nextLoot.remove(player);
AdventureUtil.playerMessage(player, MessageManager.prefix + MessageManager.hookOther);
}
}
}
public void onFailedAttempt(PlayerFishEvent event) {
//Empty
}
public void onBite(PlayerFishEvent event) {
if (ConfigManager.disableBar) return;
if (!ConfigManager.instantBar) return;
final Player player = event.getPlayer();
showBar(player);
}
public void showBar(Player player) {
if (fishingPlayerCache.get(player) != null) return;
Loot loot = nextLoot.get(player);
if (loot != null) {
if (loot == Loot.EMPTY) return;
showPlayerBar(player, loot);
}
}
public void onInGround(PlayerFishEvent event) {
//Empty
}
public void onMMOItemsRodCast(PlayerFishEvent event) {
final Player player = event.getPlayer();
if (isCoolDown(player, 5000)) return;
PlayerInventory inventory = player.getInventory();
setCustomTag(inventory.getItemInMainHand());
setCustomTag(inventory.getItemInOffHand());
}
private void setCustomTag(ItemStack itemStack) {
if(itemStack.getType() != Material.FISHING_ROD) return;
NBTItem nbtItem = new NBTItem(itemStack);
if (nbtItem.getCompound("CustomFishing") != null) return;
if (!nbtItem.hasKey("MMOITEMS_ITEM_ID")) return;
ItemStackUtil.addIdentifier(itemStack, "rod", nbtItem.getString("MMOITEMS_ITEM_ID"));
}
public boolean isCoolDown(Player player, long delay) {
long time = System.currentTimeMillis();
if (time - (coolDown.getOrDefault(player, time - delay)) < delay) return true;
coolDown.put(player, time);
return false;
}
private void enchantBonus(Bonus initialBonus, ItemStack itemStack) {
Map<Enchantment, Integer> enchantments = itemStack.getEnchantments();
for (Map.Entry<Enchantment, Integer> en : enchantments.entrySet()) {
String key = en.getKey().getKey() + ":" + en.getValue();
Bonus enchantBonus = BonusManager.ENCHANTS.get(key);
if (enchantBonus != null) {
initialBonus.addBonus(enchantBonus);
}
}
}
public List<Loot> getPossibleLootList(FishingCondition fishingCondition, boolean finder, Collection<Loot> values) {
List<Loot> available = new ArrayList<>();
outer:
for (Loot loot : values) {
if (finder && !loot.isShowInFinder()) continue;
RequirementInterface[] requirements = loot.getRequirements();
if (requirements == null){
available.add(loot);
}
else {
for (RequirementInterface requirement : requirements){
if (!requirement.isConditionMet(fishingCondition)){
continue outer;
}
}
available.add(loot);
}
}
return available;
}
@Override
public void onInteract(PlayerInteractEvent event) {
ItemStack itemStack = event.getItem();
final Player player = event.getPlayer();
if (itemStack == null || itemStack.getType() == Material.AIR) return;
NBTItem nbtItem = new NBTItem(itemStack);
NBTCompound cfCompound = nbtItem.getCompound("CustomFishing");
if (cfCompound != null && cfCompound.getString("type").equals("util") && cfCompound.getString("id").equals("fishfinder")) {
if (isCoolDown(player, 1000)) return;
useFinder(event.getPlayer());
return;
}
Block block = event.getClickedBlock();
if (block == null) return;
String totemID = nbtItem.getString("Totem");
if (totemID.equals("")) return;
Totem totem = TotemManager.TOTEMS.get(totemID);
if (totem == null) return;
if (isCoolDown(player, 1000)) return;
String blockID = CustomFishing.plugin.getIntegrationManager().getBlockInterface().getID(block);
if (blockID == null) return;
List<Totem> totemList = TotemManager.CORES.get(blockID);
if (totemList == null || !totemList.contains(totem)) return;
Location coreLoc = block.getLocation();
int type = CustomFishing.plugin.getTotemManager().checkLocationModel(totem.getOriginalModel(), coreLoc);
if (type == 0) return;
if (!AntiGriefInterface.testBreak(player, coreLoc)) return;
TotemActivationEvent totemActivationEvent = new TotemActivationEvent(player, coreLoc, totem);
Bukkit.getPluginManager().callEvent(totemActivationEvent);
if (totemActivationEvent.isCancelled()) {
return;
}
if (totemCache.get(coreLoc) != null) {
totemCache.get(coreLoc).stop();
}
CustomFishing.plugin.getTotemManager().removeModel(totem.getFinalModel(), coreLoc, type);
if (player.getGameMode() != GameMode.CREATIVE) itemStack.setAmount(itemStack.getAmount() - 1);
for (ActionInterface action : totem.getActivatorActions()) {
action.doOn(player, null);
}
for (ActionInterface action : totem.getNearbyActions()) {
for (Player nearby : coreLoc.getNearbyPlayers(totem.getRadius())) {
action.doOn(nearby, player);
}
}
Location bottomLoc = coreLoc.clone().subtract(0, totem.getOriginalModel().getCorePos().getY(), 0);
ActivatedTotem activatedTotem = new ActivatedTotem(bottomLoc, totem, this);
activatedTotem.runTaskTimer(CustomFishing.plugin, 10, 20);
totemCache.put(bottomLoc, activatedTotem);
}
private void useFinder(Player player) {
FishingCondition fishingCondition = new FishingCondition(player.getLocation(), player);
List<Loot> possibleLoots = getPossibleLootList(fishingCondition, true, LootManager.WATERLOOTS.values());
possibleLoots.addAll(getPossibleLootList(fishingCondition, true, LootManager.LAVALOOTS.values()));
FishFinderEvent fishFinderEvent = new FishFinderEvent(player, possibleLoots);
Bukkit.getPluginManager().callEvent(fishFinderEvent);
if (fishFinderEvent.isCancelled()) {
return;
}
if (possibleLoots.size() == 0) {
AdventureUtil.playerMessage(player, MessageManager.prefix + MessageManager.noLoot);
return;
}
StringBuilder stringBuilder = new StringBuilder(MessageManager.prefix + MessageManager.possibleLoots);
possibleLoots.forEach(loot -> stringBuilder.append(loot.getNick()).append(MessageManager.splitChar));
AdventureUtil.playerMessage(player, stringBuilder.substring(0, stringBuilder.length() - MessageManager.splitChar.length()));
}
private void showPlayerBar(Player player, @Nullable Loot loot){
Layout layout;
if (loot != null && loot.getLayout() != null){
layout = loot.getLayout()[new Random().nextInt(loot.getLayout().length)];
}
else {
layout = (Layout) LayoutManager.LAYOUTS.values().stream().toArray()[new Random().nextInt(LayoutManager.LAYOUTS.values().size())];
}
int speed;
int timer;
int time;
if (loot != null){
Difficulty difficulty = loot.getDifficulty()[new Random().nextInt(loot.getDifficulty().length)];
speed = difficulty.speed();
timer = difficulty.timer();
time = loot.getTime();
}
else {
speed = new Random().nextInt(5);
time = 10000;
timer = 1;
}
Bonus bonus = nextBonus.get(player);
boolean isDouble = false;
double scoreMultiplier = 0;
if (bonus != null) {
speed += bonus.getDifficulty();
isDouble = Math.random() < bonus.getDoubleLoot();
scoreMultiplier = bonus.getScore() + 1;
}
if (speed < 1){
speed = 1;
}
Difficulty difficult = new Difficulty(timer, speed);
FishHookEvent fishHookEvent = new FishHookEvent(player, difficult);
Bukkit.getPluginManager().callEvent(fishHookEvent);
if (fishHookEvent.isCancelled()) {
return;
}
FishingPlayer fishingPlayer = new FishingPlayer(System.currentTimeMillis() + time, player, layout, difficult, this, isDouble, scoreMultiplier);
fishingPlayer.runTaskTimerAsynchronously(CustomFishing.plugin, 0, 1);
fishingPlayerCache.put(player, fishingPlayer);
if (vanillaLoot.get(player) == null && loot != null){
for (ActionInterface action : loot.getHookActions()) {
action.doOn(player, null);
}
}
player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, time/50,3));
}
@Override
public void onQuit(Player player) {
coolDown.remove(player);
nextLoot.remove(player);
nextBonus.remove(player);
vanillaLoot.remove(player);
BobberCheckTask task = bobberTaskCache.remove(player);
if (task != null) task.stop();
// prevent bar duplication
FishHook fishHook = hooksCache.remove(player);
if (fishHook != null) fishHook.remove();
}
@Nullable
public FishingPlayer getFishingPlayer(Player player) {
return fishingPlayerCache.get(player);
}
public void removeFishingPlayer(Player player) {
fishingPlayerCache.remove(player);
}
private Component getDisplayName(ItemStack itemStack){
NBTItem nbtItem = new NBTItem(itemStack);
NBTCompound nbtCompound = nbtItem.getCompound("display");
if (nbtCompound != null){
String name = nbtCompound.getString("Name");
if (!name.equals("")){
return GsonComponentSerializer.gson().deserialize(name);
}
}
String type = itemStack.getType().toString().toLowerCase();
if (itemStack.getType().isBlock()) return GsonComponentSerializer.gson().deserialize("{\"translate\":\"block.minecraft." + type + "\"}");
else return GsonComponentSerializer.gson().deserialize("{\"translate\":\"item.minecraft." + type + "\"}");
}
public void removeTotem(Location location) {
totemCache.remove(location);
}
public void addPlayerToLavaFishing(Player player, BobberCheckTask task) {
this.bobberTaskCache.put(player, task);
}
public void removePlayerFromLavaFishing(Player player) {
this.bobberTaskCache.remove(player);
}
}