diff --git a/build.gradle.kts b/build.gradle.kts index b72f97c..9ce3093 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,6 +8,7 @@ plugins { repositories { mavenCentral() + maven("https://jitpack.io") maven("https://eldonexus.de/repository/maven-public") maven("https://eldonexus.de/repository/maven-proxies") maven("https://raw.githubusercontent.com/FabioZumbi12/RedProtect/mvn-repo/") @@ -15,13 +16,17 @@ repositories { dependencies { implementation("de.eldoria", "eldo-util", "1.13.9") + compileOnly("org.spigotmc", "spigot-api", "1.16.5-R0.1-SNAPSHOT") compileOnly("com.mojang", "authlib", "1.5.25") compileOnly("org.jetbrains", "annotations", "16.0.2") + compileOnly("com.github.SaberLLC", "Saber-Factions", "2.9.1-RC"){ + exclude("*") + } compileOnly("world.bentobox", "bentobox", "1.16.2-SNAPSHOT") compileOnly("com.github.TechFortress", "GriefPrevention", "16.17.1") compileOnly("com.github.TownyAdvanced", "Towny", "0.97.1.0") - implementation("com.plotsquared", "PlotSquared-Core", "6.9.0") { + compileOnly("com.plotsquared", "PlotSquared-Core", "6.9.0") { exclude("com.intellectualsites.paster") exclude("net.kyori") exclude("org.apache.logging.log4j") @@ -131,7 +136,7 @@ bukkit { main = "de.eldoria.pickmeup.PickMeUp" website = "https://www.spigotmc.org/resources/88151/" apiVersion = "1.13" - softDepend = listOf("BentoBox", "RedProtect", "GriefPrevention", "PlotSquared", "Towny") + softDepend = listOf("BentoBox", "RedProtect", "GriefPrevention", "PlotSquared", "Towny", "Factions") commands { register("pickmeup") { description = "Main command of pick me up" diff --git a/src/main/java/de/eldoria/pickmeup/PickMeUp.java b/src/main/java/de/eldoria/pickmeup/PickMeUp.java index 9199fb8..cf7d42e 100644 --- a/src/main/java/de/eldoria/pickmeup/PickMeUp.java +++ b/src/main/java/de/eldoria/pickmeup/PickMeUp.java @@ -15,6 +15,7 @@ import de.eldoria.pickmeup.listener.CarryListener; import de.eldoria.pickmeup.services.ProtectionService; import de.eldoria.pickmeup.util.Permissions; +import org.bukkit.NamespacedKey; import org.bukkit.configuration.serialization.ConfigurationSerializable; import java.util.Arrays; @@ -57,4 +58,5 @@ public void onReload() { onDisable(); onEnable(); } + } diff --git a/src/main/java/de/eldoria/pickmeup/commands/Reload.java b/src/main/java/de/eldoria/pickmeup/commands/Reload.java index d24d64a..066a459 100644 --- a/src/main/java/de/eldoria/pickmeup/commands/Reload.java +++ b/src/main/java/de/eldoria/pickmeup/commands/Reload.java @@ -16,8 +16,6 @@ import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; -import static com.palmergames.bukkit.towny.Towny.getPlugin; - public class Reload extends AdvancedCommand implements ITabExecutor { public Reload(Plugin plugin) { super(plugin, CommandMeta.builder("reload") @@ -27,7 +25,7 @@ public Reload(Plugin plugin) { @Override public void onCommand(@NotNull CommandSender sender, @NotNull String alias, @NotNull Arguments args) throws CommandException { - getPlugin().onEnable(); + ((PickMeUp) plugin()).onReload(); messageSender().sendLocalizedMessage(sender, "reload.success"); PickMeUp.logger().info("PickMeUp reloaded!"); } diff --git a/src/main/java/de/eldoria/pickmeup/config/CarrySettings.java b/src/main/java/de/eldoria/pickmeup/config/CarrySettings.java index 8abebe7..d084d1c 100644 --- a/src/main/java/de/eldoria/pickmeup/config/CarrySettings.java +++ b/src/main/java/de/eldoria/pickmeup/config/CarrySettings.java @@ -11,17 +11,21 @@ @SerializableAs("pickMeUpCarrySettings") public class CarrySettings implements ConfigurationSerializable { private double throwForce = 2.0; - private boolean allowStacking; + private int throwDelay = 10; + private boolean allowStacking = false; + private int maximumStacking = 0; + //private int maximumSelfCarry = 1; public CarrySettings(Map objectMap) { TypeResolvingMap map = SerializationUtil.mapOf(objectMap); throwForce = map.getValueOrDefault("throwForce", throwForce); + throwDelay = map.getValueOrDefault("throwDelay", throwDelay); allowStacking = map.getValueOrDefault("allowStacking", allowStacking); + maximumStacking = map.getValueOrDefault("maximumStacking", maximumStacking); + //maximumSelfCarry = map.getValueOrDefault("maximumSelfCarry", maximumSelfCarry); } - public CarrySettings() { - - } + public CarrySettings() {} @Override public @NotNull Map serialize() { @@ -32,7 +36,18 @@ public double throwForce() { return throwForce; } + public long throwDelay() { + return throwDelay; + } + public boolean isAllowStacking() { return allowStacking; } + + public int maximumStacking() { + return maximumStacking; + } + /*public int maximumSelfCarry() { + return maximumSelfCarry; + }*/ } diff --git a/src/main/java/de/eldoria/pickmeup/listener/CarryListener.java b/src/main/java/de/eldoria/pickmeup/listener/CarryListener.java index 02b6d21..a950afc 100644 --- a/src/main/java/de/eldoria/pickmeup/listener/CarryListener.java +++ b/src/main/java/de/eldoria/pickmeup/listener/CarryListener.java @@ -1,6 +1,5 @@ package de.eldoria.pickmeup.listener; -import de.eldoria.eldoutilities.core.EldoUtilities; import de.eldoria.eldoutilities.messages.MessageSender; import de.eldoria.eldoutilities.scheduling.DelayedActions; import de.eldoria.pickmeup.PickMeUp; @@ -9,31 +8,43 @@ import de.eldoria.pickmeup.scheduler.TrailHandler; import de.eldoria.pickmeup.services.ProtectionService; import de.eldoria.pickmeup.util.Permissions; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Sound; +import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.world.ChunkLoadEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerToggleSneakEvent; import org.bukkit.plugin.Plugin; import org.bukkit.util.Vector; +import org.spigotmc.event.entity.EntityDismountEvent; -import java.util.HashMap; -import java.util.HashSet; import java.util.Map; +import java.util.HashMap; import java.util.Set; +import java.util.HashSet; import java.util.UUID; +import java.util.Arrays; +import java.util.Optional; +import java.util.Objects; public class CarryListener implements Listener { private final Configuration config; - private ProtectionService protectionService; + private final ProtectionService protectionService; private final Plugin plugin; private final ThrowBarHandler throwBarHandler; - private final Set blocked = new HashSet<>(); - private final Map mountStates = new HashMap<>(); + //private final Set blocked = new HashSet<>(); + + private final Map mountHandlers = new HashMap<>(); + private final TrailHandler trailHandler; private final MessageSender messageSender; private final DelayedActions delayedActions; @@ -50,81 +61,125 @@ public CarryListener(Plugin plugin, Configuration config, ProtectionService prot @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onEntityInteract(PlayerInteractAtEntityEvent event) { - if (!config.worldSettings().allowInWorld(event.getPlayer().getWorld())) return; - - if (!protectionService.canInteract(event.getPlayer(), event.getRightClicked().getLocation())) return; - - if (blocked.contains(event.getRightClicked().getUniqueId())) return; - - MountState mountState = mountStates.get(event.getPlayer().getUniqueId()); - if (mountState == MountState.SNEAK_THROW) { - if (event.getPlayer().getPassengers().contains(event.getRightClicked()) - && event.getPlayer().getEquipment().getItemInMainHand().getType() == Material.AIR) { - unmountAll(event.getPlayer()); - throwBarHandler.getAndRemove(event.getPlayer()); - mountStates.remove(event.getPlayer().getUniqueId()); - blocked.add(event.getRightClicked().getUniqueId()); - delayedActions.schedule(() -> blocked.remove(event.getRightClicked().getUniqueId()), 20); - event.setCancelled(true); + entityCarryInteraction(event.getPlayer(), event.getRightClicked(), event); + } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onEntityInteract(EntityDamageByEntityEvent event) { + if(event.getDamager() instanceof Player player) + entityCarryInteraction(player, event.getEntity(), event); + } + + private void entityCarryInteraction(Player player, Entity entity, Cancellable cancellable){ + if (!config.worldSettings().allowInWorld(player.getWorld())) return; + + if (!protectionService.canInteract(player, entity.getLocation())) return; + + //if (blocked.contains(entity.getUniqueId())) return; + + // If the player doesn't have the hand empty, leave + if (Objects.requireNonNull(player.getEquipment()).getItemInMainHand().getType() != Material.AIR) return; + + //MountHandler mountHandler = mountHandlers.get(player.getUniqueId()); + /*//If the player interacts with the entity that is carrying with an empty hand + if (mountHandler != null + && mountHandler.state == MountState.SNEAK_THROW + && mountHandler.getDirectPassengers().contains(entity)) { + + //Dismount entity + if(!mountHandler.removePassenger(entity)) return; - } - } + //Block the entity from being picked again, to avoid spam picking + blocked.add(entity.getUniqueId()); + delayedActions.schedule(() -> blocked.remove(entity.getUniqueId()), 20); - Player player = event.getPlayer(); - if (player.getEquipment().getItemInMainHand().getType() != Material.AIR) return; - if (!config.mobSettings().canBePickedUp(event.getPlayer(), event.getRightClicked().getType())) return; - if (!player.getPassengers().isEmpty()) return; + cancellable.setCancelled(true); + return; + }*/ + + //If the player is not sneaking leave if (!player.isSneaking()) return; - if (!event.getRightClicked().getPassengers().isEmpty() && !config.carrySettings().isAllowStacking()) { - if (!player.hasPermission(Permissions.BYPASS_NOSTACK)) { - messageSender.sendLocalizedError(player, "nostack"); - return; - } + //Check if the settings/perms allow the player to pick up this entity + if (!config.mobSettings().canBePickedUp(player, entity.getType())) return; + + /*if (!player.hasPermission(Permissions.BYPASS_MAXSELFCARRY) + && (mountHandler != null + ? mountHandler.getDirectPassengers().size() + : MountHandler.getDirectPassengers(player, true).size()) + >= config.carrySettings().maximumSelfCarry()) return;*/ + + + if (!config.carrySettings().isAllowStacking() + &&!player.hasPermission(Permissions.BYPASS_NOSTACK) + && MountHandler.stackCount(entity, true) > 1) { + messageSender.sendLocalizedError(player, "nostack"); + return; + } - mountStates.put(player.getUniqueId(), MountState.SNEAK_MOUNT); - player.addPassenger(event.getRightClicked()); - event.setCancelled(true); + if(config.carrySettings().maximumStacking() != 0 + && !player.hasPermission(Permissions.BYPASS_MAXSTACK) + && MountHandler.stackCount(entity, true) + MountHandler.stackCount(player, true) - 1 > config.carrySettings().maximumStacking()) + return; + + + mountHandlers.putIfAbsent(player.getUniqueId(), new MountHandler(player)); + MountHandler handler = mountHandlers.get(player.getUniqueId()); + // Set the player state as SNEAK_MOUNT since the player just mounted an entity + handler.state = MountHandler.MountState.SNEAK_MOUNT; + // Clear any extra data in case it was leftover + throwBarHandler.getAndRemove(player); + handler.cleanTasks(); + + handler.addPassenger(entity); + + cancellable.setCancelled(true); } @EventHandler public void onSneak(PlayerToggleSneakEvent event) { Player player = event.getPlayer(); - if (!mountStates.containsKey(player.getUniqueId())) { + //If there is no mountState for the player, just dismount everything + if (!mountHandlers.containsKey(player.getUniqueId())) { unmountAll(player); return; } - MountState mountState = mountStates.get(player.getUniqueId()); + MountHandler mountHandler = mountHandlers.get(player.getUniqueId()); - if (!event.isSneaking() && mountState == MountState.SNEAK_MOUNT) { - mountStates.put(player.getUniqueId(), MountState.WALKING); + //If the player stopped sneaking and was SNEAK_MOUNT, change the state to WALKING + if (!event.isSneaking() && mountHandler.state == MountHandler.MountState.SNEAK_MOUNT) { + mountHandler.state = MountHandler.MountState.WALKING; return; } - if (event.isSneaking() && mountState == MountState.WALKING) { - mountStates.put(player.getUniqueId(), MountState.SNEAK_THROW); - delayedActions.schedule(() -> { - if (player.isSneaking()) { - throwBarHandler.register(player); - } - } - , 10); + //If the player is begun sneaking with the WALKING state we start the throw delayedTask and set state to SNEAK_THROW + if (event.isSneaking() && mountHandler.state == MountHandler.MountState.WALKING) { + mountHandler.state = MountHandler.MountState.SNEAK_THROW; + mountHandler.throwTask = + Bukkit.getScheduler().runTaskLater(plugin, + () -> { + //If the player is still sneaking after the delay + if (player.isSneaking()) { + throwBarHandler.register(player); + } + }, config.carrySettings().throwDelay()); return; } - if (!event.isSneaking() && mountState == MountState.SNEAK_THROW) { + //If the player stopped sneaking with the SNEAK_THROW state + if (!event.isSneaking() && mountHandler.state == MountHandler.MountState.SNEAK_THROW) { + //If the player is not registered on the throwBarHandler then we simply dismount the entities if (!throwBarHandler.isRegistered(player)) { unmountAll(player); } else { double force = throwBarHandler.getAndRemove(player); Vector throwVec = player.getEyeLocation().getDirection().normalize().multiply(force * config.carrySettings().throwForce()); player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ENDER_DRAGON_FLAP, 1, 1); - for (Entity passenger : player.getPassengers()) { + for (Entity passenger : mountHandler.getDirectPassengers()) { delayedActions.schedule(() -> trailHandler.startTrail(passenger), 2); - player.removePassenger(passenger); + mountHandler.removePassenger(passenger); passenger.setVelocity(throwVec); plugin.getLogger().config("Throwing entity | Location:" + player.getLocation().toVector() + " | Force: " + force @@ -132,17 +187,53 @@ public void onSneak(PlayerToggleSneakEvent event) { + " | ViewVec: " + throwVec); } } - mountStates.remove(player.getUniqueId()); } } + @EventHandler + public void onChunkLoad(ChunkLoadEvent event){ + Arrays.stream(event.getChunk().getEntities()) + .filter(MountHandler::isOffsetter) // Filter for offsetters + .forEach(Entity::remove); // Remove them + } + + @EventHandler + public void onEntityDismount(EntityDismountEvent event){ + if(event.getDismounted() instanceof Player player) + Optional.ofNullable(mountHandlers.get(player.getUniqueId())) + .ifPresentOrElse(handler -> { + if(handler.getDirectPassengers().size() - 1 <= 0) + removePlayerData(player); + }, + () ->{ + removePlayerData(player); + }); + + + // If an ArmorStand just dismounted any entity + if(event.getEntity() instanceof ArmorStand armorStand){ + if(MountHandler.isOffsetter(armorStand)){ // If so, remove it from existence + armorStand.remove(); + } + } + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event){ + removePlayerData(event.getPlayer()); + } + private void unmountAll(Player player) { for (Entity passenger : player.getPassengers()) { player.removePassenger(passenger); } } - private enum MountState { - SNEAK_MOUNT, WALKING, SNEAK_THROW + private void removePlayerData(Player player){ + //If there is a pending task, cancel it + Optional.ofNullable(mountHandlers.remove(player.getUniqueId())) + .ifPresent(MountHandler::dispose); + throwBarHandler.getAndRemove(player); } } + diff --git a/src/main/java/de/eldoria/pickmeup/listener/MountHandler.java b/src/main/java/de/eldoria/pickmeup/listener/MountHandler.java new file mode 100644 index 0000000..6925fa4 --- /dev/null +++ b/src/main/java/de/eldoria/pickmeup/listener/MountHandler.java @@ -0,0 +1,187 @@ +package de.eldoria.pickmeup.listener; + +import de.eldoria.eldoutilities.utils.DataContainerUtil; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.persistence.PersistentDataType; +import org.bukkit.scheduler.BukkitTask; + +import java.util.List; + +public class MountHandler { + @SuppressWarnings("deprecation") + private static final NamespacedKey offsetterIdentifierKey = new NamespacedKey("pickmeup", "is-offsetter"); + + + public MountState state; + public BukkitTask throwTask; + + private final Player owner; + + private ArmorStand offsetter; + + public MountHandler(Player owner) { + this.owner = owner; + } + + public void cleanTasks() { + if (throwTask != null && !throwTask.isCancelled()) throwTask.cancel(); + } + + public void dispose() { + cleanTasks(); + + if (offsetter == null) return; + + for (Entity passenger : offsetter.getPassengers()) { + offsetter.removePassenger(passenger); + } + offsetter.remove(); + offsetter = null; + } + + public boolean addPassenger(Entity passenger) { + Entity mountable = getMountable(); + + if (mountable.getUniqueId() == passenger.getUniqueId()) + return false; + + return mountable.addPassenger(passenger); + } + + public boolean removePassenger(Entity passenger) { + Entity mountable = getMountable(); + + boolean result = false; + + if (mountable.getUniqueId() != passenger.getUniqueId()) { + result = mountable.removePassenger(passenger); + } + // If there are no more passengers, dispose + if (mountable.getPassengers().isEmpty()) dispose(); + + return result; + } + + public List getDirectPassengers() { + return getMountable().getPassengers(); + } + + public List getAllPassengers(boolean filterOffsetters) { + return getAllPassengers(owner, filterOffsetters); + } + + public int stackCount(boolean filterOffsetters) { + return stackCount(owner, filterOffsetters); + } + + private void setupOffsetter() { + if (offsetter != null && !offsetter.isDead()) + return; + + ArmorStand armorStand = owner.getWorld().spawn(owner.getLocation(), ArmorStand.class); + + armorStand.setInvulnerable(true); + armorStand.setInvisible(true); + //armorStand.setMarker(true); + armorStand.setSmall(true); + armorStand.setBasePlate(false); + //armorStand.setLeftArmPose(90); + //armorStand.setRightArmPose(90); + + + // Mark it as an offsetter so it can be easily identified for removal + DataContainerUtil.putValue(armorStand, offsetterIdentifierKey, PersistentDataType.BYTE, (byte) 1); + + + // Get the current passengers of the owner + List passengers = owner.getPassengers(); + + if (owner.addPassenger(armorStand)) { + offsetter = armorStand; + // Transfer any passengers from the owner to the offsetter + for (Entity passenger : passengers) { + offsetter.addPassenger(passenger); + } + } else { + armorStand.remove(); + } + } + + private Entity getMountable() { + setupOffsetter(); + + // If the offsetter is somehow null, default to the owner himself + return offsetter != null ? offsetter : owner; + } + + + public static boolean isOffsetter(Entity entity) { + return DataContainerUtil.get(entity, offsetterIdentifierKey, PersistentDataType.BYTE) + .map(b -> b == (byte) 0) + .orElse(false); + } + + public static List getDirectPassengers(Entity origin, boolean filterOffsetters) { + List passengers = origin.getPassengers(); + for (Entity passenger : passengers) { + if (isOffsetter(passenger)) { + passengers.addAll(passenger.getPassengers()); + if (filterOffsetters) + passengers.remove(passenger); + } + + } + + return passengers; + } + + public static List getAllPassengers(Entity origin, boolean filterOffsetters) { + List passengers = getPassengersRecursive(origin); + + if (filterOffsetters) { + passengers = passengers.stream().filter(MountHandler::isOffsetter).toList(); + } + + return passengers; + } + + private static List getPassengersRecursive(Entity mountable) { + List passengers = mountable.getPassengers(); + for (Entity passenger : passengers) { + passengers.addAll(getPassengersRecursive(passenger)); + } + + return passengers; + } + + public static int stackCount(Entity origin, boolean filterOffsetters) { + return stackCountRecursive(origin, filterOffsetters, 0); + } + + private static int stackCountRecursive(Entity mountable, boolean filterOffsetters, int level) { + List passengers = mountable.getPassengers(); + + int resultLevel = level; + if (!filterOffsetters || !isOffsetter(mountable)) { + resultLevel += 1; + } + + for (Entity passenger : passengers) { + int deeperLevel = stackCountRecursive(passenger, filterOffsetters, resultLevel); + + if (deeperLevel > resultLevel) { + resultLevel = deeperLevel; + } + + } + + return resultLevel; + } + + public enum MountState { + SNEAK_MOUNT, WALKING, SNEAK_THROW + } +} diff --git a/src/main/java/de/eldoria/pickmeup/scheduler/ThrowBarHandler.java b/src/main/java/de/eldoria/pickmeup/scheduler/ThrowBarHandler.java index 3ef5161..81aae9c 100644 --- a/src/main/java/de/eldoria/pickmeup/scheduler/ThrowBarHandler.java +++ b/src/main/java/de/eldoria/pickmeup/scheduler/ThrowBarHandler.java @@ -94,6 +94,8 @@ public void register(Player player) { public double getAndRemove(Player player) { AtomicInteger remove = currentValues.remove(player); + //Send an empty message to instantly hide the bar + sender.send(MessageChannel.ACTION_BAR, MessageType.BLANK, player, ""); if (remove != null) { return calculateForce(remove.get()); } diff --git a/src/main/java/de/eldoria/pickmeup/services/ProtectionService.java b/src/main/java/de/eldoria/pickmeup/services/ProtectionService.java index 9997909..5a5ef92 100644 --- a/src/main/java/de/eldoria/pickmeup/services/ProtectionService.java +++ b/src/main/java/de/eldoria/pickmeup/services/ProtectionService.java @@ -6,6 +6,7 @@ import de.eldoria.pickmeup.services.hooks.protection.PlotSquaredHook; import de.eldoria.pickmeup.services.hooks.protection.RedProtectHook; import de.eldoria.pickmeup.services.hooks.protection.TownyHook; +import de.eldoria.pickmeup.services.hooks.protection.SaberFactionsHook; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; @@ -55,6 +56,12 @@ public boolean canInteract(Player player, Location location) { } private static IProtectionHook[] hooks() { - return new IProtectionHook[]{new BentoBoxHook(), new GriefPreventionHook(), new PlotSquaredHook(), new TownyHook(), new RedProtectHook()}; + return new IProtectionHook[]{ + new BentoBoxHook(), + new GriefPreventionHook(), + new SaberFactionsHook(), + new PlotSquaredHook(), + new TownyHook(), + new RedProtectHook()}; } } diff --git a/src/main/java/de/eldoria/pickmeup/services/hooks/protection/SaberFactionsHook.java b/src/main/java/de/eldoria/pickmeup/services/hooks/protection/SaberFactionsHook.java new file mode 100644 index 0000000..f8aedae --- /dev/null +++ b/src/main/java/de/eldoria/pickmeup/services/hooks/protection/SaberFactionsHook.java @@ -0,0 +1,23 @@ +package de.eldoria.pickmeup.services.hooks.protection; + +import com.massivecraft.factions.listeners.FactionsPlayerListener; +import com.massivecraft.factions.zcore.fperms.PermissableAction; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +public class SaberFactionsHook extends AProtectionHook { + public SaberFactionsHook() { + super("Factions"); + } + + @Override + public void init(Plugin plugin) { + } + + @Override + public boolean canInteract(Player player, Location location) { + return FactionsPlayerListener.playerCanUseItemHere(player, location, Material.BUCKET, false, PermissableAction.ITEM); + } +} diff --git a/src/main/java/de/eldoria/pickmeup/util/Permissions.java b/src/main/java/de/eldoria/pickmeup/util/Permissions.java index 588c571..949f682 100644 --- a/src/main/java/de/eldoria/pickmeup/util/Permissions.java +++ b/src/main/java/de/eldoria/pickmeup/util/Permissions.java @@ -6,6 +6,8 @@ public final class Permissions { public static final String BASE = "pickmeup."; public static final String RELOAD = BASE + "reload"; public static final String BYPASS_NOSTACK = BASE + "bypass.nostack"; + public static final String BYPASS_MAXSTACK = BASE + "bypass.maxstack"; + //public static final String BYPASS_MAXSELFCARRY = BASE + "bypass.maxselfcarry"; private Permissions() { }