From ab06df861d4f7c23b81e12060946bb3cc6e66270 Mon Sep 17 00:00:00 2001 From: Xiao-MoMi <70987828+Xiao-MoMi@users.noreply.github.com> Date: Fri, 5 May 2023 19:36:29 +0800 Subject: [PATCH] 3.1.0 --- build.gradle | 2 +- .../customcrops/api/customplugin/Handler.java | 55 +++++++++++++- .../api/customplugin/PlatformManager.java | 72 +++++++++++++------ .../customcrops/api/event/CropBreakEvent.java | 24 ++++--- .../customcrops/api/event/PotBreakEvent.java | 16 ++++- .../api/object/action/GiveMoneyImpl.java | 21 ++++++ .../api/object/action/VanillaXPImpl.java | 15 +--- .../api/object/action/VariationImpl.java | 36 +++++++--- .../api/object/basic/ConfigManager.java | 4 ++ .../customcrops/api/object/pot/PotConfig.java | 14 ++-- .../api/object/pot/PotManager.java | 27 +++++-- .../customcrops/api/object/world/CCChunk.java | 14 +++- .../customcrops/api/object/world/CCWorld.java | 15 +++- .../customcrops/api/util/ConfigUtils.java | 4 ++ .../integration/IntegrationManager.java | 12 ++++ .../customcrops/integration/VaultHook.java | 40 +++++++++++ .../integration/quest/BattlePassCCQuest.java | 5 +- .../integration/quest/BetonQuestCCQuest.java | 6 +- .../integration/quest/ClueScrollCCQuest.java | 5 +- .../quest/LegacyBetonQuestCCQuest.java | 5 +- src/main/resources/config.yml | 11 ++- src/main/resources/plugin.yml | 1 + 22 files changed, 321 insertions(+), 83 deletions(-) create mode 100644 src/main/java/net/momirealms/customcrops/api/object/action/GiveMoneyImpl.java create mode 100644 src/main/java/net/momirealms/customcrops/integration/VaultHook.java diff --git a/build.gradle b/build.gradle index ffbf19a..b8ad877 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group = 'net.momirealms' -version = '3.0.7' +version = '3.1.0' repositories { mavenCentral() diff --git a/src/main/java/net/momirealms/customcrops/api/customplugin/Handler.java b/src/main/java/net/momirealms/customcrops/api/customplugin/Handler.java index 2f019fd..4175ee5 100644 --- a/src/main/java/net/momirealms/customcrops/api/customplugin/Handler.java +++ b/src/main/java/net/momirealms/customcrops/api/customplugin/Handler.java @@ -19,12 +19,19 @@ package net.momirealms.customcrops.api.customplugin; import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.api.object.Function; +import net.momirealms.customcrops.api.object.basic.ConfigManager; +import net.momirealms.customcrops.api.object.pot.PotManager; +import net.momirealms.customcrops.api.object.world.SimpleLocation; import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.type.Farmland; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.block.*; +import org.bukkit.event.entity.EntityChangeBlockEvent; import org.bukkit.event.player.PlayerInteractEvent; public abstract class Handler extends Function implements Listener { @@ -59,4 +66,48 @@ public abstract class Handler extends Function implements Listener { public void onPlace(BlockPlaceEvent event) { platformManager.onPlaceVanilla(event); } + + @EventHandler + public void onMoistureChange(MoistureChangeEvent event) { + if (event.isCancelled()) return; + if (ConfigManager.disableMoistureMechanic) event.setCancelled(true); + } + + @EventHandler + public void onTrampling(EntityChangeBlockEvent event) { + if (event.isCancelled()) return; + Block block = event.getBlock(); + if (block.getType() == Material.FARMLAND && event.getTo() == Material.DIRT) { + if (ConfigManager.preventTrampling) { + event.setCancelled(true); + } else if (PotManager.enableFarmLand) { + platformManager.onBreakPot(event.getEntity(), "FARMLAND", block.getLocation(), event); + } + } + } + + @EventHandler + public void onBlockFade(BlockFadeEvent event) { + if (!PotManager.enableFarmLand || event.isCancelled()) return; + Block block = event.getBlock(); + if (block.getType() == Material.FARMLAND) { + if (CustomCrops.getInstance().getPlatformInterface().detectAnyThing(event.getBlock().getLocation().clone().add(0,1,0))) { + event.setCancelled(true); + } else { + platformManager.onBreakPot(null, "FARMLAND", block.getLocation(), event); + } + } + } + + @EventHandler + public void onPistonExtend(BlockPistonExtendEvent event) { + if (!PotManager.enableVanillaBlock || event.isCancelled()) return; + PotManager potManager = CustomCrops.getInstance().getPotManager(); + for (Block block : event.getBlocks()) { + String id = block.getType().name(); + if (potManager.containsPotBlock(id)) { + platformManager.onBreakPot(null, id, block.getLocation(), event); + } + } + } } \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/api/customplugin/PlatformManager.java b/src/main/java/net/momirealms/customcrops/api/customplugin/PlatformManager.java index 4e927c2..79a65de 100644 --- a/src/main/java/net/momirealms/customcrops/api/customplugin/PlatformManager.java +++ b/src/main/java/net/momirealms/customcrops/api/customplugin/PlatformManager.java @@ -660,19 +660,21 @@ public class PlatformManager extends Function { // water PassiveFillMethod[] passiveFillMethods = potConfig.getPassiveFillMethods(); - for (PassiveFillMethod passiveFillMethod : passiveFillMethods) { - if (passiveFillMethod.isRightItem(item_in_hand_id)) { + if (passiveFillMethods != null) { + for (PassiveFillMethod passiveFillMethod : passiveFillMethods) { + if (passiveFillMethod.isRightItem(item_in_hand_id)) { - PotWaterEvent potWaterEvent = new PotWaterEvent(player, item_in_hand, passiveFillMethod.getAmount(), location); - Bukkit.getPluginManager().callEvent(potWaterEvent); - if (potWaterEvent.isCancelled()) { - return true; + PotWaterEvent potWaterEvent = new PotWaterEvent(player, item_in_hand, passiveFillMethod.getAmount(), location); + Bukkit.getPluginManager().callEvent(potWaterEvent); + if (potWaterEvent.isCancelled()) { + return true; + } + + event.setCancelled(true); + doPassiveFillAction(player, item_in_hand, passiveFillMethod, location.clone().add(0,1,0)); + plugin.getWorldDataManager().addWaterToPot(SimpleLocation.getByBukkitLocation(location), potWaterEvent.getWater(), pot_id); + break outer; } - - event.setCancelled(true); - doPassiveFillAction(player, item_in_hand, passiveFillMethod, location.clone().add(0,1,0)); - plugin.getWorldDataManager().addWaterToPot(SimpleLocation.getByBukkitLocation(location), potWaterEvent.getWater(), pot_id); - break outer; } } @@ -740,7 +742,7 @@ public class PlatformManager extends Function { PotInfoEvent potInfoEvent = new PotInfoEvent(player, location, item_in_hand, potConfig, potData.getFertilizer(), potData.getWater(), growingCrop); Bukkit.getPluginManager().callEvent(potInfoEvent); - if (potConfig.getRequiredItem() != null && !item_in_hand_id.equals(potConfig.getRequiredItem())) { + if (potConfig.getPotInfoItem() != null && !item_in_hand_id.equals(potConfig.getPotInfoItem())) { return true; } @@ -788,13 +790,13 @@ public class PlatformManager extends Function { plugin.getWateringCanManager().setWater(item_in_hand, current_water, wateringCanConfig); } - public boolean onBreakPot(Player player, String id, Location location, Cancellable event) { + public boolean onBreakPot(@Nullable Entity entity, String id, Location location, Cancellable event) { PotConfig potConfig = plugin.getPotManager().getPotConfigByBlockID(id); if (potConfig == null) { return false; } - PotBreakEvent potBreakEvent = new PotBreakEvent(player, location, potConfig); + PotBreakEvent potBreakEvent = new PotBreakEvent(entity, location, potConfig); Bukkit.getPluginManager().callEvent(potBreakEvent); if (potBreakEvent.isCancelled()) { event.setCancelled(true); @@ -805,7 +807,7 @@ public class PlatformManager extends Function { String above_id = plugin.getPlatformInterface().getAnyItemIDAt(above_loc); // has item above // is a crop - if (onBreakCrop(player, above_id, above_loc, event)) { + if (onBreakCrop(entity, above_id, above_loc, event)) { // The event might be cancelled if the player doesn't meet the break requirements if (event.isCancelled()) { return true; @@ -834,7 +836,7 @@ public class PlatformManager extends Function { return true; } - private boolean onBreakCrop(Player player, String id, Location location, Cancellable event) { + private boolean onBreakCrop(@Nullable Entity entity, String id, Location location, Cancellable event) { if (plugin.getCropManager().isDeadCrop(id)) { return true; } @@ -842,18 +844,44 @@ public class PlatformManager extends Function { CropConfig cropConfig = plugin.getCropManager().getCropConfigByStage(id); if (cropConfig == null) return false; - if (!canBreak(player, cropConfig, location)) { - event.setCancelled(true); - return true; - } + if (entity instanceof Player player) { + + if (!canBreak(player, cropConfig, location)) { + event.setCancelled(true); + return true; + } + + CropBreakEvent cropBreakEvent = new CropBreakEvent(entity, cropConfig, id, location); + Bukkit.getPluginManager().callEvent(cropBreakEvent); + if (cropBreakEvent.isCancelled()) { + return true; + } + + if (player.getGameMode() != GameMode.CREATIVE) { + StageConfig stageConfig = plugin.getCropManager().getStageConfig(id); + if (stageConfig != null) { + Action[] breakActions = stageConfig.getBreakActions(); + if (breakActions != null) { + for (Action action : breakActions) { + action.doOn(player, SimpleLocation.getByBukkitLocation(location), cropConfig.getCropMode()); + } + } + } + } + } else { + + CropBreakEvent cropBreakEvent = new CropBreakEvent(entity, cropConfig, id, location); + Bukkit.getPluginManager().callEvent(cropBreakEvent); + if (cropBreakEvent.isCancelled()) { + return true; + } - if (player.getGameMode() != GameMode.CREATIVE) { StageConfig stageConfig = plugin.getCropManager().getStageConfig(id); if (stageConfig != null) { Action[] breakActions = stageConfig.getBreakActions(); if (breakActions != null) { for (Action action : breakActions) { - action.doOn(player, SimpleLocation.getByBukkitLocation(location), cropConfig.getCropMode()); + action.doOn(null, SimpleLocation.getByBukkitLocation(location), cropConfig.getCropMode()); } } } diff --git a/src/main/java/net/momirealms/customcrops/api/event/CropBreakEvent.java b/src/main/java/net/momirealms/customcrops/api/event/CropBreakEvent.java index aa230d9..210f6ea 100644 --- a/src/main/java/net/momirealms/customcrops/api/event/CropBreakEvent.java +++ b/src/main/java/net/momirealms/customcrops/api/event/CropBreakEvent.java @@ -19,24 +19,27 @@ package net.momirealms.customcrops.api.event; import net.momirealms.customcrops.api.object.crop.CropConfig; import org.bukkit.Location; -import org.bukkit.entity.Player; +import org.bukkit.entity.Entity; import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; import org.bukkit.event.HandlerList; -import org.bukkit.event.player.PlayerEvent; +import org.bukkit.event.entity.EntityEvent; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public class CropBreakEvent extends PlayerEvent implements Cancellable { +public class CropBreakEvent extends Event implements Cancellable { private static final HandlerList handlers = new HandlerList(); private boolean cancelled; private final CropConfig cropConfig; - private final String crop_id; + private final String cropItemID; private final Location location; + private final Entity entity; - public CropBreakEvent(@NotNull Player who, CropConfig cropConfig, String crop_id, Location location) { - super(who); + public CropBreakEvent(@Nullable Entity entity, CropConfig cropConfig, String cropItemID, Location location) { + this.entity = entity; this.cropConfig = cropConfig; - this.crop_id = crop_id; + this.cropItemID = cropItemID; this.location = location; } @@ -70,10 +73,15 @@ public class CropBreakEvent extends PlayerEvent implements Cancellable { * @return item id */ public String getCropItemID() { - return crop_id; + return cropItemID; } public Location getLocation() { return location; } + + @Nullable + public Entity getEntity() { + return entity; + } } diff --git a/src/main/java/net/momirealms/customcrops/api/event/PotBreakEvent.java b/src/main/java/net/momirealms/customcrops/api/event/PotBreakEvent.java index efc5587..0b07fe8 100644 --- a/src/main/java/net/momirealms/customcrops/api/event/PotBreakEvent.java +++ b/src/main/java/net/momirealms/customcrops/api/event/PotBreakEvent.java @@ -19,21 +19,26 @@ package net.momirealms.customcrops.api.event; import net.momirealms.customcrops.api.object.pot.PotConfig; import org.bukkit.Location; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; import org.bukkit.event.player.PlayerEvent; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public class PotBreakEvent extends PlayerEvent implements Cancellable { +public class PotBreakEvent extends Event implements Cancellable { private static final HandlerList handlers = new HandlerList(); private boolean cancelled; private final Location location; private final PotConfig potConfig; + private final Entity entity; - public PotBreakEvent(@NotNull Player who, Location location, PotConfig potConfig) { - super(who); + public PotBreakEvent(@Nullable Entity entity, Location location, PotConfig potConfig) { + this.entity = entity; this.location = location; this.potConfig = potConfig; } @@ -66,4 +71,9 @@ public class PotBreakEvent extends PlayerEvent implements Cancellable { public PotConfig getPotConfig() { return potConfig; } + + @Nullable + public Entity getEntity() { + return entity; + } } diff --git a/src/main/java/net/momirealms/customcrops/api/object/action/GiveMoneyImpl.java b/src/main/java/net/momirealms/customcrops/api/object/action/GiveMoneyImpl.java new file mode 100644 index 0000000..26d7e72 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/api/object/action/GiveMoneyImpl.java @@ -0,0 +1,21 @@ +package net.momirealms.customcrops.api.object.action; + +import net.momirealms.customcrops.CustomCrops; +import net.momirealms.customcrops.api.object.ItemMode; +import net.momirealms.customcrops.api.object.world.SimpleLocation; +import net.momirealms.customcrops.integration.VaultHook; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Nullable; + +public record GiveMoneyImpl(double money, double chance) implements Action { + + @Override + public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) { + if (player != null && Math.random() < chance) { + VaultHook vaultHook = CustomCrops.getInstance().getIntegrationManager().getVault(); + if (vaultHook != null) { + vaultHook.getEconomy().depositPlayer(player, money); + } + } + } +} diff --git a/src/main/java/net/momirealms/customcrops/api/object/action/VanillaXPImpl.java b/src/main/java/net/momirealms/customcrops/api/object/action/VanillaXPImpl.java index 3a13a72..5cbda79 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/action/VanillaXPImpl.java +++ b/src/main/java/net/momirealms/customcrops/api/object/action/VanillaXPImpl.java @@ -32,18 +32,7 @@ public record VanillaXPImpl(int amount, boolean mending, double chance) implemen @Override public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) { if (player == null || Math.random() > chance) return; - if (CustomCrops.getInstance().getVersionHelper().isSpigot()) { - if (mending) { - player.getLocation().getWorld().spawn(player.getLocation(), ExperienceOrb.class, e -> e.setExperience(amount)); - } - else { - player.giveExp(amount); - AdventureUtils.playerSound(player, Sound.Source.PLAYER, Key.key("minecraft:entity.experience_orb.pickup"), 1, 1); - } - } - else { - player.giveExp(amount, mending); - AdventureUtils.playerSound(player, Sound.Source.PLAYER, Key.key("minecraft:entity.experience_orb.pickup"), 1, 1); - } + player.giveExp(amount, mending); + AdventureUtils.playerSound(player, Sound.Source.PLAYER, Key.key("minecraft:entity.experience_orb.pickup"), 1, 1); } } diff --git a/src/main/java/net/momirealms/customcrops/api/object/action/VariationImpl.java b/src/main/java/net/momirealms/customcrops/api/object/action/VariationImpl.java index 2ad45bc..72552fd 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/action/VariationImpl.java +++ b/src/main/java/net/momirealms/customcrops/api/object/action/VariationImpl.java @@ -23,11 +23,14 @@ import net.momirealms.customcrops.api.object.crop.VariationCrop; import net.momirealms.customcrops.api.object.fertilizer.Variation; import net.momirealms.customcrops.api.object.pot.Pot; import net.momirealms.customcrops.api.object.world.SimpleLocation; +import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.concurrent.CompletableFuture; + public record VariationImpl(VariationCrop[] variationCrops) implements Action { @Override @@ -63,13 +66,30 @@ public record VariationImpl(VariationCrop[] variationCrops) implements Action { } private void doVariation(@NotNull SimpleLocation crop_loc, ItemMode itemMode, VariationCrop variationCrop) { - CustomCrops.getInstance().getScheduler().callSyncMethod(() -> { - Location location = crop_loc.getBukkitLocation(); - if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode)) { - CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, variationCrop.getId(), variationCrop.getCropMode()); - } - CustomCrops.getInstance().getWorldDataManager().removeCropData(crop_loc); - return null; - }); + Location location = crop_loc.getBukkitLocation(); + if (location == null) return; + CompletableFuture asyncGetChunk = location.getWorld().getChunkAtAsync(location.getBlockX() >> 4, location.getBlockZ() >> 4); + if (itemMode == ItemMode.ITEM_FRAME || itemMode == ItemMode.ITEM_DISPLAY) { + CompletableFuture loadEntities = asyncGetChunk.thenApply((chunk) -> { + chunk.getEntities(); + return chunk.isEntitiesLoaded(); + }); + loadEntities.whenComplete((result, throwable) -> + CustomCrops.getInstance().getScheduler().callSyncMethod(() -> { + if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode)) { + CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, variationCrop.getId(), variationCrop.getCropMode()); + } + return null; + })); + } + else { + asyncGetChunk.whenComplete((result, throwable) -> + CustomCrops.getInstance().getScheduler().callSyncMethod(() -> { + if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode)) { + CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, variationCrop.getId(), variationCrop.getCropMode()); + } + return null; + })); + } } } \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/api/object/basic/ConfigManager.java b/src/main/java/net/momirealms/customcrops/api/object/basic/ConfigManager.java index 07124bb..368a77f 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/basic/ConfigManager.java +++ b/src/main/java/net/momirealms/customcrops/api/object/basic/ConfigManager.java @@ -63,6 +63,8 @@ public class ConfigManager extends Function { public static boolean setUpMode; public static int intervalConsume; public static int intervalWork; + public static boolean disableMoistureMechanic; + public static boolean preventTrampling; private final HashMap cropPerWorld; private final CustomCrops plugin; @@ -138,6 +140,8 @@ public class ConfigManager extends Function { greenhouseRange = section.getInt("season.greenhouse.range", 5); greenhouseBlock = section.getString("season.greenhouse.block"); scarecrow = section.getString("scarecrow"); + disableMoistureMechanic = section.getBoolean("vanilla-farmland.disable-moisture-mechanic", false); + preventTrampling = section.getBoolean("vanilla-farmland.prevent-trampling", false); } private void loadOtherSetting(ConfigurationSection section) { diff --git a/src/main/java/net/momirealms/customcrops/api/object/pot/PotConfig.java b/src/main/java/net/momirealms/customcrops/api/object/pot/PotConfig.java index 52e9139..8eadbcc 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/pot/PotConfig.java +++ b/src/main/java/net/momirealms/customcrops/api/object/pot/PotConfig.java @@ -39,13 +39,13 @@ public class PotConfig { private final PassiveFillMethod[] passiveFillMethods; private final FertilizerHologram fertilizerHologram; private final WaterAmountHologram waterAmountHologram; - private final String requiredItem; + private final String potInfoItem; public PotConfig(String key, int max_storage, String dry_pot, String wet_pot, boolean enableFertilized, - @NotNull PassiveFillMethod[] passiveFillMethods, + @Nullable PassiveFillMethod[] passiveFillMethods, @Nullable FertilizerHologram fertilizerHologram, @Nullable WaterAmountHologram waterAmountHologram, - String requiredItem) { + String potInfoItem) { this.key = key; this.max_storage = max_storage; this.pot = Pair.of(dry_pot, wet_pot); @@ -54,7 +54,7 @@ public class PotConfig { this.passiveFillMethods = passiveFillMethods; this.fertilizerHologram = fertilizerHologram; this.waterAmountHologram = waterAmountHologram; - this.requiredItem = requiredItem; + this.potInfoItem = potInfoItem; } public void registerFertilizedPot(FertilizerType fertilizerType, String dry_pot, String wet_pot) { @@ -85,7 +85,7 @@ public class PotConfig { return max_storage; } - @NotNull + @Nullable public PassiveFillMethod[] getPassiveFillMethods() { return passiveFillMethods; } @@ -101,8 +101,8 @@ public class PotConfig { } @Nullable - public String getRequiredItem() { - return requiredItem; + public String getPotInfoItem() { + return potInfoItem; } @NotNull diff --git a/src/main/java/net/momirealms/customcrops/api/object/pot/PotManager.java b/src/main/java/net/momirealms/customcrops/api/object/pot/PotManager.java index 8dfc411..ec4c821 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/pot/PotManager.java +++ b/src/main/java/net/momirealms/customcrops/api/object/pot/PotManager.java @@ -19,6 +19,7 @@ package net.momirealms.customcrops.api.object.pot; import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.api.object.Function; +import net.momirealms.customcrops.api.object.basic.ConfigManager; import net.momirealms.customcrops.api.object.fertilizer.FertilizerType; import net.momirealms.customcrops.api.object.fill.PassiveFillMethod; import net.momirealms.customcrops.api.object.hologram.FertilizerHologram; @@ -39,6 +40,8 @@ public class PotManager extends Function { private final CustomCrops plugin; private final HashMap potConfigMap; private final HashMap blockToPotKey; + public static boolean enableFarmLand; + public static boolean enableVanillaBlock; public PotManager(CustomCrops plugin) { this.plugin = plugin; @@ -55,6 +58,8 @@ public class PotManager extends Function { public void unload() { this.potConfigMap.clear(); this.blockToPotKey.clear(); + enableFarmLand = false; + enableVanillaBlock = false; } private void loadConfig() { @@ -77,11 +82,9 @@ public class PotManager extends Function { AdventureUtils.consoleMessage("[CustomCrops] base.dry/base.wet is not correctly set for pot: " + key); continue; } - PassiveFillMethod[] methods = ConfigUtils.getPassiveFillMethods(section.getConfigurationSection("fill-method")); - if (methods == null) { - AdventureUtils.consoleMessage("[CustomCrops] fill method is not set for pot: " + key); - continue; - } + + if (ConfigUtils.isVanillaItem(base_wet) || ConfigUtils.isVanillaItem(base_dry)) enableVanillaBlock = true; + blockToPotKey.put(base_wet, key); blockToPotKey.put(base_dry, key); PotConfig potConfig = new PotConfig( @@ -90,7 +93,7 @@ public class PotManager extends Function { base_dry, base_wet, enableFertilized, - methods, + ConfigUtils.getPassiveFillMethods(section.getConfigurationSection("fill-method")), section.getBoolean("hologram.fertilizer.enable", false) ? new FertilizerHologram( section.getString("hologram.fertilizer.content", ""), section.getDouble("hologram.fertilizer.vertical-offset"), @@ -123,6 +126,7 @@ public class PotManager extends Function { ) : null, section.getString("hologram.require-item") ); + if (enableFertilized) { ConfigurationSection fertilizedSec = section.getConfigurationSection("fertilized-pots"); if (fertilizedSec == null) continue; @@ -141,6 +145,17 @@ public class PotManager extends Function { } } } + + if (base_dry.equals("FARMLAND") || base_wet.equals("FARMLAND")) { + enableFarmLand = true; + if (!ConfigManager.disableMoistureMechanic && (potConfig.getPassiveFillMethods() != null || potConfig.getWaterAmountHologram() != null)) { + AdventureUtils.consoleMessage("[CustomCrops] Since you are using vanilla farmland, vanilla moisture would"); + AdventureUtils.consoleMessage("[CustomCrops] conflict with CustomCrops' water system. It's advised to disable"); + AdventureUtils.consoleMessage("[CustomCrops] moisture mechanic in config.yml or delete fill-method and"); + AdventureUtils.consoleMessage("[CustomCrops] disable the water info hologram in pot configuration."); + } + } + potConfigMap.put(key, potConfig); } } diff --git a/src/main/java/net/momirealms/customcrops/api/object/world/CCChunk.java b/src/main/java/net/momirealms/customcrops/api/object/world/CCChunk.java index 867c674..0aae527 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/world/CCChunk.java +++ b/src/main/java/net/momirealms/customcrops/api/object/world/CCChunk.java @@ -26,6 +26,8 @@ import net.momirealms.customcrops.api.object.sprinkler.Sprinkler; import net.momirealms.customcrops.api.util.ConfigUtils; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.type.Farmland; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -166,8 +168,7 @@ public class CCChunk implements Serializable { changePotModel(simpleLocation, pot); return null; }); - } - else { + } else { Pot newPot = new Pot(pot_id, fertilizer, 0); potMap.put(simpleLocation, newPot); CustomCrops.getInstance().getScheduler().callSyncMethod(() -> { @@ -205,7 +206,14 @@ public class CCChunk implements Serializable { if (location == null) return; if (CustomCrops.getInstance().getPlatformInterface().removeAnyBlock(location)) { String replacer = pot.isWet() ? pot.getConfig().getWetPot(pot.getFertilizer()) : pot.getConfig().getDryPot(pot.getFertilizer()); - if (ConfigUtils.isVanillaItem(replacer)) location.getBlock().setType(Material.valueOf(replacer)); + if (ConfigUtils.isVanillaItem(replacer)) { + Block block = location.getBlock(); + block.setType(Material.valueOf(replacer)); + if (block.getBlockData() instanceof Farmland farmland && ConfigManager.disableMoistureMechanic) { + farmland.setMoisture(pot.isWet() ? farmland.getMaximumMoisture() : 0); + block.setBlockData(farmland); + } + } else CustomCrops.getInstance().getPlatformInterface().placeNoteBlock(location, replacer); } else { CustomCrops.getInstance().getWorldDataManager().removePotData(simpleLocation); diff --git a/src/main/java/net/momirealms/customcrops/api/object/world/CCWorld.java b/src/main/java/net/momirealms/customcrops/api/object/world/CCWorld.java index 8fe4503..95a03c4 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/world/CCWorld.java +++ b/src/main/java/net/momirealms/customcrops/api/object/world/CCWorld.java @@ -44,8 +44,11 @@ import net.momirealms.customcrops.api.util.ConfigUtils; import net.momirealms.customcrops.api.util.FakeEntityUtils; import net.momirealms.customcrops.helper.Log; import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.block.data.type.Farmland; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; +import org.bukkit.event.block.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -325,8 +328,16 @@ public class CCWorld extends Function { CustomCrops.getInstance().getScheduler().callSyncMethod(() -> { if (CustomCrops.getInstance().getPlatformInterface().removeAnyBlock(location)) { String replacer = wet ? potConfig.getWetPot(fertilizer) : potConfig.getDryPot(fertilizer); - if (ConfigUtils.isVanillaItem(replacer)) location.getBlock().setType(Material.valueOf(replacer)); - else CustomCrops.getInstance().getPlatformInterface().placeNoteBlock(location, replacer); + if (ConfigUtils.isVanillaItem(replacer)) { + Block block = location.getBlock(); + block.setType(Material.valueOf(replacer)); + if (block.getBlockData() instanceof Farmland farmland && ConfigManager.disableMoistureMechanic) { + farmland.setMoisture(wet ? farmland.getMaximumMoisture() : 0); + block.setBlockData(farmland); + } + } else { + CustomCrops.getInstance().getPlatformInterface().placeNoteBlock(location, replacer); + } } else { CustomCrops.getInstance().getWorldDataManager().removePotData(SimpleLocation.getByBukkitLocation(location)); } diff --git a/src/main/java/net/momirealms/customcrops/api/util/ConfigUtils.java b/src/main/java/net/momirealms/customcrops/api/util/ConfigUtils.java index 3b2789b..b10aa4e 100644 --- a/src/main/java/net/momirealms/customcrops/api/util/ConfigUtils.java +++ b/src/main/java/net/momirealms/customcrops/api/util/ConfigUtils.java @@ -338,6 +338,10 @@ public class ConfigUtils { actionSec.getDouble("chance") )); case "swing-hand" -> actions.add(new SwingHandImpl()); + case "give-money" -> actions.add(new GiveMoneyImpl( + actionSec.getDouble("value"), + actionSec.getDouble("chance", 1) + )); } } return actions.toArray(new Action[0]); diff --git a/src/main/java/net/momirealms/customcrops/integration/IntegrationManager.java b/src/main/java/net/momirealms/customcrops/integration/IntegrationManager.java index ce6dfe9..54976a8 100644 --- a/src/main/java/net/momirealms/customcrops/integration/IntegrationManager.java +++ b/src/main/java/net/momirealms/customcrops/integration/IntegrationManager.java @@ -54,6 +54,7 @@ public class IntegrationManager extends Function { private ItemInterface[] itemInterfaces; private SeasonInterface seasonInterface; private final PluginManager pluginManager; + private VaultHook vaultHook; private final PlaceholderManager placeholderManager; public IntegrationManager(CustomCrops plugin) { @@ -61,6 +62,12 @@ public class IntegrationManager extends Function { this.pluginManager = Bukkit.getPluginManager(); this.placeholderManager = new PlaceholderManager(plugin); this.registerQuests(); + if (Bukkit.getPluginManager().isPluginEnabled("Vault")) { + this.vaultHook = new VaultHook(); + if (!vaultHook.initialize()) { + AdventureUtils.consoleMessage("[CustomCrops] Failed to initialize Vault"); + } + } } @Override @@ -181,4 +188,9 @@ public class IntegrationManager extends Function { public PlaceholderManager getPlaceholderManager() { return placeholderManager; } + + @Nullable + public VaultHook getVault() { + return vaultHook; + } } diff --git a/src/main/java/net/momirealms/customcrops/integration/VaultHook.java b/src/main/java/net/momirealms/customcrops/integration/VaultHook.java new file mode 100644 index 0000000..cd880b0 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integration/VaultHook.java @@ -0,0 +1,40 @@ +/* + * 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.customcrops.integration; + +import net.milkbowl.vault.economy.Economy; +import net.momirealms.customcrops.CustomCrops; +import org.bukkit.plugin.RegisteredServiceProvider; + +public class VaultHook { + + private Economy economy; + + public boolean initialize() { + RegisteredServiceProvider rsp = CustomCrops.getInstance().getServer().getServicesManager().getRegistration(Economy.class); + if (rsp == null) { + return false; + } + this.economy = rsp.getProvider(); + return true; + } + + public Economy getEconomy() { + return economy; + } +} diff --git a/src/main/java/net/momirealms/customcrops/integration/quest/BattlePassCCQuest.java b/src/main/java/net/momirealms/customcrops/integration/quest/BattlePassCCQuest.java index 90f6d7e..92e759a 100644 --- a/src/main/java/net/momirealms/customcrops/integration/quest/BattlePassCCQuest.java +++ b/src/main/java/net/momirealms/customcrops/integration/quest/BattlePassCCQuest.java @@ -39,7 +39,8 @@ public class BattlePassCCQuest extends ExternalQuestExecutor implements Listener @EventHandler public void onHarvest(CropBreakEvent event) { if (event.isCancelled()) return; - Player player = event.getPlayer(); - this.execute("harvest", player, (var1x) -> var1x.root(event.getCropItemID())); + if (event.getEntity() instanceof Player player) { + this.execute("harvest", player, (var1x) -> var1x.root(event.getCropItemID())); + } } } diff --git a/src/main/java/net/momirealms/customcrops/integration/quest/BetonQuestCCQuest.java b/src/main/java/net/momirealms/customcrops/integration/quest/BetonQuestCCQuest.java index 0c81dbc..31cd74b 100644 --- a/src/main/java/net/momirealms/customcrops/integration/quest/BetonQuestCCQuest.java +++ b/src/main/java/net/momirealms/customcrops/integration/quest/BetonQuestCCQuest.java @@ -30,6 +30,7 @@ import org.betonquest.betonquest.utils.PlayerConverter; import org.betonquest.betonquest.utils.location.CompoundLocation; 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; @@ -71,7 +72,8 @@ public class BetonQuestCCQuest extends CountingObjective implements Listener { @EventHandler public void onHarvest(CropBreakEvent event) { - OnlineProfile onlineProfile = PlayerConverter.getID(event.getPlayer()); + if (!(event.getEntity() instanceof Player player)) return; + OnlineProfile onlineProfile = PlayerConverter.getID(player); if (!containsPlayer(onlineProfile)) { return; } @@ -97,7 +99,7 @@ public class BetonQuestCCQuest extends CountingObjective implements Listener { return true; } final int range = rangeVar.getInt(profile); - final Location playerLoc = event.getPlayer().getLocation(); + final Location playerLoc = event.getEntity().getLocation(); return !playerLoc.getWorld().equals(targetLocation.getWorld()) || targetLocation.distanceSquared(playerLoc) > range * range; } diff --git a/src/main/java/net/momirealms/customcrops/integration/quest/ClueScrollCCQuest.java b/src/main/java/net/momirealms/customcrops/integration/quest/ClueScrollCCQuest.java index 8a6dad5..856be47 100644 --- a/src/main/java/net/momirealms/customcrops/integration/quest/ClueScrollCCQuest.java +++ b/src/main/java/net/momirealms/customcrops/integration/quest/ClueScrollCCQuest.java @@ -19,6 +19,7 @@ package net.momirealms.customcrops.integration.quest; import com.electro2560.dev.cluescrolls.api.*; import net.momirealms.customcrops.api.event.CropBreakEvent; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.plugin.Plugin; @@ -34,6 +35,8 @@ public class ClueScrollCCQuest implements Listener { @EventHandler public void onHarvest(CropBreakEvent event) { if (event.isCancelled()) return; - commonClue.handle(event.getPlayer(), 1, new ClueDataPair("crop_id", event.getCropItemID())); + if (event.getEntity() instanceof Player player) { + commonClue.handle(player, 1, new ClueDataPair("crop_id", event.getCropItemID())); + } } } diff --git a/src/main/java/net/momirealms/customcrops/integration/quest/LegacyBetonQuestCCQuest.java b/src/main/java/net/momirealms/customcrops/integration/quest/LegacyBetonQuestCCQuest.java index d993e9e..38810c6 100644 --- a/src/main/java/net/momirealms/customcrops/integration/quest/LegacyBetonQuestCCQuest.java +++ b/src/main/java/net/momirealms/customcrops/integration/quest/LegacyBetonQuestCCQuest.java @@ -94,11 +94,12 @@ public class LegacyBetonQuestCCQuest extends Objective implements Listener { @EventHandler public void onHarvest(CropBreakEvent event) { - String playerID = PlayerConverter.getID(event.getPlayer()); + if (!(event.getEntity() instanceof Player player)) return; + String playerID = PlayerConverter.getID(player); if (this.containsPlayer(playerID)) { if (this.crop_ids.contains(event.getCropItemID())) { if (this.checkConditions(playerID)) { - if (!isValidPlayer(event.getPlayer())) { + if (!isValidPlayer(player)) { return; } CropData cropData = (CropData) this.dataMap.get(playerID); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 43a3295..2379fe0 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,5 +1,5 @@ # Don't change -config-version: '28' +config-version: '29' # BStats metrics: true # Language: english / spanish / chinese / turkish @@ -96,6 +96,15 @@ mechanics: # scarecrow item id # 稻草人物品id scarecrow: customcrops:scarecrow + # Vanilla farmland settings + # 原版耕地设置 + vanilla-farmland: + # disable vanilla farmland moisture mechanics + # 禁用原版耕地湿润机制 + disable-moisture-mechanic: false + # prevent entities from trampling the farmland + # 防止玩家踩踏耕地 + prevent-trampling: false other-settings: # This option requires a skill-plugin hook diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 5871476..1c76cab 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -7,6 +7,7 @@ authors: [ XiaoMoMi ] depend: - ProtocolLib softdepend: + - Vault - ItemsAdder - Oraxen - PlaceholderAPI