diff --git a/build.gradle b/build.gradle index 1aecb3c6..2123a587 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group = 'net.momirealms' -version = '1.1.0' +version = '1.1.3' repositories { mavenCentral() @@ -44,21 +44,22 @@ repositories { dependencies { compileOnly fileTree(dir:'libs',includes:['*.jar']) - compileOnly 'io.papermc.paper:paper-api:1.17.1-R0.1-SNAPSHOT' + compileOnly('io.papermc.paper:paper-api:1.17.1-R0.1-SNAPSHOT') compileOnly('com.github.Archy-X:AureliumSkills:Beta1.3.6') compileOnly('redis.clients:jedis:4.2.3') compileOnly('me.clip:placeholderapi:2.11.1') compileOnly('com.sk89q.worldguard:worldguard-bukkit:7.0.7') compileOnly('io.lumine:Mythic-Dist:5.0.3-SNAPSHOT') compileOnly('dev.dejvokep:boosted-yaml:1.3') + compileOnly('com.willfp:EcoSkills:1.72.0') + compileOnly('com.willfp:eco:6.38.3') + compileOnly('com.github.Zrips:Jobs:4.17.2') compileOnly('com.github.LoneDev6:api-itemsadder:3.2.3c') implementation('net.kyori:adventure-api:4.11.0') implementation('net.kyori:adventure-platform-bukkit:4.1.2') implementation('net.kyori:adventure-text-minimessage:4.11.0') implementation('net.kyori:adventure-text-serializer-legacy:4.11.0') implementation('de.tr7zw:item-nbt-api:2.10.0') - compileOnly('com.willfp:EcoSkills:1.72.0') - compileOnly('com.willfp:eco:6.38.3') } def targetJavaVersion = 16 diff --git a/src/main/java/net/momirealms/customfishing/ConfigReader.java b/src/main/java/net/momirealms/customfishing/ConfigReader.java index 98924f3b..08dec3b6 100644 --- a/src/main/java/net/momirealms/customfishing/ConfigReader.java +++ b/src/main/java/net/momirealms/customfishing/ConfigReader.java @@ -103,6 +103,8 @@ public class ConfigReader{ public static boolean showBar; public static boolean mcMMOLoot; public static boolean hasWhitelist; + public static boolean needRodFishing; + public static boolean disableJobXp; public static int fishFinderCoolDown; public static double timeMultiply; public static double vanillaRatio; @@ -169,6 +171,13 @@ public class ConfigReader{ AdventureUtil.consoleMessage("[CustomFishing] EcoSkills Hooked!"); } } + if(config.getBoolean("config.integrations.JobsReborn",false)){ + if (Bukkit.getPluginManager().getPlugin("Jobs") == null) CustomFishing.instance.getLogger().warning("Failed to initialize JobsReborn!"); + else { + skillXP = new JobsReborn(); + AdventureUtil.consoleMessage("[CustomFishing] JobsReborn Hooked!"); + } + } season = null; if (config.getBoolean("config.integrations.RealisticSeasons",false)){ @@ -199,7 +208,9 @@ public class ConfigReader{ convertMMOItems = config.getBoolean("config.convert-MMOITEMS", false); needOpenWater = config.getBoolean("config.need-open-water", false); - needSpecialRod = config.getBoolean("config.need-special-rod", false); + needSpecialRod = config.getBoolean("config.need-special-rod.for-loots", false); + needRodFishing = config.getBoolean("config.need-special-rod.to-fish", false); + loseDurability = config.getBoolean("config.rod-lose-durability", true); preventPick = config.getBoolean("config.prevent-other-players-pick-up-loot", false); @@ -208,6 +219,7 @@ public class ConfigReader{ timeMultiply = config.getDouble("config.time-multiply"); lang = config.getString("config.lang","cn"); competition = config.getBoolean("config.fishing-competition",true); + disableJobXp = config.getBoolean("config.disable-JobsReborn-fishing-exp",false); hasWhitelist = config.getBoolean("config.whitelist-worlds.enable",false); @@ -362,7 +374,8 @@ public class ConfigReader{ loot.setDifficulty(difficulty); loot.setTime(time); loot.setWeight(weight); - loot.setNick(config.getString(key + ".nick", key)); + if (config.contains(key + ".nick")) loot.setNick(config.getString(key + ".nick")); + else loot.setNick(config.getString(key + ".display.name", key)); loot.setScore(config.getDouble(key + ".score",0)); loot.setShowInFinder(config.getBoolean(key + ".show-in-fishfinder", true)); loot.setRandomDurability(config.getBoolean(key + ".random-durability", false)); @@ -549,7 +562,8 @@ public class ConfigReader{ loot.setDifficulty(difficulty); loot.setTime(time); loot.setWeight(weight); - loot.setNick(config.getString(key + ".name", key)); + if (config.contains(key + ".nick")) loot.setNick(config.getString(key + ".nick")); + else loot.setNick(config.getString(key + ".display.name", key)); loot.setScore(config.getDouble(key + ".score",0)); loot.setShowInFinder(config.getBoolean(key + ".show-in-fishfinder", true)); loot.setMmLevel(config.getInt(key + ".level", 0)); diff --git a/src/main/java/net/momirealms/customfishing/CustomFishing.java b/src/main/java/net/momirealms/customfishing/CustomFishing.java index ccc737d5..4f97549a 100644 --- a/src/main/java/net/momirealms/customfishing/CustomFishing.java +++ b/src/main/java/net/momirealms/customfishing/CustomFishing.java @@ -25,6 +25,7 @@ import net.momirealms.customfishing.competition.CompetitionSchedule; import net.momirealms.customfishing.competition.bossbar.BossBarManager; import net.momirealms.customfishing.helper.LibraryLoader; import net.momirealms.customfishing.hook.Placeholders; +import net.momirealms.customfishing.hook.skill.JobsReborn; import net.momirealms.customfishing.listener.*; import net.momirealms.customfishing.utils.AdventureUtil; import net.momirealms.customfishing.utils.ConfigUtil; @@ -51,6 +52,7 @@ public final class CustomFishing extends JavaPlugin { @Override public void onEnable() { + adventure = BukkitAudiences.create(this); miniMessage = MiniMessage.miniMessage(); Objects.requireNonNull(Bukkit.getPluginCommand("customfishing")).setExecutor(new Execute()); @@ -62,18 +64,13 @@ public final class CustomFishing extends JavaPlugin { Bukkit.getScheduler().runTaskAsynchronously(this, ()-> { ConfigReader.Reload(); + if (ConfigReader.Config.competition){ competitionSchedule = new CompetitionSchedule(); competitionSchedule.checkTime(); - Bukkit.getScheduler().runTask(this, () -> { - Bukkit.getPluginManager().registerEvents(new BossBarManager(), this); - }); - } - if (ConfigReader.Config.convertMMOItems){ - Bukkit.getScheduler().runTask(this, () -> { - Bukkit.getPluginManager().registerEvents(new MMOItemsConverter(), this); - }); + Bukkit.getScheduler().runTask(this, () -> Bukkit.getPluginManager().registerEvents(new BossBarManager(), this)); } + if (ConfigReader.Config.papi){ placeholders = new Placeholders(); Bukkit.getScheduler().runTask(this, () -> { @@ -81,15 +78,18 @@ public final class CustomFishing extends JavaPlugin { Bukkit.getPluginManager().registerEvents(new PapiUnregister(), this); }); } - if (ConfigReader.Config.preventPick){ - Bukkit.getScheduler().runTask(this, () -> { - Bukkit.getPluginManager().registerEvents(new PickUpListener(),this); - }); - } - if (!Objects.equals(ConfigReader.Config.version, "7")){ + + if (ConfigReader.Config.preventPick) + Bukkit.getScheduler().runTask(this, () -> Bukkit.getPluginManager().registerEvents(new PickUpListener(),this)); + if (!Objects.equals(ConfigReader.Config.version, "8")) ConfigUtil.update(); - } + if (ConfigReader.Config.convertMMOItems) + Bukkit.getScheduler().runTask(this, () -> Bukkit.getPluginManager().registerEvents(new MMOItemsListener(), this)); + if (ConfigReader.Config.disableJobXp) + Bukkit.getScheduler().runTask(this, () -> Bukkit.getPluginManager().registerEvents(new JobsListener(), this)); + ConfigReader.tryEnableJedis(); + AdventureUtil.consoleMessage("[CustomFishing] Plugin Enabled!"); }); } diff --git a/src/main/java/net/momirealms/customfishing/hook/skill/JobsReborn.java b/src/main/java/net/momirealms/customfishing/hook/skill/JobsReborn.java new file mode 100644 index 00000000..9cc31eec --- /dev/null +++ b/src/main/java/net/momirealms/customfishing/hook/skill/JobsReborn.java @@ -0,0 +1,44 @@ +package net.momirealms.customfishing.hook.skill; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.container.Job; +import com.gamingmesh.jobs.container.JobProgression; +import com.gamingmesh.jobs.container.JobsPlayer; +import org.bukkit.entity.Player; + +import java.util.List; + +public class JobsReborn implements SkillXP{ + + @Override + public void addXp(Player player, double amount) { + JobsPlayer jobsPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + + if (jobsPlayer != null) { + List jobs = jobsPlayer.getJobProgression(); + + Job job = Jobs.getJob("Fisherman"); + + for (JobProgression progression : jobs) + if (progression.getJob().equals(job)){ + progression.addExperience(amount); + } + } + } + + @Override + public int getLevel(Player player) { + JobsPlayer jobsPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + + if (jobsPlayer != null) { + List jobs = jobsPlayer.getJobProgression(); + + Job job = Jobs.getJob("Fisherman"); + + for (JobProgression progression : jobs) + if (progression.getJob().equals(job)) + return progression.getLevel(); + } + return 0; + } +} diff --git a/src/main/java/net/momirealms/customfishing/listener/FishListener.java b/src/main/java/net/momirealms/customfishing/listener/FishListener.java index 0d642dfd..7f1d643e 100644 --- a/src/main/java/net/momirealms/customfishing/listener/FishListener.java +++ b/src/main/java/net/momirealms/customfishing/listener/FishListener.java @@ -328,12 +328,6 @@ public class FishListener implements Listener { } } - if (ConfigReader.Config.needSpecialRod && noSpecialRod){ - if (!ConfigReader.Config.vanillaLoot) - AdventureUtil.playerMessage(player, ConfigReader.Message.prefix + ConfigReader.Message.noRod); - nextLoot.put(player, null); - } - FishHook hook = event.getHook(); hook.setMaxWaitTime((int) (timeModifier * hook.getMaxWaitTime())); hook.setMinWaitTime((int) (timeModifier * hook.getMinWaitTime())); @@ -352,6 +346,18 @@ public class FishListener implements Listener { return; } + if (ConfigReader.Config.needSpecialRod && noSpecialRod){ + if (!ConfigReader.Config.vanillaLoot) + AdventureUtil.playerMessage(player, ConfigReader.Message.prefix + ConfigReader.Message.noRod); + nextLoot.put(player, null); + } + + if (ConfigReader.Config.needRodFishing && noSpecialRod){ + nextLoot.put(player, new Loot("none")); + } + + if ((ConfigReader.Config.needSpecialRod || ConfigReader.Config.needRodFishing) && noSpecialRod) return; + double[] weights = new double[possibleLoots.size()]; int index = 0; for (Loot loot : possibleLoots){ @@ -400,14 +406,19 @@ public class FishListener implements Listener { }); } case CAUGHT_FISH -> { + + if (ConfigReader.Config.needRodFishing && nextLoot.get(player) != null && nextLoot.get(player).getKey().equals("none")){ + return; + } //是否需要两次拉杆 if (ConfigReader.Config.doubleRealIn) { FishingPlayer fishingPlayer = fishingPlayers.remove(player); + Entity entity = event.getCaught(); + if (fishingPlayer == null){ - Entity entity = event.getCaught(); if (entity instanceof Item item){ //是否有原版战利品 if (ConfigReader.Config.vanillaLoot) { @@ -447,7 +458,6 @@ public class FishListener implements Listener { } else { - Entity entity = event.getCaught(); if (entity instanceof Item item){ item.remove(); event.setExpToDrop(0); @@ -503,6 +513,7 @@ public class FishListener implements Listener { //如果玩家正在钓鱼 //那么拉杆的时候可能也会遇到上钩点,进行正常收杆判断 FishingPlayer fishingPlayer = fishingPlayers.remove(player); + if (fishingPlayer != null){ item.remove(); @@ -579,6 +590,7 @@ public class FishListener implements Listener { } } case REEL_IN -> { + FishingPlayer fishingPlayer = fishingPlayers.remove(player); //首先得是钓鱼中的玩家 if (fishingPlayer != null){ @@ -649,6 +661,7 @@ public class FishListener implements Listener { } } case BITE -> { + if (ConfigReader.Config.doubleRealIn) return; if (fishingPlayers.get(player) != null) return; @@ -657,6 +670,10 @@ public class FishListener implements Listener { if (loot == null) return; + if (ConfigReader.Config.needRodFishing && loot.getKey().equals("none")){ + return; + } + String layout; if (loot.getLayout() != null){ layout = loot.getLayout().get((int) (loot.getLayout().size() * Math.random())); diff --git a/src/main/java/net/momirealms/customfishing/listener/JobsListener.java b/src/main/java/net/momirealms/customfishing/listener/JobsListener.java new file mode 100644 index 00000000..a7e59331 --- /dev/null +++ b/src/main/java/net/momirealms/customfishing/listener/JobsListener.java @@ -0,0 +1,18 @@ +package net.momirealms.customfishing.listener; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.api.JobsExpGainEvent; +import com.gamingmesh.jobs.container.Job; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class JobsListener implements Listener { + + @EventHandler + public void onExpAdd(JobsExpGainEvent event){ + Job job = Jobs.getJob("Fisherman"); + if (event.getJob().equals(job)){ + event.setExp(0); + } + } +} diff --git a/src/main/java/net/momirealms/customfishing/listener/MMOItemsListener.java b/src/main/java/net/momirealms/customfishing/listener/MMOItemsListener.java new file mode 100644 index 00000000..ea88c302 --- /dev/null +++ b/src/main/java/net/momirealms/customfishing/listener/MMOItemsListener.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) <2022> + * + * 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 . + */ + +package net.momirealms.customfishing.listener; + +import de.tr7zw.changeme.nbtapi.NBTCompound; +import de.tr7zw.changeme.nbtapi.NBTItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerFishEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; + +import java.util.HashMap; + +public class MMOItemsListener implements Listener { + + private final HashMap coolDown = new HashMap<>(); + + @EventHandler + public void onFish(PlayerFishEvent event){ + + if (event.getState() == PlayerFishEvent.State.FISHING){ + + Player player = event.getPlayer(); + + long time = System.currentTimeMillis(); + if (time - (coolDown.getOrDefault(player, time - 5000)) < 5000) { + return; + } + coolDown.put(player, time); + + PlayerInventory inventory = player.getInventory(); + + ItemStack mainHand = inventory.getItemInMainHand(); + if(mainHand.getType() == Material.FISHING_ROD){ + NBTItem nbtItem = new NBTItem(mainHand); + if (nbtItem.getCompound("CustomFishing") == null) { + if (!nbtItem.getString("MMOITEMS_ITEM_ID").equals("")){ + NBTCompound nbtCompound = nbtItem.addCompound("CustomFishing"); + nbtCompound.setString("type","rod"); + nbtCompound.setString("id",nbtItem.getString("MMOITEMS_ITEM_ID")); + mainHand.setItemMeta(nbtItem.getItem().getItemMeta()); + } + } + } + + ItemStack offHand = inventory.getItemInOffHand(); + if(offHand.getType() == Material.FISHING_ROD){ + NBTItem nbtItem = new NBTItem(offHand); + if (nbtItem.getCompound("CustomFishing") == null) { + if (!nbtItem.getString("MMOITEMS_ITEM_ID").equals("")){ + NBTCompound nbtCompound = nbtItem.addCompound("CustomFishing"); + nbtCompound.setString("type", "rod"); + nbtCompound.setString("id", nbtItem.getString("MMOITEMS_ITEM_ID")); + offHand.setItemMeta(nbtItem.getItem().getItemMeta()); + } + } + } + } + } + + @EventHandler + public void onQuit(PlayerQuitEvent event){ + coolDown.remove(event.getPlayer()); + } +} diff --git a/src/main/java/net/momirealms/customfishing/requirements/CustomPapi.java b/src/main/java/net/momirealms/customfishing/requirements/CustomPapi.java index ffae01c6..8124c46a 100644 --- a/src/main/java/net/momirealms/customfishing/requirements/CustomPapi.java +++ b/src/main/java/net/momirealms/customfishing/requirements/CustomPapi.java @@ -33,6 +33,7 @@ public class CustomPapi implements Requirement { allPapi.add(papi); switch (type){ case "==" -> papiRequirement = new PapiEquals(papi, value); + case "!=" -> papiRequirement = new PapiNotEquals(papi, value); case ">=" -> papiRequirement = new PapiNoLess(papi, Double.parseDouble(value)); case "<=" -> papiRequirement = new PapiNoLarger(papi, Double.parseDouble(value)); case "<" -> papiRequirement = new PapiSmaller(papi, Double.parseDouble(value)); @@ -67,6 +68,7 @@ public class CustomPapi implements Requirement { allPapi.add(papi); switch (type){ case "==" -> andRequirements.add(new PapiEquals(papi, value)); + case "!=" -> andRequirements.add(new PapiNotEquals(papi, value)); case ">=" -> andRequirements.add(new PapiNoLess(papi, Double.parseDouble(value))); case "<=" -> andRequirements.add(new PapiNoLarger(papi, Double.parseDouble(value))); case "<" -> andRequirements.add(new PapiSmaller(papi, Double.parseDouble(value))); @@ -97,6 +99,7 @@ public class CustomPapi implements Requirement { allPapi.add(papi); switch (type){ case "==" -> orRequirements.add(new PapiEquals(papi, value)); + case "!=" -> orRequirements.add(new PapiNotEquals(papi, value)); case ">=" -> orRequirements.add(new PapiNoLess(papi, Double.parseDouble(value))); case "<=" -> orRequirements.add(new PapiNoLarger(papi, Double.parseDouble(value))); case "<" -> orRequirements.add(new PapiSmaller(papi, Double.parseDouble(value))); diff --git a/src/main/java/net/momirealms/customfishing/requirements/papi/PapiNotEquals.java b/src/main/java/net/momirealms/customfishing/requirements/papi/PapiNotEquals.java new file mode 100644 index 00000000..5cf45bff --- /dev/null +++ b/src/main/java/net/momirealms/customfishing/requirements/papi/PapiNotEquals.java @@ -0,0 +1,13 @@ +package net.momirealms.customfishing.requirements.papi; + +import java.util.HashMap; +import java.util.Objects; + +public record PapiNotEquals(String papi, String requirement) implements PapiRequirement{ + + @Override + public boolean isMet(HashMap papiMap) { + String value = papiMap.get(papi); + return !Objects.equals(value, requirement); + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customfishing/titlebar/TimerTask.java b/src/main/java/net/momirealms/customfishing/titlebar/TimerTask.java index 8c6b527f..6084cd00 100644 --- a/src/main/java/net/momirealms/customfishing/titlebar/TimerTask.java +++ b/src/main/java/net/momirealms/customfishing/titlebar/TimerTask.java @@ -88,6 +88,7 @@ public class TimerTask extends BukkitRunnable { bukkitScheduler.cancelTask(taskID); return; } + int timer = difficulty.getTimer() - 1; int speed = difficulty.getSpeed(); //设置指针方向 @@ -119,7 +120,7 @@ public class TimerTask extends BukkitRunnable { } } stringBuilder.append(end); - AdventureUtil.playerTitle(player, title, stringBuilder.toString(),0,300,0); + AdventureUtil.playerTitle(player, title, stringBuilder.toString(),0,500,0); //移除切换物品的玩家 PlayerInventory playerInventory = player.getInventory(); if (playerInventory.getItemInMainHand().getType() != Material.FISHING_ROD && playerInventory.getItemInOffHand().getType() != Material.FISHING_ROD){ diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 96f801c2..57735213 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,5 +1,5 @@ # don't change -config-version: '7' +config-version: '8' config: #en/es/cn @@ -13,12 +13,14 @@ config: # Papi hook PlaceholderAPI: true # Skill xp hook - # If skill xp is added not as expected - # Check the xp-source file in those skill plugins and set them to 0 + # If skill xp is added not as expected please check if you have set skill-xp for each loot + # Some plugins like AureliumSkills will still add skill-xp when player failed to fish. Check the xp-source file in those skill plugins and set them to 0 mcMMO: false MMOCore: false AureliumSkills: false EcoSkills: false + # You need a restart to cancel the Jobs xp getting in vanilla way + JobsReborn: false # Season hook CustomCrops: false RealisticSeasons: false @@ -54,8 +56,12 @@ config: # https://technical-minecraft.fandom.com/wiki/Fishing need-open-water: true - # Players must use rods with CustomFishing's NBT Tags to get loots in CustomFishing - need-special-rod: false + need-special-rod: + # if set true and "double-reel-in" is true, players must use rods with CustomFishing's NBT Tags to get loots in CustomFishing but they can experience the special fishing mechanic. + # This option will not work if "double-reel-in" is false because in that mode no vanilla loots are available + for-loots: false + # if set true and "double-reel-in" is true, players must use rods with CustomFishing's NBT Tags to experience the special fishing mechanic. Otherwise they can only fish in a vanilla way + to-fish: false # does rod lose durability when player successfully fish rod-lose-durability: true @@ -79,4 +85,7 @@ config: # If there's a plugin conflict, event priority sometimes works # HIGHEST NORMAL LOWEST - event-priority: NORMAL \ No newline at end of file + event-priority: NORMAL + + # If enabled, players would not be able to get job exp in vanilla way (Requires a restart) + disable-JobsReborn-fishing-exp: false \ No newline at end of file diff --git a/src/main/resources/loots/example.yml b/src/main/resources/loots/example.yml index 2e5ef01f..8aec1e5d 100644 --- a/src/main/resources/loots/example.yml +++ b/src/main/resources/loots/example.yml @@ -3,7 +3,7 @@ rainbow_fish: # Enable enable: false - # Nick is what to show in fish finder + # Nick is what to show in fish finder and titles nick: 'Example Fish' # Should it be displayed in fish finder? show-in-fishfinder: false @@ -60,7 +60,7 @@ rainbow_fish: # Exp that would apply to mending mending: 5 # Fishing Skill xp (requires skill plugin hook) - #skill-xp: 100 + skill-xp: 100 failure: message: - 'The fish escaped!' @@ -163,6 +163,7 @@ rainbow_fish: #Create complex condition as you want # "||" means one of the conditions is true, it would be true # "&&" means all the conditions must be true to be true + # available types "==" "!=" ">" "<" ">=" "<=" papi-condition: '||': condition_1: diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 31ab458b..caa715cd 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -18,6 +18,7 @@ softdepend: - Oraxen - MMOItems - eco + - Jobs commands: customfishing: usage: /customfishing