9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-28 03:19:15 +00:00
This commit is contained in:
XiaoMoMi
2024-03-15 09:47:51 +08:00
parent f0f69adc2f
commit 6b492aeacb
12 changed files with 548 additions and 46 deletions

View File

@@ -19,29 +19,31 @@ package net.momirealms.customcrops.api.event;
import net.momirealms.customcrops.api.mechanic.world.level.WorldCrop;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* An event that triggered when breaking a crop
*/
public class CropBreakEvent extends PlayerEvent implements Cancellable {
public class CropBreakEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancelled;
private final Location location;
private final WorldCrop worldCrop;
private final Entity entity;
public CropBreakEvent(
@NotNull Player player,
@Nullable Entity entity,
@NotNull Location location,
@Nullable WorldCrop worldCrop
) {
super(player);
this.entity = entity;
this.location = location;
this.worldCrop = worldCrop;
}
@@ -84,4 +86,17 @@ public class CropBreakEvent extends PlayerEvent implements Cancellable {
public Location getLocation() {
return location;
}
@Nullable
public Entity getEntity() {
return entity;
}
@Nullable
public Player getPlayer() {
if (entity instanceof Player player) {
return player;
}
return null;
}
}

View File

@@ -0,0 +1,105 @@
/*
* Copyright (C) <2022> <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.event;
import net.momirealms.customcrops.api.mechanic.item.water.PassiveFillMethod;
import net.momirealms.customcrops.api.mechanic.world.level.WorldPot;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* An event that triggered when a pot is watered by the fill-methods set in each pot's config
*/
public class PotFillEvent extends PlayerEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancelled;
private final Location location;
private final WorldPot pot;
private final ItemStack itemInHand;
private final PassiveFillMethod fillMethod;
public PotFillEvent(
@NotNull Player player,
@NotNull ItemStack itemInHand,
@NotNull Location location,
@NotNull PassiveFillMethod fillMethod,
@NotNull WorldPot pot
) {
super(player);
this.location = location;
this.itemInHand = itemInHand;
this.pot = pot;
this.fillMethod = fillMethod;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
@NotNull
@Override
public HandlerList getHandlers() {
return getHandlerList();
}
/**
* Get the pot location
* @return location
*/
@NotNull
public Location getLocation() {
return location;
}
/**
* Get the pot's data
* @return pot
*/
@NotNull
public WorldPot getPot() {
return pot;
}
@NotNull
public ItemStack getItemInHand() {
return itemInHand;
}
@NotNull
public PassiveFillMethod getFillMethod() {
return fillMethod;
}
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) <2022> <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.event;
import net.momirealms.customcrops.api.mechanic.item.water.PassiveFillMethod;
import net.momirealms.customcrops.api.mechanic.world.level.WorldSprinkler;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* An event that triggered when a sprinkler is watered by the fill-methods set in each sprinkler's config
*/
public class SprinklerFillEvent extends PlayerEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancelled;
private final ItemStack itemInHand;
private final Location location;
private final PassiveFillMethod fillMethod;
private final WorldSprinkler sprinkler;
public SprinklerFillEvent(
@NotNull Player player,
@NotNull ItemStack itemInHand,
@NotNull Location location,
@NotNull PassiveFillMethod fillMethod,
@NotNull WorldSprinkler sprinkler
) {
super(player);
this.itemInHand = itemInHand;
this.location = location;
this.fillMethod = fillMethod;
this.sprinkler = sprinkler;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
@NotNull
@Override
public HandlerList getHandlers() {
return getHandlerList();
}
/**
* Get the item in player's hand
* @return item in hand
*/
@NotNull
public ItemStack getItemInHand() {
return itemInHand;
}
/**
* Get the sprinkler location
* @return location
*/
@NotNull
public Location getLocation() {
return location;
}
@NotNull
public PassiveFillMethod getFillMethod() {
return fillMethod;
}
@NotNull
public WorldSprinkler getSprinkler() {
return sprinkler;
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) <2022> <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.event;
import net.momirealms.customcrops.api.mechanic.item.WateringCan;
import net.momirealms.customcrops.api.mechanic.item.water.PositiveFillMethod;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* An event that triggered when player tries to add water to the watering-can
*/
public class WateringCanFillEvent extends PlayerEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancelled;
private final ItemStack itemInHand;
private final WateringCan wateringCan;
private final PositiveFillMethod fillMethod;
private final Location location;
public WateringCanFillEvent(
@NotNull Player player,
@NotNull ItemStack itemInHand,
@NotNull WateringCan wateringCan,
@NotNull Location location,
@NotNull PositiveFillMethod fillMethod
) {
super(player);
this.cancelled = false;
this.itemInHand = itemInHand;
this.wateringCan = wateringCan;
this.location = location;
this.fillMethod = fillMethod;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
@Override
public @NotNull HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
@NotNull
public ItemStack getItemInHand() {
return itemInHand;
}
@NotNull
public WateringCan getWateringCan() {
return wateringCan;
}
@NotNull
public PositiveFillMethod getFillMethod() {
return fillMethod;
}
@NotNull
public Location getLocation() {
return location;
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) <2022> <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.event;
import net.momirealms.customcrops.api.common.item.KeyItem;
import net.momirealms.customcrops.api.mechanic.item.WateringCan;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* An event that triggered when player tries to use watering-can to add water to pots/sprinklers
*/
public class WateringCanWaterEvent extends PlayerEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancelled;
private final ItemStack itemInHand;
private final WateringCan wateringCan;
private final KeyItem potOrSprinkler;
private final Location location;
public WateringCanWaterEvent(
@NotNull Player player,
@NotNull ItemStack itemInHand,
@NotNull WateringCan wateringCan,
@NotNull Location location,
@NotNull KeyItem potOrSprinkler
) {
super(player);
this.cancelled = false;
this.itemInHand = itemInHand;
this.wateringCan = wateringCan;
this.location = location;
this.potOrSprinkler = potOrSprinkler;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
@Override
public @NotNull HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
@NotNull
public ItemStack getItemInHand() {
return itemInHand;
}
@NotNull
public WateringCan getWateringCan() {
return wateringCan;
}
@NotNull
public Location getLocation() {
return location;
}
@NotNull
public KeyItem getPotOrSprinkler() {
return potOrSprinkler;
}
}

View File

@@ -35,14 +35,30 @@ public abstract class AbstractFillMethod {
this.requirements = requirements;
}
/**
* Get the amount of water to add
*
* @return amount
*/
public int getAmount() {
return amount;
}
/**
* Trigger actions related to this fill methods
*
* @param state state
*/
public void trigger(State state) {
ActionManager.triggerActions(state, actions);
}
/**
* If player meet the requirements for this fill method
*
* @param state state
* @return meet or not
*/
public boolean canFill(State state) {
return RequirementManager.isRequirementMet(state, requirements);
}

View File

@@ -8,7 +8,7 @@ plugins {
allprojects {
project.group = "net.momirealms"
project.version = "3.4.0.8"
project.version = "3.4.1.0"
apply<JavaPlugin>()
apply(plugin = "java")

View File

@@ -64,7 +64,6 @@ import org.bukkit.block.BlockFace;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;

View File

@@ -35,7 +35,6 @@ import net.momirealms.customcrops.compatibility.papi.ParseUtils;
import net.momirealms.customcrops.mechanic.misc.CrowAttackAnimation;
import net.momirealms.customcrops.utils.ClassUtils;
import net.momirealms.customcrops.utils.ConfigUtils;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.data.type.Farmland;

View File

@@ -718,13 +718,14 @@ public class ItemManagerImpl implements ItemManager {
return FunctionResult.PASS;
}
// is a pot
Pot pot = getPotByBlock(blockWrapper.getClickedBlock());
Block block = blockWrapper.getClickedBlock();
Pot pot = getPotByBlock(block);
if (pot == null) {
return FunctionResult.PASS;
}
final Player player = blockWrapper.getPlayer();
final ItemStack itemStack = blockWrapper.getItemInHand();
final Location clicked = blockWrapper.getClickedBlock().getLocation();
final Location clicked = block.getLocation();
State state = new State(player, itemStack, clicked);
// check watering-can requirements
if (!RequirementManager.isRequirementMet(state, wateringCan.getRequirements())) {
@@ -737,8 +738,14 @@ public class ItemManagerImpl implements ItemManager {
}
// check amount of water
int waterInCan = wateringCan.getCurrentWater(itemStack);
state.setArg("{storage}", String.valueOf(wateringCan.getStorage()));
if (waterInCan > 0 || wateringCan.isInfinite()) {
// fire the event
WateringCanWaterEvent waterEvent = new WateringCanWaterEvent(player, itemStack, wateringCan, clicked, pot);
if (EventUtils.fireAndCheckCancel(waterEvent))
return FunctionResult.CANCEL_EVENT_AND_RETURN;
state.setArg("{storage}", String.valueOf(wateringCan.getStorage()));
state.setArg("{current}", String.valueOf(waterInCan - 1));
state.setArg("{water_bar}", wateringCan.getWaterBar() == null ? "" : wateringCan.getWaterBar().getWaterBar(waterInCan - 1, wateringCan.getStorage()));
wateringCan.updateItem(player, itemStack, waterInCan - 1, state.getArgs());
@@ -749,6 +756,7 @@ public class ItemManagerImpl implements ItemManager {
pot.trigger(ActionTrigger.ADD_WATER, new State(player, itemStack, location));
}
} else {
state.setArg("{storage}", String.valueOf(wateringCan.getStorage()));
state.setArg("{current}", "0");
state.setArg("{water_bar}", wateringCan.getWaterBar() == null ? "" : wateringCan.getWaterBar().getWaterBar(0, wateringCan.getStorage()));
wateringCan.trigger(ActionTrigger.NO_WATER, state);
@@ -772,7 +780,7 @@ public class ItemManagerImpl implements ItemManager {
Block potBlock = blockWrapper.getClickedBlock().getRelative(BlockFace.DOWN);
Pot pot = getPotByBlock(potBlock);
if (pot == null) {
LogUtils.warn("Unexpected issue: Detetced that crops are not planted on a pot: " + blockWrapper.getClickedBlock().getLocation());
plugin.debug("Unexpected issue: Detetced that crops are not planted on a pot: " + blockWrapper.getClickedBlock().getLocation());
return FunctionResult.RETURN;
}
@@ -799,8 +807,14 @@ public class ItemManagerImpl implements ItemManager {
}
// check amount of water
int waterInCan = wateringCan.getCurrentWater(itemStack);
state.setArg("{storage}", String.valueOf(wateringCan.getStorage()));
if (waterInCan > 0 || wateringCan.isInfinite()) {
// fire the event
WateringCanWaterEvent waterEvent = new WateringCanWaterEvent(player, itemStack, wateringCan, potBlock.getLocation(), pot);
if (EventUtils.fireAndCheckCancel(waterEvent))
return FunctionResult.CANCEL_EVENT_AND_RETURN;
state.setArg("{storage}", String.valueOf(wateringCan.getStorage()));
state.setArg("{current}", String.valueOf(waterInCan - 1));
state.setArg("{water_bar}", wateringCan.getWaterBar() == null ? "" : wateringCan.getWaterBar().getWaterBar(waterInCan - 1, wateringCan.getStorage()));
wateringCan.updateItem(player, itemStack, waterInCan - 1, state.getArgs());
@@ -811,6 +825,7 @@ public class ItemManagerImpl implements ItemManager {
pot.trigger(ActionTrigger.ADD_WATER, new State(player, itemStack, location));
}
} else {
state.setArg("{storage}", String.valueOf(wateringCan.getStorage()));
state.setArg("{current}", "0");
state.setArg("{water_bar}", wateringCan.getWaterBar() == null ? "" : wateringCan.getWaterBar().getWaterBar(0, wateringCan.getStorage()));
wateringCan.trigger(ActionTrigger.NO_WATER, state);
@@ -858,8 +873,14 @@ public class ItemManagerImpl implements ItemManager {
}
// check amount of water
int waterInCan = wateringCan.getCurrentWater(itemStack);
state.setArg("{storage}", String.valueOf(wateringCan.getStorage()));
if (waterInCan > 0 || wateringCan.isInfinite()) {
// fire the event
WateringCanWaterEvent waterEvent = new WateringCanWaterEvent(player, itemStack, wateringCan, clicked, pot);
if (EventUtils.fireAndCheckCancel(waterEvent))
return FunctionResult.CANCEL_EVENT_AND_RETURN;
state.setArg("{storage}", String.valueOf(wateringCan.getStorage()));
state.setArg("{current}", String.valueOf(waterInCan - 1));
state.setArg("{water_bar}", wateringCan.getWaterBar() == null ? "" : wateringCan.getWaterBar().getWaterBar(waterInCan - 1, wateringCan.getStorage()));
wateringCan.updateItem(player, itemStack, waterInCan - 1, state.getArgs());
@@ -870,6 +891,7 @@ public class ItemManagerImpl implements ItemManager {
pot.trigger(ActionTrigger.ADD_WATER, new State(player, itemStack, location));
}
} else {
state.setArg("{storage}", String.valueOf(wateringCan.getStorage()));
state.setArg("{current}", "0");
state.setArg("{water_bar}", wateringCan.getWaterBar() == null ? "" : wateringCan.getWaterBar().getWaterBar(0, wateringCan.getStorage()));
wateringCan.trigger(ActionTrigger.NO_WATER, state);
@@ -885,12 +907,15 @@ public class ItemManagerImpl implements ItemManager {
return FunctionResult.PASS;
}
// check watering-can requirements
State state = new State(furnitureWrapper.getPlayer(), furnitureWrapper.getItemInHand(), furnitureWrapper.getLocation());
Player player = furnitureWrapper.getPlayer();
ItemStack itemInHand = furnitureWrapper.getItemInHand();
Location location = furnitureWrapper.getLocation();
State state = new State(player, itemInHand, location);
if (!RequirementManager.isRequirementMet(state, wateringCan.getRequirements())) {
return FunctionResult.RETURN;
}
// get water in can
int waterInCan = wateringCan.getCurrentWater(furnitureWrapper.getItemInHand());
int waterInCan = wateringCan.getCurrentWater(itemInHand);
String clickedFurnitureID = furnitureWrapper.getID();
Sprinkler sprinkler = getSprinklerBy3DItemID(clickedFurnitureID);
// is a sprinkler
@@ -907,21 +932,27 @@ public class ItemManagerImpl implements ItemManager {
// check amount of water
if (waterInCan > 0 || wateringCan.isInfinite()) {
// get sprinkler data
SimpleLocation location = SimpleLocation.of(furnitureWrapper.getLocation());
Optional<WorldSprinkler> worldSprinkler = plugin.getWorldManager().getSprinklerAt(location);
SimpleLocation simpleLocation = SimpleLocation.of(location);
Optional<WorldSprinkler> worldSprinkler = plugin.getWorldManager().getSprinklerAt(simpleLocation);
if (worldSprinkler.isEmpty()) {
plugin.debug("Player " + furnitureWrapper.getPlayer().getName() + " tried to interact a sprinkler which not exists in memory. Fixing the data...");
plugin.debug("Player " + player.getName() + " tried to interact a sprinkler which not exists in memory. Fixing the data...");
} else {
if (sprinkler.getStorage() <= worldSprinkler.get().getWater()) {
return FunctionResult.RETURN;
}
}
// fire the event
WateringCanWaterEvent waterEvent = new WateringCanWaterEvent(player, itemInHand, wateringCan, location, sprinkler);
if (EventUtils.fireAndCheckCancel(waterEvent))
return FunctionResult.CANCEL_EVENT_AND_RETURN;
state.setArg("{storage}", String.valueOf(wateringCan.getStorage()));
state.setArg("{current}", String.valueOf(waterInCan - 1));
state.setArg("{water_bar}", wateringCan.getWaterBar() == null ? "" : wateringCan.getWaterBar().getWaterBar(waterInCan - 1, wateringCan.getStorage()));
wateringCan.updateItem(furnitureWrapper.getPlayer(), furnitureWrapper.getItemInHand(), waterInCan - 1, state.getArgs());
wateringCan.updateItem(player, furnitureWrapper.getItemInHand(), waterInCan - 1, state.getArgs());
wateringCan.trigger(ActionTrigger.CONSUME_WATER, state);
plugin.getWorldManager().addWaterToSprinkler(sprinkler, location, 1);
plugin.getWorldManager().addWaterToSprinkler(sprinkler, simpleLocation, 1);
} else {
state.setArg("{storage}", String.valueOf(wateringCan.getStorage()));
state.setArg("{current}", "0");
@@ -937,13 +968,18 @@ public class ItemManagerImpl implements ItemManager {
for (PositiveFillMethod method : methods) {
if (method.getId().equals(clickedFurnitureID)) {
if (method.canFill(state)) {
// fire the event
WateringCanFillEvent fillEvent = new WateringCanFillEvent(player, itemInHand, wateringCan, location, method);
if (EventUtils.fireAndCheckCancel(fillEvent))
return FunctionResult.CANCEL_EVENT_AND_RETURN;
if (waterInCan < wateringCan.getStorage()) {
waterInCan += method.getAmount();
waterInCan = Math.min(waterInCan, wateringCan.getStorage());
state.setArg("{storage}", String.valueOf(wateringCan.getStorage()));
state.setArg("{current}", String.valueOf(waterInCan));
state.setArg("{water_bar}", wateringCan.getWaterBar() == null ? "" : wateringCan.getWaterBar().getWaterBar(waterInCan, wateringCan.getStorage()));
wateringCan.updateItem(furnitureWrapper.getPlayer(), furnitureWrapper.getItemInHand(), waterInCan, state.getArgs());
wateringCan.updateItem(player, furnitureWrapper.getItemInHand(), waterInCan, state.getArgs());
wateringCan.trigger(ActionTrigger.ADD_WATER, state);
method.trigger(state);
} else {
@@ -970,12 +1006,14 @@ public class ItemManagerImpl implements ItemManager {
if (wateringCan.isInfinite()) {
return FunctionResult.PASS;
}
Player player = interactWrapper.getPlayer();
ItemStack itemInHand = interactWrapper.getItemInHand();
// get the clicked block
Block targetBlock = interactWrapper.getPlayer().getTargetBlockExact(5, FluidCollisionMode.ALWAYS);
Block targetBlock = player.getTargetBlockExact(5, FluidCollisionMode.ALWAYS);
if (targetBlock == null)
return FunctionResult.PASS;
// check watering-can requirements
State state = new State(interactWrapper.getPlayer(), interactWrapper.getItemInHand(), targetBlock.getLocation());
State state = new State(player, itemInHand, targetBlock.getLocation());
if (!RequirementManager.isRequirementMet(state, wateringCan.getRequirements())) {
return FunctionResult.RETURN;
}
@@ -984,18 +1022,23 @@ public class ItemManagerImpl implements ItemManager {
if (targetBlock.getBlockData() instanceof Waterlogged waterlogged && waterlogged.isWaterlogged()) {
blockID = "WATER";
}
int water = wateringCan.getCurrentWater(interactWrapper.getItemInHand());
int water = wateringCan.getCurrentWater(itemInHand);
PositiveFillMethod[] methods = wateringCan.getPositiveFillMethods();
for (PositiveFillMethod method : methods) {
if (method.getId().equals(blockID)) {
if (method.canFill(state)) {
if (water < wateringCan.getStorage()) {
// fire the event
WateringCanFillEvent fillEvent = new WateringCanFillEvent(player, itemInHand, wateringCan, state.getLocation(), method);
if (EventUtils.fireAndCheckCancel(fillEvent))
return FunctionResult.CANCEL_EVENT_AND_RETURN;
water += method.getAmount();
water = Math.min(water, wateringCan.getStorage());
state.setArg("{storage}", String.valueOf(wateringCan.getStorage()));
state.setArg("{current}", String.valueOf(water));
state.setArg("{water_bar}", wateringCan.getWaterBar() == null ? "" : wateringCan.getWaterBar().getWaterBar(water, wateringCan.getStorage()));
wateringCan.updateItem(interactWrapper.getPlayer(), interactWrapper.getItemInHand(), water, state.getArgs());
wateringCan.updateItem(player, itemInHand, water, state.getArgs());
wateringCan.trigger(ActionTrigger.ADD_WATER, state);
method.trigger(state);
} else {
@@ -1017,12 +1060,14 @@ public class ItemManagerImpl implements ItemManager {
if (wateringCan.isInfinite()) {
return FunctionResult.PASS;
}
Player player = interactWrapper.getPlayer();
// get the clicked block
Block targetBlock = interactWrapper.getPlayer().getTargetBlockExact(5, FluidCollisionMode.ALWAYS);
Block targetBlock = player.getTargetBlockExact(5, FluidCollisionMode.ALWAYS);
if (targetBlock == null)
return FunctionResult.PASS;
// check watering-can requirements
State state = new State(interactWrapper.getPlayer(), interactWrapper.getItemInHand(), targetBlock.getLocation());
ItemStack itemInHand = interactWrapper.getItemInHand();
State state = new State(player, itemInHand, targetBlock.getLocation());
if (!RequirementManager.isRequirementMet(state, wateringCan.getRequirements())) {
return FunctionResult.RETURN;
}
@@ -1031,18 +1076,23 @@ public class ItemManagerImpl implements ItemManager {
if (targetBlock.getBlockData() instanceof Waterlogged waterlogged && waterlogged.isWaterlogged()) {
blockID = "WATER";
}
int water = wateringCan.getCurrentWater(interactWrapper.getItemInHand());
int water = wateringCan.getCurrentWater(itemInHand);
PositiveFillMethod[] methods = wateringCan.getPositiveFillMethods();
for (PositiveFillMethod method : methods) {
if (method.getId().equals(blockID)) {
if (method.canFill(state)) {
if (water < wateringCan.getStorage()) {
// fire the event
WateringCanFillEvent fillEvent = new WateringCanFillEvent(player, itemInHand, wateringCan, state.getLocation(), method);
if (EventUtils.fireAndCheckCancel(fillEvent))
return FunctionResult.CANCEL_EVENT_AND_RETURN;
water += method.getAmount();
water = Math.min(water, wateringCan.getStorage());
state.setArg("{storage}", String.valueOf(wateringCan.getStorage()));
state.setArg("{current}", String.valueOf(water));
state.setArg("{water_bar}", wateringCan.getWaterBar() == null ? "" : wateringCan.getWaterBar().getWaterBar(water, wateringCan.getStorage()));
wateringCan.updateItem(interactWrapper.getPlayer(), interactWrapper.getItemInHand(), water, state.getArgs());
wateringCan.updateItem(player, itemInHand, water, state.getArgs());
wateringCan.trigger(ActionTrigger.ADD_WATER, state);
method.trigger(state);
} else {
@@ -1223,14 +1273,18 @@ public class ItemManagerImpl implements ItemManager {
// add water to sprinkler
String itemID = getItemID(itemInHand);
int itemAmount = itemInHand.getAmount();
Optional<WorldSprinkler> worldSprinkler = plugin.getWorldManager().getSprinklerAt(simpleLocation);
int waterInSprinkler = worldSprinkler.map(WorldSprinkler::getWater).orElse(0);
int waterInSprinkler = optionalSprinkler.get().getWater();
// if it's not infinite
if (!sprinkler.isInfinite()) {
for (PassiveFillMethod method : sprinkler.getPassiveFillMethods()) {
if (method.getUsed().equals(itemID) && itemAmount >= method.getUsedAmount()) {
if (method.canFill(state)) {
if (waterInSprinkler < sprinkler.getStorage()) {
// fire the event
SprinklerFillEvent fillEvent = new SprinklerFillEvent(player, itemInHand, location, method, optionalSprinkler.get());
if (EventUtils.fireAndCheckCancel(fillEvent))
return FunctionResult.CANCEL_EVENT_AND_RETURN;
if (player.getGameMode() != GameMode.CREATIVE) {
itemInHand.setAmount(itemAmount - method.getUsedAmount());
if (method.getReturned() != null) {
@@ -1751,25 +1805,23 @@ public class ItemManagerImpl implements ItemManager {
}
// if not reached the max point, try detecting bone meals
if (optionalCrop.isPresent()) {
if (optionalCrop.get().getPoint() < crop.getMaxPoints()) {
for (BoneMeal boneMeal : crop.getBoneMeals()) {
if (boneMeal.getItem().equals(itemID)) {
if (player.getGameMode() != GameMode.CREATIVE) {
itemInHand.setAmount(itemAmount - boneMeal.getUsedAmount());
if (boneMeal.getReturned() != null) {
ItemStack returned = getItemStack(player, boneMeal.getReturned());
ItemUtils.giveItem(player, returned, boneMeal.getReturnedAmount());
}
if (optionalCrop.get().getPoint() < crop.getMaxPoints()) {
for (BoneMeal boneMeal : crop.getBoneMeals()) {
if (boneMeal.getItem().equals(itemID)) {
if (player.getGameMode() != GameMode.CREATIVE) {
itemInHand.setAmount(itemAmount - boneMeal.getUsedAmount());
if (boneMeal.getReturned() != null) {
ItemStack returned = getItemStack(player, boneMeal.getReturned());
ItemUtils.giveItem(player, returned, boneMeal.getReturnedAmount());
}
boneMeal.trigger(cropState);
plugin.getWorldManager().addPointToCrop(crop, SimpleLocation.of(cropLocation), boneMeal.getPoint());
return FunctionResult.RETURN;
}
boneMeal.trigger(cropState);
plugin.getWorldManager().addPointToCrop(crop, SimpleLocation.of(cropLocation), boneMeal.getPoint());
return FunctionResult.RETURN;
}
} else {
crop.trigger(ActionTrigger.RIPE, cropState);
}
} else {
crop.trigger(ActionTrigger.RIPE, cropState);
}
// trigger interact actions
@@ -1900,6 +1952,11 @@ public class ItemManagerImpl implements ItemManager {
if (method.getUsed().equals(itemID) && itemAmount >= method.getUsedAmount()) {
if (method.canFill(state)) {
if (waterInPot < pot.getStorage()) {
// fire the event
PotFillEvent waterEvent = new PotFillEvent(player, itemInHand, location, method, optionalPot.get());
if (EventUtils.fireAndCheckCancel(waterEvent))
return FunctionResult.CANCEL_EVENT_AND_RETURN;
if (player.getGameMode() != GameMode.CREATIVE) {
itemInHand.setAmount(itemAmount - method.getUsedAmount());
if (method.getReturned() != null) {

View File

@@ -22,6 +22,7 @@ import net.momirealms.customcrops.api.manager.ConfigManager;
import net.momirealms.customcrops.api.manager.WorldManager;
import net.momirealms.customcrops.api.mechanic.item.Pot;
import net.momirealms.customcrops.api.mechanic.item.Sprinkler;
import net.momirealms.customcrops.api.mechanic.item.WateringCan;
import net.momirealms.customcrops.api.mechanic.world.SimpleLocation;
import net.momirealms.customcrops.mechanic.item.ItemManagerImpl;
import org.bukkit.Location;
@@ -38,6 +39,7 @@ import org.bukkit.event.block.*;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemDamageEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
@@ -177,6 +179,15 @@ public abstract class AbstractCustomListener implements Listener {
}
}
@EventHandler (ignoreCancelled = true)
public void onItemDamage(PlayerItemDamageEvent event) {
ItemStack itemStack = event.getItem();
WateringCan wateringCan = this.itemManager.getWateringCanByItemStack(itemStack);
if (wateringCan != null) {
event.setCancelled(true);
}
}
public void onPlaceBlock(Player player, Block block, String blockID, Cancellable event) {
this.itemManager.handlePlayerPlaceBlock(player, block, blockID, event);
}

View File

@@ -134,6 +134,7 @@ public class WateringCanConfig extends AbstractEventItem implements WateringCan
@Override
public void updateItem(Player player, ItemStack itemStack, int water, Map<String, String> args) {
int maxDurability = itemStack.getType().getMaxDurability();
NBTItem nbtItem = new NBTItem(itemStack);
if (isInfinite()) water = storage;
if (hasDynamicLore()) {
@@ -159,6 +160,9 @@ public class WateringCanConfig extends AbstractEventItem implements WateringCan
}
nbtItem.setInteger("WaterAmount", water);
if (maxDurability != 0) {
nbtItem.setInteger("Damage", (int) (maxDurability * (((double) storage - water) / storage)));
}
itemStack.setItemMeta(nbtItem.getItem().getItemMeta());
}