9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-19 15:09:25 +00:00

added tick events

This commit is contained in:
XiaoMoMi
2025-08-29 16:44:46 +08:00
parent aea7664887
commit f15ec539e9
8 changed files with 155 additions and 8 deletions

View File

@@ -47,6 +47,7 @@ public abstract class AbstractActionManager<T> implements ActionManager<T> {
protected void registerBuiltInActions() { protected void registerBuiltInActions() {
this.registerCommandAction(); this.registerCommandAction();
this.registerBroadcastAction(); this.registerBroadcastAction();
this.registerConsumeWater();
this.registerNearbyMessage(); this.registerNearbyMessage();
this.registerNearbyActionBar(); this.registerNearbyActionBar();
this.registerNearbyTitle(); this.registerNearbyTitle();
@@ -157,6 +158,17 @@ public abstract class AbstractActionManager<T> implements ActionManager<T> {
} }
} }
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() { protected void registerBroadcastAction() {
registerAction((args, chance) -> new ActionBroadcast<>(plugin, args, chance), "broadcast"); registerAction((args, chance) -> new ActionBroadcast<>(plugin, args, chance), "broadcast");
} }

View File

@@ -0,0 +1,98 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<T> extends AbstractBuiltInAction<T> {
private final int yOffset;
private final int amount;
public ActionConsumeWater(
BukkitCustomCropsPlugin plugin,
Section section,
MathValue<T> chance
) {
super(plugin, chance);
this.yOffset = section.getInt("y-offset", -1);
this.amount = section.getInt("amount", 1);
}
@Override
protected void triggerAction(Context<T> context) {
Location location = requireNonNull(context.arg(ContextKeys.LOCATION));
Optional<CustomCropsWorld<?>> 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<CustomCropsBlockState> cropBlockState = world.get().getBlockState(pos3);
if (cropBlockState.isEmpty() || !(cropBlockState.get().type() instanceof CropBlock)) {
return;
}
}
Pos3 potLocation = pos3.add(0, this.yOffset, 0);
Optional<CustomCropsBlockState> 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;
}
}

View File

@@ -273,6 +273,14 @@ public class SprinklerBlock extends AbstractCustomCropsBlock {
world.removeBlockState(location); world.removeBlockState(location);
return; return;
} }
World bukkitWorld = world.bukkitWorld();
Location bukkitLocation = location.toLocation(bukkitWorld);
Context<CustomCropsBlockState> context = Context.block(state, bukkitLocation).arg(ContextKeys.OFFLINE, offline);
if (!RequirementManager.isSatisfied(context, config.tickRequirements())) {
return;
}
boolean updateState; boolean updateState;
if (!config.infinite()) { if (!config.infinite()) {
int water = water(state); int water = water(state);
@@ -284,10 +292,6 @@ public class SprinklerBlock extends AbstractCustomCropsBlock {
updateState = false; updateState = false;
} }
World bukkitWorld = world.bukkitWorld();
Location bukkitLocation = location.toLocation(bukkitWorld);
Context<CustomCropsBlockState> context = Context.block(state, bukkitLocation).arg(ContextKeys.OFFLINE, offline);
// place/remove entities on main thread // place/remove entities on main thread
BukkitCustomCropsPlugin.getInstance().getScheduler().sync().run(() -> { BukkitCustomCropsPlugin.getInstance().getScheduler().sync().run(() -> {

View File

@@ -31,7 +31,6 @@ import org.bukkit.entity.Player;
import java.util.*; import java.util.*;
public class PotConfigImpl implements PotConfig { public class PotConfigImpl implements PotConfig {
private final String id; private final String id;
private final boolean vanillaFarmland; private final boolean vanillaFarmland;
private final boolean disablePluginSystem; private final boolean disablePluginSystem;

View File

@@ -131,6 +131,14 @@ public interface SprinklerConfig {
@NotNull @NotNull
ExistenceForm existenceForm(); ExistenceForm existenceForm();
/**
* Gets the tick requirements for the sprinkler.
*
* @return An array of tick {@link Requirement}s, or null if none.
*/
@Nullable
Requirement<CustomCropsBlockState>[] tickRequirements();
/** /**
* Gets the placement requirements for the sprinkler. * Gets the placement requirements for the sprinkler.
* *
@@ -360,6 +368,14 @@ public interface SprinklerConfig {
*/ */
Builder useRequirements(Requirement<Player>[] useRequirements); Builder useRequirements(Requirement<Player>[] 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<CustomCropsBlockState>[] tickRequirements);
/** /**
* Sets the actions to be performed when the sprinkler is working. * Sets the actions to be performed when the sprinkler is working.
* *

View File

@@ -25,6 +25,7 @@ import net.momirealms.customcrops.api.misc.water.WateringMethod;
import net.momirealms.customcrops.api.requirement.Requirement; import net.momirealms.customcrops.api.requirement.Requirement;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet; import java.util.HashSet;
import java.util.Objects; import java.util.Objects;
@@ -46,6 +47,7 @@ public class SprinklerConfigImpl implements SprinklerConfig {
private final Requirement<Player>[] placeRequirements; private final Requirement<Player>[] placeRequirements;
private final Requirement<Player>[] breakRequirements; private final Requirement<Player>[] breakRequirements;
private final Requirement<Player>[] useRequirements; private final Requirement<Player>[] useRequirements;
private final Requirement<CustomCropsBlockState>[] tickRequirements;
private final Action<CustomCropsBlockState>[] workActions; private final Action<CustomCropsBlockState>[] workActions;
private final Action<Player>[] interactActions; private final Action<Player>[] interactActions;
private final Action<Player>[] reachLimitActions; private final Action<Player>[] reachLimitActions;
@@ -72,6 +74,7 @@ public class SprinklerConfigImpl implements SprinklerConfig {
Requirement<Player>[] placeRequirements, Requirement<Player>[] placeRequirements,
Requirement<Player>[] breakRequirements, Requirement<Player>[] breakRequirements,
Requirement<Player>[] useRequirements, Requirement<Player>[] useRequirements,
Requirement<CustomCropsBlockState>[] tickRequirements,
Action<CustomCropsBlockState>[] workActions, Action<CustomCropsBlockState>[] workActions,
Action<Player>[] interactActions, Action<Player>[] interactActions,
Action<Player>[] reachLimitActions, Action<Player>[] reachLimitActions,
@@ -95,6 +98,7 @@ public class SprinklerConfigImpl implements SprinklerConfig {
this.threeDItemWithWater = Objects.requireNonNullElse(threeDItemWithWater, threeDItem); this.threeDItemWithWater = Objects.requireNonNullElse(threeDItemWithWater, threeDItem);
this.placeRequirements = placeRequirements; this.placeRequirements = placeRequirements;
this.breakRequirements = breakRequirements; this.breakRequirements = breakRequirements;
this.tickRequirements = tickRequirements;
this.useRequirements = useRequirements; this.useRequirements = useRequirements;
this.workActions = workActions; this.workActions = workActions;
this.interactActions = interactActions; this.interactActions = interactActions;
@@ -179,6 +183,11 @@ public class SprinklerConfigImpl implements SprinklerConfig {
return existenceForm; return existenceForm;
} }
@Override
public @Nullable Requirement<CustomCropsBlockState>[] tickRequirements() {
return tickRequirements;
}
@Override @Override
public Requirement<Player>[] placeRequirements() { public Requirement<Player>[] placeRequirements() {
return placeRequirements; return placeRequirements;
@@ -248,6 +257,7 @@ public class SprinklerConfigImpl implements SprinklerConfig {
private Requirement<Player>[] placeRequirements; private Requirement<Player>[] placeRequirements;
private Requirement<Player>[] breakRequirements; private Requirement<Player>[] breakRequirements;
private Requirement<Player>[] useRequirements; private Requirement<Player>[] useRequirements;
private Requirement<CustomCropsBlockState>[] tickRequirements;
private Action<CustomCropsBlockState>[] workActions; private Action<CustomCropsBlockState>[] workActions;
private Action<Player>[] interactActions; private Action<Player>[] interactActions;
private Action<Player>[] reachLimitActions; private Action<Player>[] reachLimitActions;
@@ -263,7 +273,7 @@ public class SprinklerConfigImpl implements SprinklerConfig {
@Override @Override
public SprinklerConfig build() { public SprinklerConfig build() {
return new SprinklerConfigImpl(id, existenceForm, storage, range, infinite, wateringAmount, sprinklingAmount, potWhitelist, waterBar, twoDItem, threeDItem, threeDItemWithWater, 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 @Override
@@ -344,6 +354,12 @@ public class SprinklerConfigImpl implements SprinklerConfig {
return this; return this;
} }
@Override
public Builder tickRequirements(Requirement<CustomCropsBlockState>[] workRequirements) {
this.tickRequirements = workRequirements;
return this;
}
@Override @Override
public Builder breakRequirements(Requirement<Player>[] breakRequirements) { public Builder breakRequirements(Requirement<Player>[] breakRequirements) {
this.breakRequirements = breakRequirements; this.breakRequirements = breakRequirements;

View File

@@ -1,6 +1,6 @@
# Project settings # Project settings
# Rule: [major update].[feature update].[bug fix] # Rule: [major update].[feature update].[bug fix]
project_version=3.6.44.1 project_version=3.6.44.2
config_version=42 config_version=42
project_group=net.momirealms project_group=net.momirealms
@@ -33,7 +33,7 @@ caffeine_version=3.1.8
rtag_version=1.5.11 rtag_version=1.5.11
exp4j_version=0.4.8 exp4j_version=0.4.8
placeholder_api_version=2.11.6 placeholder_api_version=2.11.6
anti_grief_version=0.15 anti_grief_version=0.20
zstd_version=1.5.6-9 zstd_version=1.5.6-9
flow_nbt_version=2.0.2 flow_nbt_version=2.0.2
guava_version=33.3.1-jre guava_version=33.3.1-jre

View File

@@ -271,6 +271,7 @@ public class ConfigType {
ActionManager<Player> pam = BukkitCustomCropsPlugin.getInstance().getActionManager(Player.class); ActionManager<Player> pam = BukkitCustomCropsPlugin.getInstance().getActionManager(Player.class);
ActionManager<CustomCropsBlockState> bam = BukkitCustomCropsPlugin.getInstance().getActionManager(CustomCropsBlockState.class); ActionManager<CustomCropsBlockState> bam = BukkitCustomCropsPlugin.getInstance().getActionManager(CustomCropsBlockState.class);
RequirementManager<Player> prm = BukkitCustomCropsPlugin.getInstance().getRequirementManager(Player.class); RequirementManager<Player> prm = BukkitCustomCropsPlugin.getInstance().getRequirementManager(Player.class);
RequirementManager<CustomCropsBlockState> brm = BukkitCustomCropsPlugin.getInstance().getRequirementManager(CustomCropsBlockState.class);
SprinklerConfig config = SprinklerConfig.builder() SprinklerConfig config = SprinklerConfig.builder()
.id(id) .id(id)
@@ -295,6 +296,7 @@ public class ConfigType {
.useRequirements(prm.parseRequirements(section.getSection("requirements.use"), true)) .useRequirements(prm.parseRequirements(section.getSection("requirements.use"), true))
.placeRequirements(prm.parseRequirements(section.getSection("requirements.place"), true)) .placeRequirements(prm.parseRequirements(section.getSection("requirements.place"), true))
.breakRequirements(prm.parseRequirements(section.getSection("requirements.break"), true)) .breakRequirements(prm.parseRequirements(section.getSection("requirements.break"), true))
.tickRequirements(brm.parseRequirements(section.getSection("requirements.tick"), true))
.waterBar(section.contains("water-bar") ? WaterBar.of( .waterBar(section.contains("water-bar") ? WaterBar.of(
section.getString("water-bar.left", ""), section.getString("water-bar.left", ""),
section.getString("water-bar.empty", ""), section.getString("water-bar.empty", ""),