From a21af25570065e3212d261c54f3911766e7638bc Mon Sep 17 00:00:00 2001 From: XiaoMoMi <70987828+Xiao-MoMi@users.noreply.github.com> Date: Tue, 3 Sep 2024 01:28:01 +0800 Subject: [PATCH] Implement logic for dead crops --- .../api/action/AbstractActionManager.java | 13 +--- .../customcrops/api/context/ContextKeys.java | 3 + .../api/core/AbstractCustomEventListener.java | 31 +++------ .../api/core/BuiltInBlockMechanics.java | 1 + .../customcrops/api/core/ConfigManager.java | 5 ++ .../customcrops/api/core/Registries.java | 1 + .../customcrops/api/core/block/CropBlock.java | 60 ++--------------- .../customcrops/api/core/block/DeadCrop.java | 66 +++++++++++++++++++ .../customcrops/api/core/block/PotBlock.java | 15 +++++ .../api/core/item/WateringCanItem.java | 4 +- .../api/core/world/CustomCropsChunk.java | 1 - .../bukkit/BukkitCustomCropsPluginImpl.java | 1 + .../command/feature/ForceTickCommand.java | 2 - .../command/feature/GetDateCommand.java | 1 - .../command/feature/SetDateCommand.java | 5 -- .../command/feature/SetSeasonCommand.java | 4 -- .../bukkit/config/BukkitConfigManager.java | 27 ++++++-- plugin/src/main/resources/config.yml | 3 + 18 files changed, 137 insertions(+), 106 deletions(-) create mode 100644 api/src/main/java/net/momirealms/customcrops/api/core/block/DeadCrop.java diff --git a/api/src/main/java/net/momirealms/customcrops/api/action/AbstractActionManager.java b/api/src/main/java/net/momirealms/customcrops/api/action/AbstractActionManager.java index 033a9d1..e808a58 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/action/AbstractActionManager.java +++ b/api/src/main/java/net/momirealms/customcrops/api/action/AbstractActionManager.java @@ -758,17 +758,8 @@ public abstract class AbstractActionManager implements ActionManager { return; } if (applyCorrection) { - Optional optionalState = optionalWorld.get().getBlockState(pos3); - if (optionalState.isPresent()) { - if (optionalState.get().type() instanceof CropBlock cropBlock) { - CropConfig config = cropBlock.config(optionalState.get()); - int point = cropBlock.point(optionalState.get()); - if (config != null) { - CropStageConfig stageConfig = config.stageWithModelByPoint(point); - location.add(0,stageConfig.displayInfoOffset(),0); - } - } - } + String itemID = plugin.getItemManager().anyID(location.clone().add(0,1,0)); + location.add(0,ConfigManager.getOffset(itemID),0); } ArrayList viewers = new ArrayList<>(); if (onlyShowToOne) { diff --git a/api/src/main/java/net/momirealms/customcrops/api/context/ContextKeys.java b/api/src/main/java/net/momirealms/customcrops/api/context/ContextKeys.java index dbe6cf8..8a846b0 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/context/ContextKeys.java +++ b/api/src/main/java/net/momirealms/customcrops/api/context/ContextKeys.java @@ -42,6 +42,9 @@ public class ContextKeys { public static final ContextKeys SLOT = of("slot", EquipmentSlot.class); public static final ContextKeys TEMP_NEAR_PLAYER = of("near", String.class); public static final ContextKeys OFFLINE = of("offline", Boolean.class); + public static final ContextKeys ICON = of("icon", String.class); + public static final ContextKeys MAX_TIMES = of("max_times", Integer.class); + public static final ContextKeys LEFT_TIMES = of("left_times", Integer.class); public static final ContextKeys PLAYER_INSTANCE = of("player_instance", Player.class); private final String key; diff --git a/api/src/main/java/net/momirealms/customcrops/api/core/AbstractCustomEventListener.java b/api/src/main/java/net/momirealms/customcrops/api/core/AbstractCustomEventListener.java index dcf5e14..d1f5309 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/core/AbstractCustomEventListener.java +++ b/api/src/main/java/net/momirealms/customcrops/api/core/AbstractCustomEventListener.java @@ -50,7 +50,10 @@ import org.bukkit.event.player.PlayerItemDamageEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; -import java.util.*; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; public abstract class AbstractCustomEventListener implements Listener { @@ -324,27 +327,8 @@ public abstract class AbstractCustomEventListener implements Listener { Context context = Context.player(null); context.arg(ContextKeys.LOCATION, location); boneMeal.triggerActions(context); - int afterPoints = Math.min(point + boneMeal.rollPoint(), cropConfig.maxPoints()); cropBlock.point(state, afterPoints); - - String afterStage = null; - ExistenceForm afterForm = null; - int tempPoints = afterPoints; - while (tempPoints >= 0) { - Map.Entry afterEntry = cropConfig.getFloorStageEntry(tempPoints); - CropStageConfig after = afterEntry.getValue(); - if (after.stageID() != null) { - afterStage = after.stageID(); - afterForm = after.existenceForm(); - break; - } - tempPoints = after.point() - 1; - } - - Objects.requireNonNull(afterForm); - Objects.requireNonNull(afterStage); - Context blockContext = Context.block(state); blockContext.arg(ContextKeys.LOCATION, LocationUtils.toBlockLocation(location)); for (int i = point + 1; i <= afterPoints; i++) { @@ -353,14 +337,15 @@ public abstract class AbstractCustomEventListener implements Listener { ActionManager.trigger(blockContext, stage.growActions()); } } - - // TODO if the block model chanegs + CropStageConfig currentStage = cropConfig.stageWithModelByPoint(point); + CropStageConfig afterStage = cropConfig.stageWithModelByPoint(afterPoints); + if (currentStage == afterStage) return; Location bukkitLocation = location.toLocation(world.bukkitWorld()); FurnitureRotation rotation = BukkitCustomCropsPlugin.getInstance().getItemManager().remove(bukkitLocation, ExistenceForm.ANY); if (rotation == FurnitureRotation.NONE && cropConfig.rotation()) { rotation = FurnitureRotation.random(); } - BukkitCustomCropsPlugin.getInstance().getItemManager().place(bukkitLocation, afterForm, afterStage, rotation); + BukkitCustomCropsPlugin.getInstance().getItemManager().place(bukkitLocation, afterStage.existenceForm(), Objects.requireNonNull(afterStage.stageID()), rotation); } } } diff --git a/api/src/main/java/net/momirealms/customcrops/api/core/BuiltInBlockMechanics.java b/api/src/main/java/net/momirealms/customcrops/api/core/BuiltInBlockMechanics.java index 986697d..3bbc3eb 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/core/BuiltInBlockMechanics.java +++ b/api/src/main/java/net/momirealms/customcrops/api/core/BuiltInBlockMechanics.java @@ -27,6 +27,7 @@ import java.util.Objects; public class BuiltInBlockMechanics { public static final BuiltInBlockMechanics CROP = create("crop"); + public static final BuiltInBlockMechanics DEAD_CROP = create("dead_crop"); public static final BuiltInBlockMechanics SPRINKLER = create("sprinkler"); public static final BuiltInBlockMechanics GREENHOUSE = create("greenhouse"); public static final BuiltInBlockMechanics POT = create("pot"); diff --git a/api/src/main/java/net/momirealms/customcrops/api/core/ConfigManager.java b/api/src/main/java/net/momirealms/customcrops/api/core/ConfigManager.java index 6e05e14..7d9d4fd 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/core/ConfigManager.java +++ b/api/src/main/java/net/momirealms/customcrops/api/core/ConfigManager.java @@ -63,12 +63,17 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable { protected boolean preventTrampling; protected boolean disableMoistureMechanic; + protected HashMap offsets = new HashMap<>(); public ConfigManager(BukkitCustomCropsPlugin plugin) { this.plugin = plugin; instance = this; } + public static double getOffset(String id) { + return instance.offsets.getOrDefault(id, 0d); + } + public static boolean syncSeasons() { return instance.syncSeasons; } diff --git a/api/src/main/java/net/momirealms/customcrops/api/core/Registries.java b/api/src/main/java/net/momirealms/customcrops/api/core/Registries.java index d9a7884..7a2f192 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/core/Registries.java +++ b/api/src/main/java/net/momirealms/customcrops/api/core/Registries.java @@ -57,4 +57,5 @@ public class Registries { public static final ClearableRegistry ITEM_TO_POT = new ClearableMappedRegistry<>(Key.key("fast_lookup", "item_to_pot")); public static final ClearableRegistry ITEM_TO_SPRINKLER = new ClearableMappedRegistry<>(Key.key("fast_lookup", "item_to_sprinkler")); public static final ClearableRegistry ITEM_TO_WATERING_CAN = new ClearableMappedRegistry<>(Key.key("fast_lookup", "item_to_wateringcan")); + public static final ClearableRegistry ITEM_TO_DEAD_CROP = new ClearableMappedRegistry<>(Key.key("fast_lookup", "item_to_dead_crop")); } diff --git a/api/src/main/java/net/momirealms/customcrops/api/core/block/CropBlock.java b/api/src/main/java/net/momirealms/customcrops/api/core/block/CropBlock.java index 474e2a1..3f474b4 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/core/block/CropBlock.java +++ b/api/src/main/java/net/momirealms/customcrops/api/core/block/CropBlock.java @@ -225,22 +225,7 @@ public class CropBlock extends AbstractCustomCropsBlock { int afterPoints = Math.min(point + boneMeal.rollPoint(), cropConfig.maxPoints()); point(state, afterPoints); - String afterStage = null; - ExistenceForm afterForm = null; - int tempPoints = afterPoints; - while (tempPoints >= 0) { - Map.Entry afterEntry = cropConfig.getFloorStageEntry(tempPoints); - CropStageConfig after = afterEntry.getValue(); - if (after.stageID() != null) { - afterStage = after.stageID(); - afterForm = after.existenceForm(); - break; - } - tempPoints = after.point() - 1; - } - - Objects.requireNonNull(afterForm); - Objects.requireNonNull(afterStage); + CropStageConfig nextStage = cropConfig.stageWithModelByPoint(afterPoints); Context blockContext = Context.block(state); blockContext.arg(ContextKeys.LOCATION, LocationUtils.toBlockLocation(location)); @@ -251,13 +236,13 @@ public class CropBlock extends AbstractCustomCropsBlock { } } - if (Objects.equals(afterStage, event.relatedID())) return; + if (Objects.equals(nextStage.stageID(), event.relatedID())) return; Location bukkitLocation = location.toLocation(world.bukkitWorld()); FurnitureRotation rotation = BukkitCustomCropsPlugin.getInstance().getItemManager().remove(bukkitLocation, ExistenceForm.ANY); if (rotation == FurnitureRotation.NONE && cropConfig.rotation()) { rotation = FurnitureRotation.random(); } - BukkitCustomCropsPlugin.getInstance().getItemManager().place(bukkitLocation, afterForm, afterStage, rotation); + BukkitCustomCropsPlugin.getInstance().getItemManager().place(bukkitLocation, nextStage.existenceForm(), Objects.requireNonNull(nextStage.stageID()), rotation); return; } } @@ -363,39 +348,8 @@ public class CropBlock extends AbstractCustomCropsBlock { int afterPoints = Math.min(previousPoint + pointToAdd, config.maxPoints()); point(state, afterPoints); - int tempPoints = previousPoint; - String preStage = null; - while (tempPoints >= 0) { - Map.Entry preEntry = config.getFloorStageEntry(tempPoints); - CropStageConfig pre = preEntry.getValue(); - if (pre.stageID() != null) { - preStage = pre.stageID(); - break; - } - tempPoints = pre.point() - 1; - } - - String afterStage = null; - ExistenceForm afterForm = null; - tempPoints = afterPoints; - while (tempPoints >= 0) { - Map.Entry afterEntry = config.getFloorStageEntry(tempPoints); - CropStageConfig after = afterEntry.getValue(); - if (after.stageID() != null) { - afterStage = after.stageID(); - afterForm = after.existenceForm(); - break; - } - tempPoints = after.point() - 1; - } - - final String finalPreStage = preStage; - final String finalAfterStage = afterStage; - final ExistenceForm finalAfterForm = afterForm; - - Objects.requireNonNull(finalAfterStage); - Objects.requireNonNull(finalPreStage); - Objects.requireNonNull(finalAfterForm); + CropStageConfig currentStage = config.stageWithModelByPoint(previousPoint); + CropStageConfig nextStage = config.stageWithModelByPoint(afterPoints); BukkitCustomCropsPlugin.getInstance().getScheduler().sync().run(() -> { for (int i = previousPoint + 1; i <= afterPoints; i++) { @@ -404,12 +358,12 @@ public class CropBlock extends AbstractCustomCropsBlock { ActionManager.trigger(context, stage.growActions()); } } - if (Objects.equals(finalAfterStage, finalPreStage)) return; + if (currentStage == nextStage) return; FurnitureRotation rotation = BukkitCustomCropsPlugin.getInstance().getItemManager().remove(bukkitLocation, ExistenceForm.ANY); if (rotation == FurnitureRotation.NONE && config.rotation()) { rotation = FurnitureRotation.random(); } - BukkitCustomCropsPlugin.getInstance().getItemManager().place(bukkitLocation, finalAfterForm, finalAfterStage, rotation); + BukkitCustomCropsPlugin.getInstance().getItemManager().place(bukkitLocation, nextStage.existenceForm(), Objects.requireNonNull(nextStage.stageID()), rotation); }, bukkitLocation); } diff --git a/api/src/main/java/net/momirealms/customcrops/api/core/block/DeadCrop.java b/api/src/main/java/net/momirealms/customcrops/api/core/block/DeadCrop.java new file mode 100644 index 0000000..9d2bdda --- /dev/null +++ b/api/src/main/java/net/momirealms/customcrops/api/core/block/DeadCrop.java @@ -0,0 +1,66 @@ +/* + * 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.api.core.block; + +import net.momirealms.customcrops.api.BukkitCustomCropsPlugin; +import net.momirealms.customcrops.api.context.Context; +import net.momirealms.customcrops.api.context.ContextKeys; +import net.momirealms.customcrops.api.core.BuiltInBlockMechanics; +import net.momirealms.customcrops.api.core.Registries; +import net.momirealms.customcrops.api.core.world.CustomCropsBlockState; +import net.momirealms.customcrops.api.core.world.CustomCropsWorld; +import net.momirealms.customcrops.api.core.world.Pos3; +import net.momirealms.customcrops.api.core.wrapper.WrappedInteractEvent; +import net.momirealms.customcrops.api.util.LocationUtils; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +public class DeadCrop extends AbstractCustomCropsBlock { + + public DeadCrop() { + super(BuiltInBlockMechanics.DEAD_CROP.key()); + } + + @Override + public boolean isBlockInstance(String id) { + return Registries.ITEM_TO_DEAD_CROP.containsKey(id); + } + + @Override + public void onInteract(WrappedInteractEvent event) { + final Player player = event.player(); + Context context = Context.player(player); + // data first + CustomCropsWorld world = event.world(); + Location location = event.location(); + context.arg(ContextKeys.SLOT, event.hand()); + // check pot below + Location potLocation = location.clone().subtract(0,1,0); + String blockBelowID = BukkitCustomCropsPlugin.getInstance().getItemManager().blockID(potLocation.getBlock()); + PotConfig potConfig = Registries.ITEM_TO_POT.get(blockBelowID); + if (potConfig != null) { + context.arg(ContextKeys.LOCATION, LocationUtils.toBlockLocation(potLocation)); + PotBlock potBlock = (PotBlock) BuiltInBlockMechanics.POT.mechanic(); + assert potBlock != null; + // fix or get data + CustomCropsBlockState potState = potBlock.fixOrGetState(world, Pos3.from(potLocation), potConfig, event.relatedID()); + if (potBlock.tryWateringPot(player, context, potState, event.hand(), event.itemID(), potConfig, potLocation, event.itemInHand())) + return; + } + } +} diff --git a/api/src/main/java/net/momirealms/customcrops/api/core/block/PotBlock.java b/api/src/main/java/net/momirealms/customcrops/api/core/block/PotBlock.java index 0312001..c9a90b0 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/core/block/PotBlock.java +++ b/api/src/main/java/net/momirealms/customcrops/api/core/block/PotBlock.java @@ -245,6 +245,21 @@ public class PotBlock extends AbstractCustomCropsBlock { if (tryWateringPot(player, context, state, event.hand(), event.itemID(), potConfig, location, itemInHand)) return; + int water = water(state); + context.arg(ContextKeys.STORAGE, potConfig.storage()); + context.arg(ContextKeys.CURRENT_WATER, water); + context.arg(ContextKeys.WATER_BAR, Optional.ofNullable(potConfig.waterBar()).map(it -> it.getWaterBar(water, potConfig.storage())).orElse("")); + Fertilizer[] fertilizers = fertilizers(state); + // for backward compatibility + for (Fertilizer latest : fertilizers) { + FertilizerConfig config = latest.config(); + if (config != null) { + context.arg(ContextKeys.ICON, config.icon()); + context.arg(ContextKeys.MAX_TIMES, config.times()); + context.arg(ContextKeys.LEFT_TIMES, latest.times()); + break; + } + } ActionManager.trigger(context, potConfig.interactActions()); } diff --git a/api/src/main/java/net/momirealms/customcrops/api/core/item/WateringCanItem.java b/api/src/main/java/net/momirealms/customcrops/api/core/item/WateringCanItem.java index e06f87d..aaa1953 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/core/item/WateringCanItem.java +++ b/api/src/main/java/net/momirealms/customcrops/api/core/item/WateringCanItem.java @@ -239,8 +239,8 @@ public class WateringCanItem extends AbstractCustomCropsItem { } // if the clicked block is a crop, correct the target block - List cropConfigs = Registries.STAGE_TO_CROP_UNSAFE.get(event.relatedID()); - if (cropConfigs != null) { + List cropConfigs = Registries.STAGE_TO_CROP_UNSAFE.get(targetBlockID); + if (cropConfigs != null || Registries.ITEM_TO_DEAD_CROP.containsKey(targetBlockID)) { // is a crop targetLocation = targetLocation.subtract(0,1,0); targetBlockID = BukkitCustomCropsPlugin.getInstance().getItemManager().blockID(targetLocation); diff --git a/api/src/main/java/net/momirealms/customcrops/api/core/world/CustomCropsChunk.java b/api/src/main/java/net/momirealms/customcrops/api/core/world/CustomCropsChunk.java index 0ae1cb8..3adc0b0 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/core/world/CustomCropsChunk.java +++ b/api/src/main/java/net/momirealms/customcrops/api/core/world/CustomCropsChunk.java @@ -19,7 +19,6 @@ package net.momirealms.customcrops.api.core.world; import org.jetbrains.annotations.NotNull; -import java.util.Collection; import java.util.Optional; import java.util.PriorityQueue; import java.util.Set; 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 128eecf..b92c28c 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/bukkit/BukkitCustomCropsPluginImpl.java +++ b/plugin/src/main/java/net/momirealms/customcrops/bukkit/BukkitCustomCropsPluginImpl.java @@ -232,6 +232,7 @@ public class BukkitCustomCropsPluginImpl extends BukkitCustomCropsPlugin { registryAccess.registerBlockMechanic(new ScarecrowBlock()); registryAccess.registerBlockMechanic(new SprinklerBlock()); registryAccess.registerBlockMechanic(new GreenhouseBlock()); + registryAccess.registerBlockMechanic(new DeadCrop()); registryAccess.registerItemMechanic(new SeedItem()); registryAccess.registerItemMechanic(new WateringCanItem()); diff --git a/plugin/src/main/java/net/momirealms/customcrops/bukkit/command/feature/ForceTickCommand.java b/plugin/src/main/java/net/momirealms/customcrops/bukkit/command/feature/ForceTickCommand.java index 92ea411..0355b92 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/bukkit/command/feature/ForceTickCommand.java +++ b/plugin/src/main/java/net/momirealms/customcrops/bukkit/command/feature/ForceTickCommand.java @@ -27,7 +27,6 @@ import net.momirealms.customcrops.common.command.CustomCropsCommandManager; import net.momirealms.customcrops.common.locale.MessageConstants; import net.momirealms.customcrops.common.util.Key; import net.momirealms.customcrops.common.util.QuadConsumer; -import net.momirealms.customcrops.common.util.TriConsumer; import org.bukkit.NamespacedKey; import org.bukkit.World; import org.bukkit.command.CommandSender; @@ -39,7 +38,6 @@ import org.incendo.cloud.bukkit.parser.WorldParser; import org.incendo.cloud.context.CommandContext; import org.incendo.cloud.context.CommandInput; import org.incendo.cloud.parser.standard.EnumParser; -import org.incendo.cloud.parser.standard.StringParser; import org.incendo.cloud.suggestion.Suggestion; import org.incendo.cloud.suggestion.SuggestionProvider; diff --git a/plugin/src/main/java/net/momirealms/customcrops/bukkit/command/feature/GetDateCommand.java b/plugin/src/main/java/net/momirealms/customcrops/bukkit/command/feature/GetDateCommand.java index f156d02..db163c5 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/bukkit/command/feature/GetDateCommand.java +++ b/plugin/src/main/java/net/momirealms/customcrops/bukkit/command/feature/GetDateCommand.java @@ -19,7 +19,6 @@ package net.momirealms.customcrops.bukkit.command.feature; import net.kyori.adventure.text.Component; import net.momirealms.customcrops.api.BukkitCustomCropsPlugin; -import net.momirealms.customcrops.api.core.world.Season; import net.momirealms.customcrops.api.integration.SeasonProvider; import net.momirealms.customcrops.bukkit.command.BukkitCommandFeature; import net.momirealms.customcrops.common.command.CustomCropsCommandManager; diff --git a/plugin/src/main/java/net/momirealms/customcrops/bukkit/command/feature/SetDateCommand.java b/plugin/src/main/java/net/momirealms/customcrops/bukkit/command/feature/SetDateCommand.java index 2acfa10..3a9207e 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/bukkit/command/feature/SetDateCommand.java +++ b/plugin/src/main/java/net/momirealms/customcrops/bukkit/command/feature/SetDateCommand.java @@ -21,7 +21,6 @@ import net.kyori.adventure.text.Component; import net.momirealms.customcrops.api.BukkitCustomCropsPlugin; import net.momirealms.customcrops.api.core.ConfigManager; import net.momirealms.customcrops.api.core.world.CustomCropsWorld; -import net.momirealms.customcrops.api.core.world.Season; import net.momirealms.customcrops.api.integration.SeasonProvider; import net.momirealms.customcrops.bukkit.command.BukkitCommandFeature; import net.momirealms.customcrops.common.command.CustomCropsCommandManager; @@ -32,11 +31,7 @@ import org.incendo.cloud.Command; import org.incendo.cloud.CommandManager; import org.incendo.cloud.bukkit.parser.WorldParser; import org.incendo.cloud.parser.standard.IntegerParser; -import org.incendo.cloud.parser.standard.StringParser; -import org.incendo.cloud.suggestion.Suggestion; -import org.incendo.cloud.suggestion.SuggestionProvider; -import java.util.Locale; import java.util.Optional; public class SetDateCommand extends BukkitCommandFeature { diff --git a/plugin/src/main/java/net/momirealms/customcrops/bukkit/command/feature/SetSeasonCommand.java b/plugin/src/main/java/net/momirealms/customcrops/bukkit/command/feature/SetSeasonCommand.java index c5bf431..df337be 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/bukkit/command/feature/SetSeasonCommand.java +++ b/plugin/src/main/java/net/momirealms/customcrops/bukkit/command/feature/SetSeasonCommand.java @@ -28,19 +28,15 @@ import net.momirealms.customcrops.common.command.CustomCropsCommandManager; import net.momirealms.customcrops.common.locale.MessageConstants; import org.bukkit.World; import org.bukkit.command.CommandSender; -import org.checkerframework.checker.nullness.qual.NonNull; import org.incendo.cloud.Command; import org.incendo.cloud.CommandManager; import org.incendo.cloud.bukkit.parser.WorldParser; -import org.incendo.cloud.context.CommandContext; -import org.incendo.cloud.context.CommandInput; import org.incendo.cloud.parser.standard.StringParser; import org.incendo.cloud.suggestion.Suggestion; import org.incendo.cloud.suggestion.SuggestionProvider; import java.util.Locale; import java.util.Optional; -import java.util.concurrent.CompletableFuture; public class SetSeasonCommand extends BukkitCommandFeature { 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 283277f..6c3a726 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 @@ -30,10 +30,7 @@ import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings; import dev.dejvokep.boostedyaml.utils.format.NodeRole; import net.momirealms.customcrops.api.BukkitCustomCropsPlugin; import net.momirealms.customcrops.api.core.*; -import net.momirealms.customcrops.api.core.block.CropConfig; -import net.momirealms.customcrops.api.core.block.CropStageConfig; -import net.momirealms.customcrops.api.core.block.PotConfig; -import net.momirealms.customcrops.api.core.block.SprinklerConfig; +import net.momirealms.customcrops.api.core.block.*; import net.momirealms.customcrops.api.core.item.FertilizerConfig; import net.momirealms.customcrops.api.core.item.WateringCanConfig; import net.momirealms.customcrops.common.helper.AdventureHelper; @@ -132,6 +129,16 @@ public class BukkitConfigManager extends ConfigManager { preventTrampling = config.getBoolean("mechanics.vanilla-farmland.prevent-trampling", false); disableMoistureMechanic = config.getBoolean("mechanics.vanilla-farmland.disable-moisture-mechanic", false); + + offsets.clear(); + Section section = config.getSection("mechanics.hologram-offset-correction"); + if (section != null) { + for (Map.Entry entry : section.getStringRouteMappedValues(false).entrySet()) { + if (entry.getValue() instanceof Number n) { + offsets.put(entry.getKey(), n.doubleValue()); + } + } + } } @Override @@ -228,9 +235,21 @@ public class BukkitConfigManager extends ConfigManager { Registries.CROP.register(config.id(), config); Registries.SEED_TO_CROP.register(config.seed(), config); Registries.ITEMS.register(config.seed(), BuiltInItemMechanics.SEED.mechanic()); + for (DeathCondition condition : config.deathConditions()) { + String deadStage = condition.deathStage(); + if (deadStage != null) { + if (!Registries.BLOCKS.containsKey(deadStage)) { + Registries.BLOCKS.register(deadStage, BuiltInBlockMechanics.DEAD_CROP.mechanic()); + } + if (!Registries.ITEM_TO_DEAD_CROP.containsKey(deadStage)) { + Registries.ITEM_TO_DEAD_CROP.register(deadStage, 0); + } + } + } for (CropStageConfig stageConfig : config.stages()) { String stageID = stageConfig.stageID(); if (stageID != null) { + offsets.put(stageID, stageConfig.displayInfoOffset()); List list = Registries.STAGE_TO_CROP_UNSAFE.get(stageID); if (list != null) { list.add(config); diff --git a/plugin/src/main/resources/config.yml b/plugin/src/main/resources/config.yml index cc585c9..8e412eb 100644 --- a/plugin/src/main/resources/config.yml +++ b/plugin/src/main/resources/config.yml @@ -117,6 +117,9 @@ mechanics: disable-moisture-mechanic: false # Prevent entities from trampling the farmland prevent-trampling: false + # Set hologram offset correction for other blocks + hologram-offset-correction: + "{0}crop_stage_death": 0 other-settings: # It's recommended to use MiniMessage format. If you insist on using legacy color code "&", enable the support below. # Disable this would improve performance