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

implement watering can

This commit is contained in:
XiaoMoMi
2024-09-01 01:39:51 +08:00
parent f632b99554
commit 139cd9649d
62 changed files with 210 additions and 146 deletions

View File

@@ -30,6 +30,9 @@ import java.util.Objects;
public class ContextKeys<T> {
public static final ContextKeys<Location> LOCATION = of("location", Location.class);
public static final ContextKeys<String> WATER_BAR = of("water_bar", String.class);
public static final ContextKeys<Integer> CURRENT_WATER = of("current", Integer.class);
public static final ContextKeys<Integer> STORAGE = of("storage", Integer.class);
public static final ContextKeys<Integer> X = of("x", Integer.class);
public static final ContextKeys<Integer> Y = of("y", Integer.class);
public static final ContextKeys<Integer> Z = of("z", Integer.class);

View File

@@ -69,7 +69,8 @@ public abstract class AbstractCustomEventListener implements Listener {
return;
this.itemManager.handlePlayerInteractAir(
event.getPlayer(),
event.getHand(), event.getItem()
event.getHand(),
event.getItem()
);
}

View File

@@ -57,7 +57,7 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
protected boolean syncSeasons;
protected String referenceWorld;
protected String[] itemDetectOrder;
protected String[] itemDetectOrder = new String[0];
protected double[] defaultQualityRatio;

View File

@@ -19,7 +19,6 @@ package net.momirealms.customcrops.api.core;
public enum InteractionResult {
SUCCESS,
FAIL,
COMPLETE,
PASS
}

View File

@@ -18,6 +18,7 @@
package net.momirealms.customcrops.api.core;
import net.momirealms.customcrops.common.item.Item;
import net.momirealms.customcrops.common.plugin.feature.Reloadable;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
@@ -26,7 +27,7 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface ItemManager {
public interface ItemManager extends Reloadable {
void place(@NotNull Location location, @NotNull ExistenceForm form, @NotNull String id, FurnitureRotation rotation);

View File

@@ -56,4 +56,5 @@ public class Registries {
public static final ClearableRegistry<String, FertilizerConfig> ITEM_TO_FERTILIZER = new ClearableMappedRegistry<>(Key.key("fast_lookup", "item_to_fertilizer"));
public static final ClearableRegistry<String, PotConfig> ITEM_TO_POT = new ClearableMappedRegistry<>(Key.key("fast_lookup", "item_to_pot"));
public static final ClearableRegistry<String, SprinklerConfig> ITEM_TO_SPRINKLER = new ClearableMappedRegistry<>(Key.key("fast_lookup", "item_to_sprinkler"));
public static final ClearableRegistry<String, WateringCanConfig> ITEM_TO_WATERING_CAN = new ClearableMappedRegistry<>(Key.key("fast_lookup", "item_to_wateringcan"));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -21,6 +21,7 @@ import com.flowpowered.nbt.IntTag;
import net.momirealms.customcrops.api.BukkitCustomCropsPlugin;
import net.momirealms.customcrops.api.action.ActionManager;
import net.momirealms.customcrops.api.context.Context;
import net.momirealms.customcrops.api.context.ContextKeys;
import net.momirealms.customcrops.api.core.*;
import net.momirealms.customcrops.api.core.item.Fertilizer;
import net.momirealms.customcrops.api.core.item.FertilizerConfig;
@@ -35,6 +36,7 @@ import net.momirealms.customcrops.api.event.CropBreakEvent;
import net.momirealms.customcrops.api.event.CropInteractEvent;
import net.momirealms.customcrops.api.requirement.RequirementManager;
import net.momirealms.customcrops.api.util.EventUtils;
import net.momirealms.customcrops.api.util.LocationUtils;
import net.momirealms.customcrops.api.util.PlayerUtils;
import org.bukkit.GameMode;
import org.bukkit.Location;
@@ -185,6 +187,7 @@ public class CropBlock extends AbstractCustomCropsBlock {
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
@@ -193,6 +196,7 @@ public class CropBlock extends AbstractCustomCropsBlock {
return;
}
context.arg(ContextKeys.LOCATION, LocationUtils.toBlockLocation(location));
if (point < cropConfig.maxPoints()) {
for (BoneMeal boneMeal : cropConfig.boneMeals()) {
if (boneMeal.requiredItem().equals(event.itemID()) && boneMeal.amountOfRequiredItem() <= itemInHand.getAmount()) {
@@ -231,6 +235,7 @@ public class CropBlock extends AbstractCustomCropsBlock {
Objects.requireNonNull(afterStage);
Context<CustomCropsBlockState> blockContext = Context.block(state);
blockContext.arg(ContextKeys.LOCATION, LocationUtils.toBlockLocation(location));
for (int i = point + 1; i <= afterPoints; i++) {
CropStageConfig stage = cropConfig.stageByPoint(i);
if (stage != null) {
@@ -307,9 +312,10 @@ public class CropBlock extends AbstractCustomCropsBlock {
}
Context<CustomCropsBlockState> context = Context.block(state);
Location bukkitLocation = location.toLocation(bukkitWorld);
context.arg(ContextKeys.LOCATION, bukkitLocation);
for (DeathCondition deathCondition : config.deathConditions()) {
if (deathCondition.isMet(context)) {
Location bukkitLocation = location.toLocation(bukkitWorld);
BukkitCustomCropsPlugin.getInstance().getScheduler().sync().runLater(() -> {
FurnitureRotation rotation = BukkitCustomCropsPlugin.getInstance().getItemManager().remove(bukkitLocation, ExistenceForm.ANY);
world.removeBlockState(location);
@@ -375,8 +381,6 @@ public class CropBlock extends AbstractCustomCropsBlock {
tempPoints = after.point() - 1;
}
Location bukkitLocation = location.toLocation(bukkitWorld);
final String finalPreStage = preStage;
final String finalAfterStage = afterStage;
final ExistenceForm finalAfterForm = afterForm;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -21,6 +21,7 @@ import com.flowpowered.nbt.*;
import net.momirealms.customcrops.api.BukkitCustomCropsPlugin;
import net.momirealms.customcrops.api.action.ActionManager;
import net.momirealms.customcrops.api.context.Context;
import net.momirealms.customcrops.api.context.ContextKeys;
import net.momirealms.customcrops.api.core.*;
import net.momirealms.customcrops.api.core.item.Fertilizer;
import net.momirealms.customcrops.api.core.item.FertilizerConfig;
@@ -34,6 +35,7 @@ import net.momirealms.customcrops.api.core.wrapper.WrappedPlaceEvent;
import net.momirealms.customcrops.api.event.*;
import net.momirealms.customcrops.api.requirement.RequirementManager;
import net.momirealms.customcrops.api.util.EventUtils;
import net.momirealms.customcrops.api.util.LocationUtils;
import net.momirealms.customcrops.api.util.PlayerUtils;
import net.momirealms.customcrops.api.util.StringUtils;
import org.bukkit.GameMode;
@@ -220,6 +222,8 @@ public class PotBlock extends AbstractCustomCropsBlock {
final Player player = event.player();
Context<Player> context = Context.player(player);
context.arg(ContextKeys.LOCATION, LocationUtils.toBlockLocation(location));
// check use requirements
if (!RequirementManager.isSatisfied(context, potConfig.useRequirements())) {
return;
@@ -258,6 +262,9 @@ public class PotBlock extends AbstractCustomCropsBlock {
}
}
}
if (addWater(state, method.amountOfWater())) {
updateBlockAppearance(potLocation, potConfig, true, fertilizers(state));
}
method.triggerActions(context);
ActionManager.trigger(context, potConfig.addWaterActions());
}
@@ -361,7 +368,11 @@ public class PotBlock extends AbstractCustomCropsBlock {
boolean fertilizerChanged = tickFertilizer(state);
if (fertilizerChanged || waterChanged) {
updateBlockAppearance(location.toLocation(bukkitWorld), config, hasNaturalWater, fertilizers(state));
boolean finalHasNaturalWater = hasNaturalWater;
Location bukkitLocation = location.toLocation(bukkitWorld);
BukkitCustomCropsPlugin.getInstance().getScheduler().sync().run(() -> {
updateBlockAppearance(bukkitLocation, config, finalHasNaturalWater, fertilizers(state));
}, bukkitLocation);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -53,7 +53,7 @@ public class FertilizerItem extends AbstractCustomCropsItem {
public InteractionResult interactAt(WrappedInteractEvent event) {
FertilizerConfig fertilizerConfig = Registries.FERTILIZER.get(event.itemID());
if (fertilizerConfig == null) {
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
final Player player = event.player();
@@ -77,14 +77,14 @@ public class FertilizerItem extends AbstractCustomCropsItem {
// check pot whitelist
if (!fertilizerConfig.whitelistPots().contains(potConfig.id())) {
ActionManager.trigger(context, fertilizerConfig.wrongPotActions());
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
// check requirements
if (!RequirementManager.isSatisfied(context, fertilizerConfig.requirements())) {
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
if (!RequirementManager.isSatisfied(context, potConfig.useRequirements())) {
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
// check "before-plant"
if (fertilizerConfig.beforePlant()) {
@@ -94,7 +94,7 @@ public class FertilizerItem extends AbstractCustomCropsItem {
CustomCropsBlockState blockState = state.get();
if (blockState.type() instanceof CropBlock) {
ActionManager.trigger(context, fertilizerConfig.beforePlantActions());
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
}
}
@@ -108,12 +108,12 @@ public class FertilizerItem extends AbstractCustomCropsItem {
.build();
CustomCropsBlockState potState = potBlock.fixOrGetState(world, Pos3.from(targetLocation), potConfig, event.relatedID());
if (!potBlock.canApplyFertilizer(potState,fertilizer)) {
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
// trigger event
FertilizerUseEvent useEvent = new FertilizerUseEvent(player, itemInHand, fertilizer, targetLocation, potState, event.hand(), potConfig);
if (EventUtils.fireAndCheckCancel(useEvent))
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
// add the fertilizer
if (potBlock.addFertilizer(potState, fertilizer)) {
potBlock.updateBlockAppearance(targetLocation, potState, potBlock.fertilizers(potState));
@@ -122,7 +122,7 @@ public class FertilizerItem extends AbstractCustomCropsItem {
itemInHand.setAmount(itemInHand.getAmount() - 1);
}
ActionManager.trigger(context, fertilizerConfig.useActions());
return InteractionResult.SUCCESS;
return InteractionResult.COMPLETE;
}
return InteractionResult.PASS;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -45,12 +45,11 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Collection;
import java.util.Map;
public class SeedItem extends AbstractCustomCropsItem {
public SeedItem() {
super(BuiltInBlockMechanics.CROP.key());
super(BuiltInItemMechanics.SEED.key());
}
@Override
@@ -60,11 +59,10 @@ public class SeedItem extends AbstractCustomCropsItem {
if (potConfig == null) return InteractionResult.PASS;
// check if the crop exists
CropConfig cropConfig = Registries.SEED_TO_CROP.get(event.itemID());
if (cropConfig == null) return InteractionResult.FAIL;
if (cropConfig == null) return InteractionResult.COMPLETE;
// check the block face
if (event.clickedBlockFace() != BlockFace.UP)
return InteractionResult.PASS;
final Player player = event.player();
Context<Player> context = Context.player(player);
// check pot whitelist
@@ -73,20 +71,21 @@ public class SeedItem extends AbstractCustomCropsItem {
}
// check plant requirements
if (!RequirementManager.isSatisfied(context, cropConfig.plantRequirements())) {
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
// check if the block is empty
if (!suitableForSeed(event.location())) {
return InteractionResult.FAIL;
Location seedLocation = event.location().add(0, 1, 0);
if (!suitableForSeed(seedLocation)) {
return InteractionResult.COMPLETE;
}
CustomCropsWorld<?> world = event.world();
Location seedLocation = event.location().add(0, 1, 0);
Pos3 pos3 = Pos3.from(seedLocation);
// check limitation
if (world.setting().cropPerChunk() >= 0) {
if (world.testChunkLimitation(pos3, CropBlock.class, world.setting().cropPerChunk())) {
ActionManager.trigger(context, cropConfig.reachLimitActions());
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
}
final ItemStack itemInHand = event.itemInHand();
@@ -97,24 +96,17 @@ public class SeedItem extends AbstractCustomCropsItem {
// trigger event
CropPlantEvent plantEvent = new CropPlantEvent(player, itemInHand, event.hand(), seedLocation, cropConfig, state, 0);
if (EventUtils.fireAndCheckCancel(plantEvent)) {
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
int point = plantEvent.getPoint();
int temp = point;
ExistenceForm form = null;
String stageID = null;
while (temp >= 0) {
Map.Entry<Integer, CropStageConfig> entry = cropConfig.getFloorStageEntry(temp);
CropStageConfig stageConfig = entry.getValue();
if (stageConfig.stageID() != null) {
form = stageConfig.existenceForm();
stageID = stageConfig.stageID();
break;
}
temp = stageConfig.point() - 1;
CropStageConfig stageConfig = cropConfig.stageWithModelByPoint(point);
if (stageConfig == null) {
return InteractionResult.COMPLETE;
}
String stageID = stageConfig.stageID();
ExistenceForm form = stageConfig.existenceForm();
if (stageID == null || form == null) {
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
// reduce item
if (player.getGameMode() != GameMode.CREATIVE)
@@ -133,7 +125,7 @@ public class SeedItem extends AbstractCustomCropsItem {
context.arg(ContextKeys.SLOT, event.hand());
// trigger plant actions
ActionManager.trigger(context, cropConfig.plantActions());
return InteractionResult.SUCCESS;
return InteractionResult.COMPLETE;
}
private boolean suitableForSeed(Location location) {

View File

@@ -56,7 +56,7 @@ public class SprinklerItem extends AbstractCustomCropsItem {
return InteractionResult.PASS;
SprinklerConfig config = Registries.SPRINKLER.get(event.itemID());
if (config == null) {
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
Block clicked = event.location().getBlock();
@@ -79,7 +79,7 @@ public class SprinklerItem extends AbstractCustomCropsItem {
Context<Player> context = Context.player(player);
// check requirements
if (!RequirementManager.isSatisfied(context, config.placeRequirements())) {
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
final CustomCropsWorld<?> world = event.world();
@@ -88,7 +88,7 @@ public class SprinklerItem extends AbstractCustomCropsItem {
if (world.setting().sprinklerPerChunk() >= 0) {
if (world.testChunkLimitation(pos3, SprinklerBlock.class, world.setting().sprinklerPerChunk())) {
ActionManager.trigger(context, config.reachLimitActions());
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
}
// generate state
@@ -99,7 +99,7 @@ public class SprinklerItem extends AbstractCustomCropsItem {
// trigger event
SprinklerPlaceEvent placeEvent = new SprinklerPlaceEvent(player, itemInHand, event.hand(), targetLocation.clone(), config, state);
if (EventUtils.fireAndCheckCancel(placeEvent))
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
// clear replaceable block
targetLocation.getBlock().setType(Material.AIR, false);
if (player.getGameMode() != GameMode.CREATIVE)
@@ -114,7 +114,7 @@ public class SprinklerItem extends AbstractCustomCropsItem {
);
});
ActionManager.trigger(context, config.placeActions());
return InteractionResult.SUCCESS;
return InteractionResult.COMPLETE;
}
private boolean suitableForSprinkler(Location location) {

View File

@@ -49,6 +49,8 @@ import org.bukkit.block.BlockFace;
import org.bukkit.block.data.Waterlogged;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.RayTraceResult;
import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.List;
@@ -71,7 +73,7 @@ public class WateringCanItem extends AbstractCustomCropsItem {
Item<ItemStack> wrapped = BukkitCustomCropsPlugin.getInstance().getItemManager().wrap(itemStack);
int realWater = Math.min(config.storage(), water);
if (!config.infinite()) {
wrapped.setTag("CustomCrops", "water", realWater);
wrapped.setTag(realWater, "CustomCrops", "water");
wrapped.maxDamage().ifPresent(max -> {
if (max <= 0) return;
int damage = (int) (max * (((double) config.storage() - realWater) / config.storage()));
@@ -104,23 +106,27 @@ public class WateringCanItem extends AbstractCustomCropsItem {
@Override
public void interactAir(WrappedInteractAirEvent event) {
WateringCanConfig config = Registries.WATERING_CAN.get(event.itemID());
WateringCanConfig config = Registries.ITEM_TO_WATERING_CAN.get(event.itemID());
if (config == null)
return;
final Player player = event.player();;
Context<Player> context = Context.player(player);
// check requirements
if (!RequirementManager.isSatisfied(context, config.requirements())) {
if (!RequirementManager.isSatisfied(context, config.requirements()))
return;
}
// ignore infinite
if (config.infinite())
return;
// get target block
Block targetBlock = player.getTargetBlockExact(5, FluidCollisionMode.ALWAYS);
RayTraceResult result = player.getWorld().rayTraceBlocks(player.getEyeLocation(), player.getLocation().getDirection(), 5, FluidCollisionMode.ALWAYS);
if (result == null)
return;
Block targetBlock = result.getHitBlock();
if (targetBlock == null)
return;
final Vector vector = result.getHitPosition();
// for old config compatibility
context.arg(ContextKeys.LOCATION, new Location(player.getWorld(), vector.getX() - 0.5,vector.getY() - 1, vector.getZ() - 0.5));
final ItemStack itemInHand = event.itemInHand();
int water = getCurrentWater(itemInHand);
@@ -140,6 +146,10 @@ public class WateringCanItem extends AbstractCustomCropsItem {
WateringCanFillEvent fillEvent = new WateringCanFillEvent(player, event.hand(), itemInHand, targetBlock.getLocation(), config, method);
if (EventUtils.fireAndCheckCancel(fillEvent))
return;
int current = Math.min(water + method.amountOfWater(), config.storage());
context.arg(ContextKeys.WATER_BAR, Optional.ofNullable(config.waterBar()).map(bar -> bar.getWaterBar(current, config.storage())).orElse(""));
context.arg(ContextKeys.STORAGE, config.storage());
context.arg(ContextKeys.CURRENT_WATER, current);
setCurrentWater(itemInHand, config, water + method.amountOfWater(), context);
method.triggerActions(context);
ActionManager.trigger(context, config.addWaterActions());
@@ -151,16 +161,16 @@ public class WateringCanItem extends AbstractCustomCropsItem {
@Override
public InteractionResult interactAt(WrappedInteractEvent event) {
WateringCanConfig wateringCanConfig = Registries.WATERING_CAN.get(event.itemID());
WateringCanConfig wateringCanConfig = Registries.ITEM_TO_WATERING_CAN.get(event.itemID());
if (wateringCanConfig == null)
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
final Player player = event.player();
final Context<Player> context = Context.player(player);
// check watering can requirements
if (!RequirementManager.isSatisfied(context, wateringCanConfig.requirements())) {
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
final CustomCropsWorld<?> world = event.world();
@@ -175,21 +185,21 @@ public class WateringCanItem extends AbstractCustomCropsItem {
if (sprinklerConfig != null) {
// ignore infinite sprinkler
if (sprinklerConfig.infinite()) {
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
// check requirements
if (!RequirementManager.isSatisfied(context, sprinklerConfig.useRequirements())) {
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
// check water
if (waterInCan <= 0 && !wateringCanConfig.infinite()) {
ActionManager.trigger(context, wateringCanConfig.runOutOfWaterActions());
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
// check whitelist
if (!wateringCanConfig.whitelistSprinklers().contains(sprinklerConfig.id())) {
ActionManager.trigger(context, wateringCanConfig.wrongSprinklerActions());
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
SprinklerBlock sprinklerBlock = (SprinklerBlock) BuiltInBlockMechanics.SPRINKLER.mechanic();
@@ -198,14 +208,19 @@ public class WateringCanItem extends AbstractCustomCropsItem {
// check full
if (sprinklerBlock.water(sprinklerState) >= sprinklerConfig.storage()) {
ActionManager.trigger(context, sprinklerConfig.fullWaterActions());
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
// trigger event
WateringCanWaterSprinklerEvent waterSprinklerEvent = new WateringCanWaterSprinklerEvent(player, itemInHand, event.hand(), wateringCanConfig, sprinklerConfig, sprinklerState, targetLocation);
if (EventUtils.fireAndCheckCancel(waterSprinklerEvent)) {
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
context.arg(ContextKeys.WATER_BAR, Optional.ofNullable(wateringCanConfig.waterBar()).map(bar -> bar.getWaterBar(waterInCan - 1, wateringCanConfig.storage())).orElse(""));
context.arg(ContextKeys.STORAGE, wateringCanConfig.storage());
context.arg(ContextKeys.CURRENT_WATER, waterInCan - 1);
// add water
if (sprinklerBlock.addWater(sprinklerState, sprinklerConfig, wateringCanConfig.wateringAmount())) {
if (!sprinklerConfig.threeDItem().equals(sprinklerConfig.threeDItemWithWater())) {
@@ -215,26 +230,7 @@ public class WateringCanItem extends AbstractCustomCropsItem {
ActionManager.trigger(context, wateringCanConfig.consumeWaterActions());
setCurrentWater(itemInHand, wateringCanConfig, waterInCan - 1, context);
return InteractionResult.SUCCESS;
}
// try filling the watering can
for (FillMethod method : wateringCanConfig.fillMethods()) {
if (method.getID().equals(event.relatedID())) {
if (method.checkRequirements(context)) {
if (waterInCan >= wateringCanConfig.storage()) {
ActionManager.trigger(context, wateringCanConfig.fullActions());
return InteractionResult.FAIL;
}
WateringCanFillEvent fillEvent = new WateringCanFillEvent(player, event.hand(), itemInHand, targetLocation, wateringCanConfig, method);
if (EventUtils.fireAndCheckCancel(fillEvent))
return InteractionResult.FAIL;
setCurrentWater(itemInHand, wateringCanConfig, waterInCan + method.amountOfWater(), context);
method.triggerActions(context);
ActionManager.trigger(context, wateringCanConfig.addWaterActions());
}
return InteractionResult.SUCCESS;
}
return InteractionResult.COMPLETE;
}
// if the clicked block is a crop, correct the target block
@@ -254,12 +250,12 @@ public class WateringCanItem extends AbstractCustomCropsItem {
// check whitelist
if (!wateringCanConfig.whitelistPots().contains(potConfig.id())) {
ActionManager.trigger(context, wateringCanConfig.wrongPotActions());
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
// check water
if (waterInCan <= 0 && !wateringCanConfig.infinite()) {
ActionManager.trigger(context, wateringCanConfig.runOutOfWaterActions());
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
World bukkitWorld = targetLocation.getWorld();
@@ -267,26 +263,65 @@ public class WateringCanItem extends AbstractCustomCropsItem {
WateringCanWaterPotEvent waterPotEvent = new WateringCanWaterPotEvent(player, itemInHand, event.hand(), wateringCanConfig, potConfig, pots);
if (EventUtils.fireAndCheckCancel(waterPotEvent)) {
return InteractionResult.FAIL;
return InteractionResult.COMPLETE;
}
context.arg(ContextKeys.WATER_BAR, Optional.ofNullable(wateringCanConfig.waterBar()).map(bar -> bar.getWaterBar(waterInCan - 1, wateringCanConfig.storage())).orElse(""));
context.arg(ContextKeys.STORAGE, wateringCanConfig.storage());
context.arg(ContextKeys.CURRENT_WATER, waterInCan - 1);
PotBlock potBlock = (PotBlock) BuiltInBlockMechanics.POT.mechanic();
for (Pair<Pos3, String> pair : waterPotEvent.getPotWithIDs()) {
CustomCropsBlockState potState = potBlock.fixOrGetState(world,pair.left(), potConfig, pair.right());
Location temp = pair.left().toLocation(bukkitWorld);
if (potBlock.addWater(potState, potConfig, wateringCanConfig.wateringAmount())) {
Location temp = pair.left().toLocation(bukkitWorld);
potBlock.updateBlockAppearance(temp, potConfig, true, potBlock.fertilizers(potState));
context.arg(ContextKeys.LOCATION, temp);
ActionManager.trigger(context, potConfig.addWaterActions());
}
context.arg(ContextKeys.LOCATION, temp);
ActionManager.trigger(context, potConfig.addWaterActions());
}
ActionManager.trigger(context, wateringCanConfig.consumeWaterActions());
setCurrentWater(itemInHand, wateringCanConfig, waterInCan - 1, context);
return InteractionResult.SUCCESS;
return InteractionResult.COMPLETE;
}
return InteractionResult.PASS;
RayTraceResult result = player.getWorld().rayTraceBlocks(player.getEyeLocation(), player.getLocation().getDirection(), 5, FluidCollisionMode.ALWAYS);
if (result == null)
return InteractionResult.COMPLETE;
Block targetBlock = result.getHitBlock();
if (targetBlock == null)
return InteractionResult.COMPLETE;
final Vector vector = result.getHitPosition();
// for old config compatibility
context.arg(ContextKeys.LOCATION, new Location(player.getWorld(), vector.getX() - 0.5,vector.getY() - 1, vector.getZ() - 0.5));
String blockID = BukkitCustomCropsPlugin.getInstance().getItemManager().blockID(targetBlock);
if (targetBlock.getBlockData() instanceof Waterlogged waterlogged && waterlogged.isWaterlogged()) {
blockID = "WATER";
}
for (FillMethod method : wateringCanConfig.fillMethods()) {
if (method.getID().equals(blockID)) {
if (method.checkRequirements(context)) {
if (waterInCan >= wateringCanConfig.storage()) {
ActionManager.trigger(context, wateringCanConfig.fullActions());
return InteractionResult.COMPLETE;
}
WateringCanFillEvent fillEvent = new WateringCanFillEvent(player, event.hand(), itemInHand, targetBlock.getLocation(), wateringCanConfig, method);
if (EventUtils.fireAndCheckCancel(fillEvent))
return InteractionResult.COMPLETE;
int current = Math.min(waterInCan + method.amountOfWater(), wateringCanConfig.storage());
context.arg(ContextKeys.WATER_BAR, Optional.ofNullable(wateringCanConfig.waterBar()).map(bar -> bar.getWaterBar(current, wateringCanConfig.storage())).orElse(""));
context.arg(ContextKeys.STORAGE, wateringCanConfig.storage());
context.arg(ContextKeys.CURRENT_WATER, current);
setCurrentWater(itemInHand, wateringCanConfig, waterInCan + method.amountOfWater(), context);
method.triggerActions(context);
ActionManager.trigger(context, wateringCanConfig.addWaterActions());
}
return InteractionResult.COMPLETE;
}
}
return InteractionResult.COMPLETE;
}
public ArrayList<Pair<Pos3, String>> potInRange(World world, Pos3 pos3, int width, int length, float yaw, PotConfig config) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
* 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