If the player has been given the brewery.sensitive.xx permission, will factor in the sensitivity to the given alcohol amount. + *
Will return the calculated value without changing the event + * + * @param alc The base amount of alcohol + * @return The amount of alcohol given the players alcohol-sensitivity + */ + @Contract(pure = true) + public int calcAlcWSensitivity(int alc) { + int sensitive = PermissionUtil.getDrinkSensitive(player); + if (sensitive == 0) { + alc = 0; + } else if (sensitive > 0) { + alc *= ((float) sensitive) / 100f; + } + return alc; + } + public Player getPlayer() { return player; } diff --git a/src/com/dre/brewery/filedata/BConfig.java b/src/com/dre/brewery/filedata/BConfig.java index 00e5e7f..44db141 100644 --- a/src/com/dre/brewery/filedata/BConfig.java +++ b/src/com/dre/brewery/filedata/BConfig.java @@ -82,6 +82,7 @@ public class BConfig { public static boolean enableLoginDisallow; public static boolean enablePuke; public static String homeType; + public static boolean enableWake; //Brew public static boolean colorInBarrels; // color the Lore while in Barrels @@ -89,6 +90,7 @@ public class BConfig { public static boolean enableEncode; public static boolean alwaysShowQuality; // Always show quality stars public static boolean alwaysShowAlc; // Always show alc% + public static boolean brewHopperDump; // Allow Dumping of Brew liquid into Hoppers //Features public static boolean craftSealingTable; // Allow Crafting of Sealing Table @@ -228,6 +230,7 @@ public class BConfig { stumbleModifier = ((float) config.getInt("stumblePercent", 100)) / 100f; showStatusOnDrink = config.getBoolean("showStatusOnDrink", false); homeType = config.getString("homeType", null); + enableWake = config.getBoolean("enableWake", false); craftSealingTable = config.getBoolean("craftSealingTable", false); enableSealingTable = config.getBoolean("enableSealingTable", false); colorInBarrels = config.getBoolean("colorInBarrels", false); @@ -240,6 +243,7 @@ public class BConfig { minimalParticles = config.getBoolean("minimalParticles", false); useOffhandForCauldron = config.getBoolean("useOffhandForCauldron", false); loadDataAsync = config.getBoolean("loadDataAsync", true); + brewHopperDump = config.getBoolean("brewHopperDump", false); if (P.use1_14) { MCBarrel.maxBrews = config.getInt("maxBrewsInMCBarrels", 6); diff --git a/src/com/dre/brewery/integration/IntegrationListener.java b/src/com/dre/brewery/integration/IntegrationListener.java index ebea3df..4408b45 100644 --- a/src/com/dre/brewery/integration/IntegrationListener.java +++ b/src/com/dre/brewery/integration/IntegrationListener.java @@ -15,7 +15,7 @@ import com.dre.brewery.integration.item.MMOItemsPluginItem; import com.dre.brewery.recipe.BCauldronRecipe; import com.dre.brewery.recipe.RecipeItem; import com.dre.brewery.utility.LegacyUtil; -import net.mmogroup.mmolib.api.item.NBTItem; +import io.lumine.mythic.lib.api.item.NBTItem; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.block.Block; @@ -318,12 +318,13 @@ public class IntegrationListener implements Listener { // Catch the Interact Event early, so MMOItems does not act before us and cancel the event while we try to add it to the Cauldron if (!P.use1_9) return; if (BConfig.hasMMOItems == null) { - BConfig.hasMMOItems = P.p.getServer().getPluginManager().isPluginEnabled("MMOItems"); + BConfig.hasMMOItems = P.p.getServer().getPluginManager().isPluginEnabled("MMOItems") + && P.p.getServer().getPluginManager().isPluginEnabled("MythicLib"); } if (!BConfig.hasMMOItems) return; try { if (event.getAction() == Action.RIGHT_CLICK_BLOCK && event.hasItem() && event.getHand() == EquipmentSlot.HAND) { - if (event.getClickedBlock() != null && event.getClickedBlock().getType() == Material.CAULDRON) { + if (event.getClickedBlock() != null && LegacyUtil.isWaterCauldron(event.getClickedBlock().getType())) { NBTItem item = NBTItem.get(event.getItem()); if (item.hasType()) { for (RecipeItem rItem : BCauldronRecipe.acceptedCustom) { diff --git a/src/com/dre/brewery/integration/item/MMOItemsPluginItem.java b/src/com/dre/brewery/integration/item/MMOItemsPluginItem.java index 8ef60b9..ff4eef4 100644 --- a/src/com/dre/brewery/integration/item/MMOItemsPluginItem.java +++ b/src/com/dre/brewery/integration/item/MMOItemsPluginItem.java @@ -3,7 +3,7 @@ package com.dre.brewery.integration.item; import com.dre.brewery.P; import com.dre.brewery.filedata.BConfig; import com.dre.brewery.recipe.PluginItem; -import net.mmogroup.mmolib.api.item.NBTItem; +import io.lumine.mythic.lib.api.item.NBTItem; import org.bukkit.inventory.ItemStack; public class MMOItemsPluginItem extends PluginItem { @@ -15,7 +15,8 @@ public class MMOItemsPluginItem extends PluginItem { @Override public boolean matches(ItemStack item) { if (BConfig.hasMMOItems == null) { - BConfig.hasMMOItems = P.p.getServer().getPluginManager().isPluginEnabled("MMOItems"); + BConfig.hasMMOItems = P.p.getServer().getPluginManager().isPluginEnabled("MMOItems") + && P.p.getServer().getPluginManager().isPluginEnabled("MythicLib"); } if (!BConfig.hasMMOItems) return false; diff --git a/src/com/dre/brewery/integration/item/SlimefunPluginItem.java b/src/com/dre/brewery/integration/item/SlimefunPluginItem.java index e3f72dd..010f737 100644 --- a/src/com/dre/brewery/integration/item/SlimefunPluginItem.java +++ b/src/com/dre/brewery/integration/item/SlimefunPluginItem.java @@ -23,9 +23,9 @@ public class SlimefunPluginItem extends PluginItem { try { SlimefunItem sfItem = SlimefunItem.getByItem(item); if (sfItem != null) { - return sfItem.getID().equalsIgnoreCase(getItemId()); + return sfItem.getId().equalsIgnoreCase(getItemId()); } - } catch (Throwable e) { + } catch (Exception | LinkageError e) { e.printStackTrace(); P.p.errorLog("Could not check Slimefun for Item ID"); BConfig.hasSlimefun = false; diff --git a/src/com/dre/brewery/listeners/CauldronListener.java b/src/com/dre/brewery/listeners/CauldronListener.java index c119c58..ff8ff2e 100644 --- a/src/com/dre/brewery/listeners/CauldronListener.java +++ b/src/com/dre/brewery/listeners/CauldronListener.java @@ -1,6 +1,11 @@ package com.dre.brewery.listeners; import com.dre.brewery.BCauldron; +import com.dre.brewery.P; +import com.dre.brewery.utility.LegacyUtil; +import org.bukkit.Material; +import org.bukkit.block.BlockState; +import org.bukkit.block.data.Levelled; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -8,8 +13,44 @@ import org.bukkit.event.block.CauldronLevelChangeEvent; public class CauldronListener implements Listener { + /** + * Water in Cauldron gets filled up: remove BCauldron to disallow unlimited Brews + * Water in Cauldron gets removed: remove BCauldron to remove Brew data and stop particles + */ @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onCauldronChange(CauldronLevelChangeEvent event) { + if (LegacyUtil.WATER_CAULDRON == null) { + // < 1.17 + oldCauldronChange(event); + return; + } + + Material currentType = event.getBlock().getType(); + BlockState newState = event.getNewState(); + Material newType = newState.getType(); + + if (currentType == Material.WATER_CAULDRON) { + if (newType != Material.WATER_CAULDRON) { + // Change from water to anything else + if (event.getReason() != CauldronLevelChangeEvent.ChangeReason.BOTTLE_FILL) { + BCauldron.remove(event.getBlock()); + } + } else { // newType == Material.WATER_CAULDRON + // Water level change + Levelled oldCauldron = ((Levelled) event.getBlock().getBlockData()); + Levelled newCauldron = ((Levelled) newState.getBlockData()); + + // Water Level increased somehow, might be Bucket, Bottle, Rain, etc. + if (newCauldron.getLevel() > oldCauldron.getLevel()) { + BCauldron.remove(event.getBlock()); + } + } + } + } + + + @SuppressWarnings("deprecation") + private void oldCauldronChange(CauldronLevelChangeEvent event) { if (event.getNewLevel() == 0 && event.getOldLevel() != 0) { if (event.getReason() == CauldronLevelChangeEvent.ChangeReason.BOTTLE_FILL) { return; diff --git a/src/com/dre/brewery/listeners/CommandListener.java b/src/com/dre/brewery/listeners/CommandListener.java index 5f799aa..e2357d5 100644 --- a/src/com/dre/brewery/listeners/CommandListener.java +++ b/src/com/dre/brewery/listeners/CommandListener.java @@ -512,7 +512,8 @@ public class CommandListener implements CommandExecutor { int ingQ = ingredients.getIngredientQuality(recipe); int cookQ = ingredients.getCookingQuality(recipe, false); int cookDistQ = ingredients.getCookingQuality(recipe, true); - P.p.log(recipe.getRecipeName() + ": ingQlty: " + ingQ + ", cookQlty:" + cookQ + ", cook+DistQlty: " + cookDistQ); + int ageQ = ingredients.getAgeQuality(recipe, brew.getAgeTime()); + P.p.log(recipe.getRecipeName() + ": ingQlty: " + ingQ + ", cookQlty:" + cookQ + ", cook+DistQlty: " + cookDistQ + ", ageQlty: " + ageQ); } BRecipe distill = ingredients.getBestRecipe(brew.getWood(), brew.getAgeTime(), true); BRecipe nonDistill = ingredients.getBestRecipe(brew.getWood(), brew.getAgeTime(), false); @@ -535,7 +536,8 @@ public class CommandListener implements CommandExecutor { int ingQ = ingredients.getIngredientQuality(recipe); int cookQ = ingredients.getCookingQuality(recipe, false); int cookDistQ = ingredients.getCookingQuality(recipe, true); - P.p.log("ingQlty: " + ingQ + ", cookQlty:" + cookQ + ", cook+DistQlty: " + cookDistQ); + int ageQ = ingredients.getAgeQuality(recipe, brew.getAgeTime()); + P.p.log("ingQlty: " + ingQ + ", cookQlty:" + cookQ + ", cook+DistQlty: " + cookDistQ + ", ageQlty: " + ageQ); } P.p.msg(player, "Debug Info for item written into Log"); diff --git a/src/com/dre/brewery/listeners/PlayerListener.java b/src/com/dre/brewery/listeners/PlayerListener.java index 05077b6..9e3a948 100644 --- a/src/com/dre/brewery/listeners/PlayerListener.java +++ b/src/com/dre/brewery/listeners/PlayerListener.java @@ -3,12 +3,15 @@ package com.dre.brewery.listeners; import com.dre.brewery.*; import com.dre.brewery.filedata.BConfig; import com.dre.brewery.filedata.UpdateChecker; +import com.dre.brewery.utility.BUtil; import com.dre.brewery.utility.LegacyUtil; import com.dre.brewery.utility.PermissionUtil; import org.bukkit.GameMode; import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -29,20 +32,31 @@ public class PlayerListener implements Listener { if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; Player player = event.getPlayer(); - if (player.isSneaking()) return; - Material type = clickedBlock.getType(); - // Interacting with a Cauldron - if (type == Material.CAULDRON) { - // Handle the Cauldron Interact - // The Event might get cancelled in here - BCauldron.clickCauldron(event); + // -- Clicking an Hopper -- + if (type == Material.HOPPER) { + if (BConfig.brewHopperDump && event.getPlayer().isSneaking()) { + if (!P.use1_9 || event.getHand() == EquipmentSlot.HAND) { + ItemStack item = event.getItem(); + if (Brew.isBrew(item)) { + event.setCancelled(true); + BUtil.setItemInHand(event, Material.GLASS_BOTTLE, false); + if (P.use1_11) { + clickedBlock.getWorld().playSound(clickedBlock.getLocation(), Sound.ITEM_BOTTLE_EMPTY, 1f, 1f); + } + } + } + } return; } - + // -- Opening a Sealing Table -- if (P.use1_14 && BSealer.isBSealer(clickedBlock)) { + if (player.isSneaking()) { + event.setUseInteractedBlock(Event.Result.DENY); + return; + } event.setCancelled(true); if (BConfig.enableSealingTable) { BSealer sealer = new BSealer(player); @@ -52,6 +66,18 @@ public class PlayerListener implements Listener { } return; } + + if (player.isSneaking()) return; + + // -- Interacting with a Cauldron -- + if (LegacyUtil.isWaterCauldron(type)) { + // Handle the Cauldron Interact + // The Event might get cancelled in here + BCauldron.clickCauldron(event); + return; + } + + // -- Opening a Minecraft Barrel -- if (P.use1_14 && type == Material.BARREL) { if (!player.hasPermission("brewery.openbarrel.mc")) { event.setCancelled(true); @@ -65,7 +91,7 @@ public class PlayerListener implements Listener { return; } - // Access a Barrel + // -- Access a Barrel -- Barrel barrel = null; if (LegacyUtil.isWoodPlanks(type)) { if (BConfig.openEverywhere) { diff --git a/src/com/dre/brewery/lore/BrewLore.java b/src/com/dre/brewery/lore/BrewLore.java index 6453f2e..20ab518 100644 --- a/src/com/dre/brewery/lore/BrewLore.java +++ b/src/com/dre/brewery/lore/BrewLore.java @@ -275,7 +275,7 @@ public class BrewLore { } public void updateAlc(boolean inDistiller) { - if (!brew.isUnlabeled() && (inDistiller || BConfig.alwaysShowAlc) && (!brew.hasRecipe() || brew.getCurrentRecipe().getAlcohol() > 0)) { + if (!brew.isUnlabeled() && (inDistiller || BConfig.alwaysShowAlc) && (!brew.hasRecipe() || brew.getCurrentRecipe().getAlcohol() != 0)) { int alc = brew.getOrCalcAlc(); addOrReplaceLore(Type.ALC, "§8", P.p.languageReader.get("Brew_Alc", alc + "")); } else { diff --git a/src/com/dre/brewery/recipe/BRecipe.java b/src/com/dre/brewery/recipe/BRecipe.java index 3d3d1e1..f649dfc 100644 --- a/src/com/dre/brewery/recipe/BRecipe.java +++ b/src/com/dre/brewery/recipe/BRecipe.java @@ -326,7 +326,7 @@ public class BRecipe { P.p.errorLog("Invalid distilltime '" + distillTime + "' in Recipe: " + getRecipeName()); return false; } - if (wood < 0 || wood > 6) { + if (wood < 0 || wood > 8) { P.p.errorLog("Invalid wood type '" + wood + "' in Recipe: " + getRecipeName()); return false; } @@ -338,10 +338,6 @@ public class BRecipe { P.p.errorLog("Invalid difficulty '" + difficulty + "' in Recipe: " + getRecipeName()); return false; } - if (alcohol < 0) { - P.p.errorLog("Invalid alcohol '" + alcohol + "' in Recipe: " + getRecipeName()); - return false; - } return true; } diff --git a/src/com/dre/brewery/utility/BUtil.java b/src/com/dre/brewery/utility/BUtil.java index 07e5721..7c57371 100644 --- a/src/com/dre/brewery/utility/BUtil.java +++ b/src/com/dre/brewery/utility/BUtil.java @@ -13,6 +13,9 @@ import org.bukkit.block.Block; import org.bukkit.command.CommandSender; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.jetbrains.annotations.Nullable; @@ -78,6 +81,26 @@ public class BUtil { ); } + /** + * Sets the Item in the Players hand, depending on which hand he used and if the hand should be swapped + * + * @param event Interact Event to tell which hand the player used + * @param mat The Material of the new item + * @param swapped If true, will set the opposite Hand instead of the one he used + */ + @SuppressWarnings("deprecation") + public static void setItemInHand(PlayerInteractEvent event, Material mat, boolean swapped) { + if (P.use1_9) { + if ((event.getHand() == EquipmentSlot.OFF_HAND) != swapped) { + event.getPlayer().getInventory().setItemInOffHand(new ItemStack(mat)); + } else { + event.getPlayer().getInventory().setItemInMainHand(new ItemStack(mat)); + } + } else { + event.getPlayer().setItemInHand(new ItemStack(mat)); + } + } + /** * Returns either uuid or Name of player, depending on bukkit version */ @@ -234,8 +257,11 @@ public class BUtil { * @return True if the Block can be destroyed */ public static boolean blockDestroy(Block block, Player player, BarrelDestroyEvent.Reason reason) { + if (block == null || block.getType() == null) { + return true; + } Material type = block.getType(); - if (type == Material.CAULDRON) { + if (type == Material.CAULDRON || type == LegacyUtil.WATER_CAULDRON) { // will only remove when existing BCauldron.remove(block); return true; diff --git a/src/com/dre/brewery/utility/LegacyUtil.java b/src/com/dre/brewery/utility/LegacyUtil.java index d050601..58db8b6 100644 --- a/src/com/dre/brewery/utility/LegacyUtil.java +++ b/src/com/dre/brewery/utility/LegacyUtil.java @@ -78,6 +78,7 @@ public class LegacyUtil { FENCES = fences; } + public static final Material WATER_CAULDRON = get("WATER_CAULDRON"); public static final Material MAGMA_BLOCK = get("MAGMA_BLOCK", "MAGMA"); public static final Material CAMPFIRE = get("CAMPFIRE"); public static final Material SOUL_CAMPFIRE = get("SOUL_CAMPFIRE"); @@ -220,13 +221,20 @@ public class LegacyUtil { } } + /** + * Test if this Material Type is a Cauldron filled with water, or any cauldron in 1.16 and lower + */ + public static boolean isWaterCauldron(Material type) { + return WATER_CAULDRON != null ? type == WATER_CAULDRON : type == Material.CAULDRON; + } + /** * Get The Fill Level of a Cauldron Block, 0 = empty, 1 = something in, 2 = full * * @return 0 = empty, 1 = something in, 2 = full */ public static byte getFillLevel(Block block) { - if (block.getType() != Material.CAULDRON) { + if (!isWaterCauldron(block.getType())) { return EMPTY; } diff --git a/src/com/dre/brewery/utility/PermissionUtil.java b/src/com/dre/brewery/utility/PermissionUtil.java index 5cc5316..a033e1f 100644 --- a/src/com/dre/brewery/utility/PermissionUtil.java +++ b/src/com/dre/brewery/utility/PermissionUtil.java @@ -1,9 +1,13 @@ package com.dre.brewery.utility; +import org.apache.commons.lang.math.NumberUtils; import org.bukkit.command.CommandSender; +import org.bukkit.permissions.Permissible; +import org.bukkit.permissions.PermissionAttachmentInfo; import java.util.HashMap; import java.util.Map; +import java.util.Optional; public class PermissionUtil { @@ -76,6 +80,59 @@ public class PermissionUtil { return sender.hasPermission(bPerm.permission); } + /** + * Returns the Sensitivity of the Player towards Alcohol in percent. + *
Sensitivity describes how much of the alcohol gets transferred to the players drunkeness + * + *
100 means normal alcohol sensitivity + *
less than 100 means less alcohol gets added. + *
more than 100 means more alcohol gets added. + *
0 means no alcohol gets added. + * + * @param player The player of whom to get the sensitivity of + * @return The Players alcohol sensitivity + */ + public static int getDrinkSensitive(Permissible player) { + return getRangedPermission(player, "brewery.sensitive."); + } + + /** + * Returns the Alcohol recovery rate of the player in drunkeness per minute. + *
The default is 2 drunkeness per minute + * + * + * @param player The player of whom to get the recovery rate of + * @return The Players alcohol recovery rate + */ + public static int getAlcRecovery(Permissible player) { + return getRangedPermission(player, "brewery.recovery."); + } + + /** + * Get the number behind the given permission + *
i.e. for brewery.sensitive.100 it returns 100
+ *
+ * @param player The player to get the ranged permission of
+ * @param subPermission The permission string before the number
+ * @return The permission number as int
+ */
+ public static int getRangedPermission(Permissible player, String subPermission) {
+ Optional