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 53af24d..7bb9b31 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 @@ -47,6 +47,7 @@ public abstract class AbstractActionManager implements ActionManager { protected void registerBuiltInActions() { this.registerCommandAction(); this.registerBroadcastAction(); + this.registerConsumeWater(); this.registerNearbyMessage(); this.registerNearbyActionBar(); this.registerNearbyTitle(); @@ -157,6 +158,17 @@ public abstract class AbstractActionManager implements ActionManager { } } + protected void registerConsumeWater() { + registerAction((args, chance) -> { + if (args instanceof Section section) { + return new ActionConsumeWater<>(plugin, section, chance); + } else { + plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at consume-water action which should be Section"); + return Action.empty(); + } + }, "consume-water"); + } + protected void registerBroadcastAction() { registerAction((args, chance) -> new ActionBroadcast<>(plugin, args, chance), "broadcast"); } diff --git a/api/src/main/java/net/momirealms/customcrops/api/action/builtin/ActionConsumeWater.java b/api/src/main/java/net/momirealms/customcrops/api/action/builtin/ActionConsumeWater.java new file mode 100644 index 0000000..4895a70 --- /dev/null +++ b/api/src/main/java/net/momirealms/customcrops/api/action/builtin/ActionConsumeWater.java @@ -0,0 +1,98 @@ +/* + * 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.action.builtin; + +import dev.dejvokep.boostedyaml.block.implementation.Section; +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.CustomForm; +import net.momirealms.customcrops.api.core.ExistenceForm; +import net.momirealms.customcrops.api.core.FurnitureRotation; +import net.momirealms.customcrops.api.core.block.CropBlock; +import net.momirealms.customcrops.api.core.block.PotBlock; +import net.momirealms.customcrops.api.core.mechanic.crop.VariationData; +import net.momirealms.customcrops.api.core.mechanic.fertilizer.Fertilizer; +import net.momirealms.customcrops.api.core.mechanic.fertilizer.FertilizerConfig; +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.misc.value.MathValue; +import org.bukkit.Location; + +import java.util.*; + +import static java.util.Objects.requireNonNull; + +public class ActionConsumeWater extends AbstractBuiltInAction { + private final int yOffset; + private final int amount; + + public ActionConsumeWater( + BukkitCustomCropsPlugin plugin, + Section section, + MathValue chance + ) { + super(plugin, chance); + this.yOffset = section.getInt("y-offset", -1); + this.amount = section.getInt("amount", 1); + } + + @Override + protected void triggerAction(Context context) { + Location location = requireNonNull(context.arg(ContextKeys.LOCATION)); + Optional> world = plugin.getWorldManager().getWorld(location.getWorld()); + if (world.isEmpty()) { + return; + } + Pos3 pos3 = Pos3.from(location); + if (context.holder() instanceof CustomCropsBlockState state) { + if (!(state.type() instanceof CropBlock)) { + return; + } + } else { + Optional cropBlockState = world.get().getBlockState(pos3); + if (cropBlockState.isEmpty() || !(cropBlockState.get().type() instanceof CropBlock)) { + return; + } + } + Pos3 potLocation = pos3.add(0, this.yOffset, 0); + Optional optionalPotState = world.get().getBlockState(potLocation); + if (optionalPotState.isEmpty()) { + return; + } + CustomCropsBlockState potState = optionalPotState.get(); + if (!(potState.type() instanceof PotBlock potBlock)) { + return; + } + + boolean changed = potBlock.consumeWater(potState, 1); + if (changed) { + potBlock.updateBlockAppearance(new Location(location.getWorld(), potLocation.x(), potLocation.y(), potLocation.z()), potState); + } + } + + public int amount() { + return amount; + } + + public int yOffset() { + return yOffset; + } +} diff --git a/api/src/main/java/net/momirealms/customcrops/api/core/block/SprinklerBlock.java b/api/src/main/java/net/momirealms/customcrops/api/core/block/SprinklerBlock.java index abae3d5..4cc3b8b 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/core/block/SprinklerBlock.java +++ b/api/src/main/java/net/momirealms/customcrops/api/core/block/SprinklerBlock.java @@ -273,6 +273,14 @@ public class SprinklerBlock extends AbstractCustomCropsBlock { world.removeBlockState(location); return; } + + World bukkitWorld = world.bukkitWorld(); + Location bukkitLocation = location.toLocation(bukkitWorld); + Context context = Context.block(state, bukkitLocation).arg(ContextKeys.OFFLINE, offline); + if (!RequirementManager.isSatisfied(context, config.tickRequirements())) { + return; + } + boolean updateState; if (!config.infinite()) { int water = water(state); @@ -284,10 +292,6 @@ public class SprinklerBlock extends AbstractCustomCropsBlock { updateState = false; } - World bukkitWorld = world.bukkitWorld(); - Location bukkitLocation = location.toLocation(bukkitWorld); - Context context = Context.block(state, bukkitLocation).arg(ContextKeys.OFFLINE, offline); - // place/remove entities on main thread BukkitCustomCropsPlugin.getInstance().getScheduler().sync().run(() -> { diff --git a/api/src/main/java/net/momirealms/customcrops/api/core/mechanic/pot/PotConfigImpl.java b/api/src/main/java/net/momirealms/customcrops/api/core/mechanic/pot/PotConfigImpl.java index c370fba..6699dbc 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/core/mechanic/pot/PotConfigImpl.java +++ b/api/src/main/java/net/momirealms/customcrops/api/core/mechanic/pot/PotConfigImpl.java @@ -31,7 +31,6 @@ import org.bukkit.entity.Player; import java.util.*; public class PotConfigImpl implements PotConfig { - private final String id; private final boolean vanillaFarmland; private final boolean disablePluginSystem; diff --git a/api/src/main/java/net/momirealms/customcrops/api/core/mechanic/sprinkler/SprinklerConfig.java b/api/src/main/java/net/momirealms/customcrops/api/core/mechanic/sprinkler/SprinklerConfig.java index 73f8570..600e666 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/core/mechanic/sprinkler/SprinklerConfig.java +++ b/api/src/main/java/net/momirealms/customcrops/api/core/mechanic/sprinkler/SprinklerConfig.java @@ -131,6 +131,14 @@ public interface SprinklerConfig { @NotNull ExistenceForm existenceForm(); + /** + * Gets the tick requirements for the sprinkler. + * + * @return An array of tick {@link Requirement}s, or null if none. + */ + @Nullable + Requirement[] tickRequirements(); + /** * Gets the placement requirements for the sprinkler. * @@ -360,6 +368,14 @@ public interface SprinklerConfig { */ Builder useRequirements(Requirement[] useRequirements); + /** + * Sets the requirements for the sprinkler to tick. + * + * @param tickRequirements An array of {@link Requirement} instances for ticking. + * @return The current instance of the Builder. + */ + Builder tickRequirements(Requirement[] tickRequirements); + /** * Sets the actions to be performed when the sprinkler is working. * diff --git a/api/src/main/java/net/momirealms/customcrops/api/core/mechanic/sprinkler/SprinklerConfigImpl.java b/api/src/main/java/net/momirealms/customcrops/api/core/mechanic/sprinkler/SprinklerConfigImpl.java index d232768..ce29154 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/core/mechanic/sprinkler/SprinklerConfigImpl.java +++ b/api/src/main/java/net/momirealms/customcrops/api/core/mechanic/sprinkler/SprinklerConfigImpl.java @@ -25,6 +25,7 @@ import net.momirealms.customcrops.api.misc.water.WateringMethod; import net.momirealms.customcrops.api.requirement.Requirement; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.HashSet; import java.util.Objects; @@ -46,6 +47,7 @@ public class SprinklerConfigImpl implements SprinklerConfig { private final Requirement[] placeRequirements; private final Requirement[] breakRequirements; private final Requirement[] useRequirements; + private final Requirement[] tickRequirements; private final Action[] workActions; private final Action[] interactActions; private final Action[] reachLimitActions; @@ -72,6 +74,7 @@ public class SprinklerConfigImpl implements SprinklerConfig { Requirement[] placeRequirements, Requirement[] breakRequirements, Requirement[] useRequirements, + Requirement[] tickRequirements, Action[] workActions, Action[] interactActions, Action[] reachLimitActions, @@ -95,6 +98,7 @@ public class SprinklerConfigImpl implements SprinklerConfig { this.threeDItemWithWater = Objects.requireNonNullElse(threeDItemWithWater, threeDItem); this.placeRequirements = placeRequirements; this.breakRequirements = breakRequirements; + this.tickRequirements = tickRequirements; this.useRequirements = useRequirements; this.workActions = workActions; this.interactActions = interactActions; @@ -179,6 +183,11 @@ public class SprinklerConfigImpl implements SprinklerConfig { return existenceForm; } + @Override + public @Nullable Requirement[] tickRequirements() { + return tickRequirements; + } + @Override public Requirement[] placeRequirements() { return placeRequirements; @@ -248,6 +257,7 @@ public class SprinklerConfigImpl implements SprinklerConfig { private Requirement[] placeRequirements; private Requirement[] breakRequirements; private Requirement[] useRequirements; + private Requirement[] tickRequirements; private Action[] workActions; private Action[] interactActions; private Action[] reachLimitActions; @@ -263,7 +273,7 @@ public class SprinklerConfigImpl implements SprinklerConfig { @Override public SprinklerConfig build() { return new SprinklerConfigImpl(id, existenceForm, storage, range, infinite, wateringAmount, sprinklingAmount, potWhitelist, waterBar, twoDItem, threeDItem, threeDItemWithWater, - placeRequirements, breakRequirements, useRequirements, workActions, interactActions, reachLimitActions, addWaterActions, placeActions, breakActions, fullWaterActions, wateringMethods); + placeRequirements, breakRequirements, useRequirements, tickRequirements, workActions, interactActions, reachLimitActions, addWaterActions, placeActions, breakActions, fullWaterActions, wateringMethods); } @Override @@ -344,6 +354,12 @@ public class SprinklerConfigImpl implements SprinklerConfig { return this; } + @Override + public Builder tickRequirements(Requirement[] workRequirements) { + this.tickRequirements = workRequirements; + return this; + } + @Override public Builder breakRequirements(Requirement[] breakRequirements) { this.breakRequirements = breakRequirements; diff --git a/gradle.properties b/gradle.properties index ff6f01b..1c58c11 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=3.6.44.1 +project_version=3.6.44.2 config_version=42 project_group=net.momirealms @@ -33,7 +33,7 @@ caffeine_version=3.1.8 rtag_version=1.5.11 exp4j_version=0.4.8 placeholder_api_version=2.11.6 -anti_grief_version=0.15 +anti_grief_version=0.20 zstd_version=1.5.6-9 flow_nbt_version=2.0.2 guava_version=33.3.1-jre diff --git a/plugin/src/main/java/net/momirealms/customcrops/bukkit/config/ConfigType.java b/plugin/src/main/java/net/momirealms/customcrops/bukkit/config/ConfigType.java index 04fe107..73d58aa 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/bukkit/config/ConfigType.java +++ b/plugin/src/main/java/net/momirealms/customcrops/bukkit/config/ConfigType.java @@ -271,6 +271,7 @@ public class ConfigType { ActionManager pam = BukkitCustomCropsPlugin.getInstance().getActionManager(Player.class); ActionManager bam = BukkitCustomCropsPlugin.getInstance().getActionManager(CustomCropsBlockState.class); RequirementManager prm = BukkitCustomCropsPlugin.getInstance().getRequirementManager(Player.class); + RequirementManager brm = BukkitCustomCropsPlugin.getInstance().getRequirementManager(CustomCropsBlockState.class); SprinklerConfig config = SprinklerConfig.builder() .id(id) @@ -295,6 +296,7 @@ public class ConfigType { .useRequirements(prm.parseRequirements(section.getSection("requirements.use"), true)) .placeRequirements(prm.parseRequirements(section.getSection("requirements.place"), true)) .breakRequirements(prm.parseRequirements(section.getSection("requirements.break"), true)) + .tickRequirements(brm.parseRequirements(section.getSection("requirements.tick"), true)) .waterBar(section.contains("water-bar") ? WaterBar.of( section.getString("water-bar.left", ""), section.getString("water-bar.empty", ""),