diff --git a/api/src/main/java/net/momirealms/customcrops/api/event/CropBreakEvent.java b/api/src/main/java/net/momirealms/customcrops/api/event/CropBreakEvent.java index 5ef5117..088347b 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/event/CropBreakEvent.java +++ b/api/src/main/java/net/momirealms/customcrops/api/event/CropBreakEvent.java @@ -151,7 +151,7 @@ public class CropBreakEvent extends Event implements Cancellable { * * @return the block state before breakage, or null if not applicable. */ - @Nullable + @NotNull public CustomCropsBlockState getBlockState() { return blockState; } diff --git a/compatibility/libs/ClueScrolls-4.8.7-api.jar b/compatibility/libs/ClueScrolls-4.8.7-api.jar new file mode 100644 index 0000000..783c6ff Binary files /dev/null and b/compatibility/libs/ClueScrolls-4.8.7-api.jar differ diff --git a/compatibility/libs/ClueScrolls-api.jar b/compatibility/libs/ClueScrolls-api.jar deleted file mode 100644 index 38234c6..0000000 Binary files a/compatibility/libs/ClueScrolls-api.jar and /dev/null differ diff --git a/compatibility/src/main/java/net/momirealms/customcrops/bukkit/integration/quest/BattlePassQuest.java b/compatibility/src/main/java/net/momirealms/customcrops/bukkit/integration/quest/BattlePassQuest.java new file mode 100644 index 0000000..43d3a14 --- /dev/null +++ b/compatibility/src/main/java/net/momirealms/customcrops/bukkit/integration/quest/BattlePassQuest.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) <2024> + * + * 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.customcrops.bukkit.integration.quest; + +import io.github.battlepass.BattlePlugin; +import io.github.battlepass.api.events.server.PluginReloadEvent; +import net.advancedplugins.bp.impl.actions.ActionRegistry; +import net.advancedplugins.bp.impl.actions.external.executor.ActionQuestExecutor; +import net.momirealms.customcrops.api.BukkitCustomCropsPlugin; +import net.momirealms.customcrops.api.event.CropBreakEvent; +import net.momirealms.customcrops.api.event.CropPlantEvent; +import org.bukkit.Bukkit; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.plugin.java.JavaPlugin; + +public class BattlePassQuest implements Listener { + + public BattlePassQuest() { + Bukkit.getPluginManager().registerEvents(this, BukkitCustomCropsPlugin.getInstance().getBoostrap()); + } + + public void register() { + ActionRegistry actionRegistry = BattlePlugin.getPlugin().getActionRegistry(); + actionRegistry.hook("customcrops", BPCropsQuest::new); + } + + @EventHandler(ignoreCancelled = true) + public void onBattlePassReload(PluginReloadEvent event){ + register(); + } + + @SuppressWarnings("deprecation") + private static class BPCropsQuest extends ActionQuestExecutor { + public BPCropsQuest(JavaPlugin plugin) { + super(plugin, "customcrops"); + } + + @EventHandler (ignoreCancelled = true) + public void onBreakCrop(CropBreakEvent event) { + Entity entity = event.getEntityBreaker(); + if (!(entity instanceof Player player)) return; + String id = event.getStageItemID(); + // remove namespace + if (id.contains(":")) { + id = id.split(":")[1]; + } + // Harvest crops + this.executionBuilder("harvest") + .player(player) + .root(id) + .progress(1) + .buildAndExecute(); + } + + @EventHandler (ignoreCancelled = true) + public void onPlantCrop(CropPlantEvent event){ + Player player = event.getPlayer(); + // Plant crops + this.executionBuilder("plant") + .player(player) + .root(event.getCropConfig().id()) + .progress(1) + .buildAndExecute(); + } + } +} diff --git a/compatibility/src/main/java/net/momirealms/customcrops/bukkit/integration/quest/BetonQuestQuest.java b/compatibility/src/main/java/net/momirealms/customcrops/bukkit/integration/quest/BetonQuestQuest.java new file mode 100644 index 0000000..793a4f0 --- /dev/null +++ b/compatibility/src/main/java/net/momirealms/customcrops/bukkit/integration/quest/BetonQuestQuest.java @@ -0,0 +1,195 @@ +/* + * Copyright (C) <2024> + * + * 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.customcrops.bukkit.integration.quest; + +import net.momirealms.customcrops.api.event.CropBreakEvent; +import net.momirealms.customcrops.api.event.CropPlantEvent; +import org.betonquest.betonquest.BetonQuest; +import org.betonquest.betonquest.Instruction; +import org.betonquest.betonquest.api.CountingObjective; +import org.betonquest.betonquest.api.config.quest.QuestPackage; +import org.betonquest.betonquest.api.profiles.OnlineProfile; +import org.betonquest.betonquest.api.profiles.Profile; +import org.betonquest.betonquest.exceptions.InstructionParseException; +import org.betonquest.betonquest.exceptions.QuestRuntimeException; +import org.betonquest.betonquest.instruction.variable.VariableNumber; +import org.betonquest.betonquest.instruction.variable.location.VariableLocation; +import org.betonquest.betonquest.utils.PlayerConverter; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; + +import java.util.Collections; +import java.util.HashSet; + +@SuppressWarnings("DuplicatedCode") +public class BetonQuestQuest { + + public static void register() { + BetonQuest.getInstance().registerObjectives("customcrops_harvest", HarvestObjective.class); + BetonQuest.getInstance().registerObjectives("customcrops_plant", PlantObjective.class); + } + + public static class HarvestObjective extends CountingObjective implements Listener { + + private final VariableLocation playerLocation; + private final VariableNumber rangeVar; + private final HashSet crop_ids; + + public HarvestObjective(Instruction instruction) throws InstructionParseException { + super(instruction, "crop_to_harvest"); + crop_ids = new HashSet<>(); + Collections.addAll(crop_ids, instruction.getArray()); + targetAmount = instruction.getVarNum(VariableNumber.NOT_LESS_THAN_ONE_CHECKER); + final QuestPackage pack = instruction.getPackage(); + final String loc = instruction.getOptional("playerLocation"); + final String range = instruction.getOptional("range"); + if (loc != null && range != null) { + playerLocation = new VariableLocation(BetonQuest.getInstance().getVariableProcessor(), pack, loc); + rangeVar = new VariableNumber(BetonQuest.getInstance().getVariableProcessor(), pack, range); + } else { + playerLocation = null; + rangeVar = null; + } + } + + @EventHandler (ignoreCancelled = true) + public void onBreakCrop(CropBreakEvent event) { + if (!(event.getEntityBreaker() instanceof Player player)) { + return; + } + String id = event.getStageItemID(); + + OnlineProfile onlineProfile = PlayerConverter.getID(player); + if (!containsPlayer(onlineProfile)) { + return; + } + if (isInvalidLocation(player, onlineProfile)) { + return; + } + if (this.crop_ids.contains(id) && this.checkConditions(onlineProfile)) { + getCountingData(onlineProfile).progress(1); + completeIfDoneOrNotify(onlineProfile); + } + } + + private boolean isInvalidLocation(Player player, final Profile profile) { + if (playerLocation == null || rangeVar == null) { + return false; + } + + final Location targetLocation; + try { + targetLocation = playerLocation.getValue(profile); + } catch (final org.betonquest.betonquest.exceptions.QuestRuntimeException e) { + return true; + } + int range; + try { + range = rangeVar.getValue(profile).intValue(); + } catch (QuestRuntimeException e) { + throw new RuntimeException(e); + } + final Location playerLoc = player.getLocation(); + return !playerLoc.getWorld().equals(targetLocation.getWorld()) || targetLocation.distanceSquared(playerLoc) > range * range; + } + + @Override + public void start() { + Bukkit.getPluginManager().registerEvents(this, BetonQuest.getInstance()); + } + + @Override + public void stop() { + HandlerList.unregisterAll(this); + } + } + + public static class PlantObjective extends CountingObjective implements Listener { + + private final VariableLocation playerLocation; + private final VariableNumber rangeVar; + private final HashSet crops; + + public PlantObjective(Instruction instruction) throws InstructionParseException { + super(instruction, "crop_to_plant"); + crops = new HashSet<>(); + Collections.addAll(crops, instruction.getArray()); + targetAmount = instruction.getVarNum(VariableNumber.NOT_LESS_THAN_ONE_CHECKER); + final QuestPackage pack = instruction.getPackage(); + final String loc = instruction.getOptional("playerLocation"); + final String range = instruction.getOptional("range"); + if (loc != null && range != null) { + playerLocation = new VariableLocation(BetonQuest.getInstance().getVariableProcessor(), pack, loc); + rangeVar = new VariableNumber(BetonQuest.getInstance().getVariableProcessor(), pack, range); + } else { + playerLocation = null; + rangeVar = null; + } + } + + @EventHandler (ignoreCancelled = true) + public void onPlantCrop(CropPlantEvent event) { + OnlineProfile onlineProfile = PlayerConverter.getID(event.getPlayer()); + if (!containsPlayer(onlineProfile)) { + return; + } + if (isInvalidLocation(event.getPlayer(), onlineProfile)) { + return; + } + if (this.crops.contains(event.getCropConfig().id()) && this.checkConditions(onlineProfile)) { + getCountingData(onlineProfile).progress(1); + completeIfDoneOrNotify(onlineProfile); + } + } + + private boolean isInvalidLocation(Player player, final Profile profile) { + if (playerLocation == null || rangeVar == null) { + return false; + } + + final Location targetLocation; + try { + targetLocation = playerLocation.getValue(profile); + } catch (final org.betonquest.betonquest.exceptions.QuestRuntimeException e) { + return true; + } + int range; + try { + range = rangeVar.getValue(profile).intValue(); + } catch (QuestRuntimeException e) { + throw new RuntimeException(e); + } + final Location playerLoc = player.getLocation(); + return !playerLoc.getWorld().equals(targetLocation.getWorld()) || targetLocation.distanceSquared(playerLoc) > range * range; + } + + @Override + public void start() { + Bukkit.getPluginManager().registerEvents(this, BetonQuest.getInstance()); + } + + @Override + public void stop() { + HandlerList.unregisterAll(this); + } + } +} diff --git a/compatibility/src/main/java/net/momirealms/customcrops/bukkit/integration/quest/ClueScrollsQuest.java b/compatibility/src/main/java/net/momirealms/customcrops/bukkit/integration/quest/ClueScrollsQuest.java new file mode 100644 index 0000000..f9bc3d2 --- /dev/null +++ b/compatibility/src/main/java/net/momirealms/customcrops/bukkit/integration/quest/ClueScrollsQuest.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) <2024> + * + * 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.customcrops.bukkit.integration.quest; + +import com.electro2560.dev.cluescrolls.api.*; +import net.momirealms.customcrops.api.event.CropBreakEvent; +import net.momirealms.customcrops.api.event.CropPlantEvent; +import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class ClueScrollsQuest implements Listener { + + private final CustomClue harvestClue; + private final CustomClue plantClue; + + public ClueScrollsQuest() { + harvestClue = ClueScrollsAPI.getInstance().registerCustomClue(BukkitCustomFishingPlugin.getInstance().getBoostrap(), "harvest", new ClueConfigData("id", DataType.STRING)); + plantClue = ClueScrollsAPI.getInstance().registerCustomClue(BukkitCustomFishingPlugin.getInstance().getBoostrap(), "plant", new ClueConfigData("id", DataType.STRING)); + } + + public void register() { + Bukkit.getPluginManager().registerEvents(this, BukkitCustomFishingPlugin.getInstance().getBoostrap()); + } + + @EventHandler (ignoreCancelled = true) + public void onBreakCrop(CropBreakEvent event) { + if (!(event.getEntityBreaker() instanceof Player player)) return; + harvestClue.handle( + player, + 1, + new ClueDataPair("id", event.getStageItemID()) + ); + } + + @EventHandler (ignoreCancelled = true) + public void onPlantCrop(CropPlantEvent event) { + plantClue.handle( + event.getPlayer(), + 1, + new ClueDataPair("id", event.getCropConfig().id()) + ); + } +} diff --git a/plugin/src/main/java/net/momirealms/customcrops/bukkit/BukkitCustomCropsPluginImpl.java b/plugin/src/main/java/net/momirealms/customcrops/bukkit/BukkitCustomCropsPluginImpl.java index 4eb5afe..9604ba9 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/bukkit/BukkitCustomCropsPluginImpl.java +++ b/plugin/src/main/java/net/momirealms/customcrops/bukkit/BukkitCustomCropsPluginImpl.java @@ -208,7 +208,7 @@ public class BukkitCustomCropsPluginImpl extends BukkitCustomCropsPlugin { Bukkit.getScheduler().runTask(getBoostrap(), () -> { ((SimpleRegistryAccess) registryAccess).freeze(); logger.info("Registry access has been frozen"); - ((BukkitItemManager) itemManager).setAntiGriefLib(AntiGriefLib.builder((JavaPlugin) getBoostrap()).silentLogs(true).ignoreOP(true).build()); + ((BukkitItemManager) itemManager).setAntiGriefLib(AntiGriefLib.builder((JavaPlugin) getBoostrap()).silentLogs(false).ignoreOP(true).build()); }); } } diff --git a/plugin/src/main/java/net/momirealms/customcrops/bukkit/config/BukkitConfigManager.java b/plugin/src/main/java/net/momirealms/customcrops/bukkit/config/BukkitConfigManager.java index be37f37..df9161b 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/bukkit/config/BukkitConfigManager.java +++ b/plugin/src/main/java/net/momirealms/customcrops/bukkit/config/BukkitConfigManager.java @@ -96,6 +96,11 @@ public class BukkitConfigManager extends ConfigManager { } this.loadSettings(); this.loadConfigs(); + plugin.debug("Loaded " + Registries.CROP.size() + " crops"); + plugin.debug("Loaded " + Registries.SPRINKLER.size() + " sprinklers"); + plugin.debug("Loaded " + Registries.WATERING_CAN.size() + " watering-cans"); + plugin.debug("Loaded " + Registries.POT.size() + " pots"); + plugin.debug("Loaded " + Registries.FERTILIZER.size() + " fertilizers"); } private void loadSettings() { diff --git a/plugin/src/main/java/net/momirealms/customcrops/bukkit/integration/BukkitIntegrationManager.java b/plugin/src/main/java/net/momirealms/customcrops/bukkit/integration/BukkitIntegrationManager.java index f1b37b5..ee23935 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/bukkit/integration/BukkitIntegrationManager.java +++ b/plugin/src/main/java/net/momirealms/customcrops/bukkit/integration/BukkitIntegrationManager.java @@ -25,6 +25,9 @@ import net.momirealms.customcrops.api.integration.SeasonProvider; import net.momirealms.customcrops.bukkit.integration.item.*; import net.momirealms.customcrops.bukkit.integration.level.*; import net.momirealms.customcrops.bukkit.integration.papi.CustomCropsPapi; +import net.momirealms.customcrops.bukkit.integration.quest.BattlePassQuest; +import net.momirealms.customcrops.bukkit.integration.quest.BetonQuestQuest; +import net.momirealms.customcrops.bukkit.integration.quest.ClueScrollsQuest; import net.momirealms.customcrops.bukkit.integration.season.AdvancedSeasonsProvider; import net.momirealms.customcrops.bukkit.integration.season.RealisticSeasonsProvider; import net.momirealms.customcrops.bukkit.item.BukkitItemManager; @@ -104,6 +107,17 @@ public class BukkitIntegrationManager implements IntegrationManager { if (isHooked("PlaceholderAPI")) { new CustomCropsPapi(plugin).load(); } + if (isHooked("BattlePass")){ + BattlePassQuest battlePassQuest = new BattlePassQuest(); + battlePassQuest.register(); + } + if (isHooked("ClueScrolls")) { + ClueScrollsQuest clueScrollsQuest = new ClueScrollsQuest(); + clueScrollsQuest.register(); + } + if (isHooked("BetonQuest", "2")) { + BetonQuestQuest.register(); + } } private boolean isHooked(String hooked) { diff --git a/plugin/src/main/java/net/momirealms/customcrops/bukkit/item/BukkitItemManager.java b/plugin/src/main/java/net/momirealms/customcrops/bukkit/item/BukkitItemManager.java index dc58823..1b666ba 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/bukkit/item/BukkitItemManager.java +++ b/plugin/src/main/java/net/momirealms/customcrops/bukkit/item/BukkitItemManager.java @@ -32,6 +32,7 @@ import net.momirealms.customcrops.api.core.wrapper.WrappedBreakEvent; import net.momirealms.customcrops.api.core.wrapper.WrappedInteractAirEvent; import net.momirealms.customcrops.api.core.wrapper.WrappedInteractEvent; import net.momirealms.customcrops.api.core.wrapper.WrappedPlaceEvent; +import net.momirealms.customcrops.api.integration.ExternalProvider; import net.momirealms.customcrops.api.integration.ItemProvider; import net.momirealms.customcrops.api.util.EventUtils; import net.momirealms.customcrops.api.util.LocationUtils; @@ -92,6 +93,10 @@ public class BukkitItemManager extends AbstractItemManager { @Override public void load() { this.resetItemDetectionOrder(); + for (ItemProvider provider : itemProviders.values()) { + plugin.debug("Registered ItemProvider: " + provider.identifier()); + } + plugin.debug("Item order: " + Arrays.toString(Arrays.stream(itemDetectArray).map(ExternalProvider::identifier).toList().toArray(new String[0]))); } @Override