From 988006f913527dfdd3009e10a3760fa11a3e6795 Mon Sep 17 00:00:00 2001 From: GJ Date: Tue, 11 Feb 2014 16:22:57 -0500 Subject: [PATCH] Alchemy cleanup, part 1. --- .../commands/skills/AlchemyCommand.java | 4 +- .../config/skills/alchemy/PotionConfig.java | 49 +++- .../skills/alchemy/AlchemyPotion.java | 4 - .../nossr50/listeners/InventoryListener.java | 147 +++++++++- .../skills/AlchemyBrewCheckTask.java | 5 +- .../runnables/skills/AlchemyBrewTask.java | 7 +- .../gmail/nossr50/skills/alchemy/Alchemy.java | 18 +- .../skills/alchemy/AlchemyManager.java | 59 +--- .../skills/alchemy/AlchemyPotionBrewer.java | 260 +++++------------- 9 files changed, 264 insertions(+), 289 deletions(-) diff --git a/src/main/java/com/gmail/nossr50/commands/skills/AlchemyCommand.java b/src/main/java/com/gmail/nossr50/commands/skills/AlchemyCommand.java index e0fd61c4c..1853a4083 100644 --- a/src/main/java/com/gmail/nossr50/commands/skills/AlchemyCommand.java +++ b/src/main/java/com/gmail/nossr50/commands/skills/AlchemyCommand.java @@ -33,8 +33,8 @@ public class AlchemyCommand extends SkillCommand { AlchemyManager alchemyManager = UserManager.getPlayer(player).getAlchemyManager(); String[] displayValues = new String[2]; - displayValues[0] = decimal.format(alchemyManager.getBrewSpeed()) + "x"; - displayValues[1] = isLucky ? decimal.format(alchemyManager.getBrewSpeedLucky()) + "x" : null; + displayValues[0] = decimal.format(alchemyManager.calculateBrewSpeed(false)) + "x"; + displayValues[1] = isLucky ? decimal.format(alchemyManager.calculateBrewSpeed(true)) + "x" : null; return displayValues; } diff --git a/src/main/java/com/gmail/nossr50/config/skills/alchemy/PotionConfig.java b/src/main/java/com/gmail/nossr50/config/skills/alchemy/PotionConfig.java index 2d881b1fe..0a0f91eb3 100644 --- a/src/main/java/com/gmail/nossr50/config/skills/alchemy/PotionConfig.java +++ b/src/main/java/com/gmail/nossr50/config/skills/alchemy/PotionConfig.java @@ -5,6 +5,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import com.gmail.nossr50.skills.alchemy.Alchemy; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; @@ -18,16 +19,16 @@ import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion; public class PotionConfig extends ConfigLoader { private static PotionConfig instance; - public List concoctionsIngredientsTierOne = new ArrayList(); - public List concoctionsIngredientsTierTwo = new ArrayList(); - public List concoctionsIngredientsTierThree = new ArrayList(); - public List concoctionsIngredientsTierFour = new ArrayList(); - public List concoctionsIngredientsTierFive = new ArrayList(); - public List concoctionsIngredientsTierSix = new ArrayList(); - public List concoctionsIngredientsTierSeven = new ArrayList(); - public List concoctionsIngredientsTierEight = new ArrayList(); + private List concoctionsIngredientsTierOne = new ArrayList(); + private List concoctionsIngredientsTierTwo = new ArrayList(); + private List concoctionsIngredientsTierThree = new ArrayList(); + private List concoctionsIngredientsTierFour = new ArrayList(); + private List concoctionsIngredientsTierFive = new ArrayList(); + private List concoctionsIngredientsTierSix = new ArrayList(); + private List concoctionsIngredientsTierSeven = new ArrayList(); + private List concoctionsIngredientsTierEight = new ArrayList(); - public Map potionMap = new HashMap(); + private Map potionMap = new HashMap(); private PotionConfig() { super("potions.yml"); @@ -189,4 +190,34 @@ public class PotionConfig extends ConfigLoader { return null; } + + public List getIngredients(int tier) { + switch (tier) { + case 8: + return concoctionsIngredientsTierEight; + case 7: + return concoctionsIngredientsTierSeven; + case 6: + return concoctionsIngredientsTierSix; + case 5: + return concoctionsIngredientsTierFive; + case 4: + return concoctionsIngredientsTierFour; + case 3: + return concoctionsIngredientsTierThree; + case 2: + return concoctionsIngredientsTierTwo; + case 1: + default: + return concoctionsIngredientsTierOne; + } + } + + public boolean isValidPotion(ItemStack item) { + return potionMap.containsKey(item.getDurability()); + } + + public AlchemyPotion getPotion(short durability) { + return potionMap.get(durability); + } } diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/alchemy/AlchemyPotion.java b/src/main/java/com/gmail/nossr50/datatypes/skills/alchemy/AlchemyPotion.java index 490dc9cdb..6ad921548 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/alchemy/AlchemyPotion.java +++ b/src/main/java/com/gmail/nossr50/datatypes/skills/alchemy/AlchemyPotion.java @@ -28,10 +28,6 @@ public class AlchemyPotion { return "AlchemyPotion{" + dataValue + "," + name + ",Effects[" + effects.size() + "], Children[" + children.size() + "]}"; } - public ItemStack toItemStack() { - return toItemStack(1); - } - public ItemStack toItemStack(int amount) { ItemStack potion = new ItemStack(Material.POTION, amount, this.getDataValue()); PotionMeta meta = (PotionMeta) potion.getItemMeta(); diff --git a/src/main/java/com/gmail/nossr50/listeners/InventoryListener.java b/src/main/java/com/gmail/nossr50/listeners/InventoryListener.java index 7e4ed79a9..c120698e4 100644 --- a/src/main/java/com/gmail/nossr50/listeners/InventoryListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/InventoryListener.java @@ -12,6 +12,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.CraftItemEvent; import org.bukkit.event.inventory.FurnaceBurnEvent; import org.bukkit.event.inventory.FurnaceExtractEvent; @@ -22,8 +23,10 @@ import org.bukkit.event.inventory.InventoryDragEvent; import org.bukkit.event.inventory.InventoryMoveItemEvent; import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.BrewerInventory; import org.bukkit.inventory.FurnaceInventory; import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; import org.bukkit.metadata.MetadataValue; @@ -32,6 +35,7 @@ import com.gmail.nossr50.config.Config; import com.gmail.nossr50.datatypes.skills.SecondaryAbility; import com.gmail.nossr50.datatypes.skills.SkillType; import com.gmail.nossr50.runnables.PlayerUpdateInventoryTask; +import com.gmail.nossr50.skills.alchemy.Alchemy; import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer; import com.gmail.nossr50.util.ItemUtils; import com.gmail.nossr50.util.Misc; @@ -138,43 +142,166 @@ public class InventoryListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onInventoryClickEventNormal(InventoryClickEvent event) { - if (event.getInventory().getType() != InventoryType.BREWING || !(event.getInventory().getHolder() instanceof BrewingStand)) { + Inventory inventory = event.getInventory(); + + if (!(inventory instanceof BrewerInventory)) { return; } - if (!(event.getWhoClicked() instanceof Player) || Misc.isNPCEntity(event.getWhoClicked()) || !Permissions.concoctions(event.getWhoClicked())) { + InventoryHolder holder = inventory.getHolder(); + + if (!(holder instanceof BrewingStand)) { return; } - AlchemyPotionBrewer.handleInventoryClick(event); + HumanEntity whoClicked = event.getWhoClicked(); + + if (Misc.isNPCEntity(whoClicked) || !(whoClicked instanceof Player) || !Permissions.secondaryAbilityEnabled(whoClicked, SecondaryAbility.CONCOCTIONS)) { + return; + } + + Player player = (Player) whoClicked; + BrewingStand stand = (BrewingStand) holder; + ItemStack clicked = event.getCurrentItem(); + + if (clicked != null && clicked.getType() == Material.POTION) { + AlchemyPotionBrewer.scheduleCheck(player, stand); + return; + } + + ClickType click = event.getClick(); + InventoryType.SlotType slot = event.getSlotType(); + + if (click.isShiftClick()) { + switch (slot) { + case FUEL: + AlchemyPotionBrewer.scheduleCheck(player, stand); + return; + case CONTAINER: + case QUICKBAR: + if (!AlchemyPotionBrewer.isValidIngredient(player, clicked)) { + return; + } + + AlchemyPotionBrewer.transferItems(event.getView(), event.getRawSlot(), Alchemy.INGREDIENT_SLOT, click); + event.setCancelled(true); + AlchemyPotionBrewer.scheduleUpdate(inventory); + AlchemyPotionBrewer.scheduleCheck(player, stand); + return; + default: + return; + } + } + else if (slot == InventoryType.SlotType.FUEL) { + ItemStack cursor = event.getCursor(); + boolean emptyClicked = AlchemyPotionBrewer.isEmpty(clicked); + + if (AlchemyPotionBrewer.isEmpty(cursor)) { + if (emptyClicked) { + if (click == ClickType.NUMBER_KEY) { + AlchemyPotionBrewer.scheduleCheck(player, stand); + return; + } + } + + AlchemyPotionBrewer.scheduleCheck(player, stand); + } + else if (emptyClicked) { + if (AlchemyPotionBrewer.isValidIngredient(player, cursor)) { + int amount = cursor.getAmount(); + + if (click == ClickType.LEFT || (click == ClickType.RIGHT && amount == 1)) { + event.setCancelled(true); + event.setCurrentItem(cursor.clone()); + event.setCursor(null); + + AlchemyPotionBrewer.scheduleUpdate(inventory); + AlchemyPotionBrewer.scheduleCheck(player, stand); + } + else if (click == ClickType.RIGHT) { + event.setCancelled(true); + + ItemStack one = cursor.clone(); + one.setAmount(1); + + ItemStack rest = cursor.clone(); + rest.setAmount(amount - 1); + + event.setCurrentItem(one); + event.setCursor(rest); + + AlchemyPotionBrewer.scheduleUpdate(inventory); + AlchemyPotionBrewer.scheduleCheck(player, stand); + } + } + } + } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onInventoryDragEvent(InventoryDragEvent event) { - if (event.getInventory().getType() != InventoryType.BREWING || !(event.getInventory().getHolder() instanceof BrewingStand)) { + Inventory inventory = event.getInventory(); + + if (!(inventory instanceof BrewerInventory)) { return; } - if (!(event.getWhoClicked() instanceof Player) || Misc.isNPCEntity(event.getWhoClicked()) || !Permissions.concoctions(event.getWhoClicked())) { + InventoryHolder holder = inventory.getHolder(); + + if (!(holder instanceof BrewingStand)) { return; } - AlchemyPotionBrewer.handleInventoryDrag(event); + HumanEntity whoClicked = event.getWhoClicked(); + + if (Misc.isNPCEntity(whoClicked) || !(whoClicked instanceof Player) || !Permissions.secondaryAbilityEnabled(whoClicked, SecondaryAbility.CONCOCTIONS)) { + return; + } + + if (!event.getInventorySlots().contains(Alchemy.INGREDIENT_SLOT)) { + return; + } + + ItemStack cursor = event.getCursor(); + ItemStack ingredient = ((BrewerInventory) inventory).getIngredient(); + + if (AlchemyPotionBrewer.isEmpty(ingredient) || ingredient.isSimilar(cursor)) { + Player player = (Player) whoClicked; + + if (AlchemyPotionBrewer.isValidIngredient(player, cursor)) { + // Not handled: dragging custom ingredients over ingredient slot (does not trigger any event) + AlchemyPotionBrewer.scheduleCheck(player, (BrewingStand) holder); + return; + } + + event.setCancelled(true); + AlchemyPotionBrewer.scheduleUpdate(inventory); + } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onInventoryMoveItemEvent(InventoryMoveItemEvent event) { - if (event.getDestination().getType() != InventoryType.BREWING || !(event.getDestination().getHolder() instanceof BrewingStand)) { + Inventory inventory = event.getDestination(); + + if (!(inventory instanceof BrewerInventory)) { return; } - if (Config.getInstance().getPreventHopperTransfer() && event.getItem() != null && event.getItem().getType() != Material.POTION) { + InventoryHolder holder = inventory.getHolder(); + + if (!(holder instanceof BrewingStand)) { + return; + } + + ItemStack item = event.getItem(); + + if (Config.getInstance().getPreventHopperTransfer() && item.getType() != Material.POTION) { event.setCancelled(true); return; } - if (Config.getInstance().getEnabledForHoppers()) { - AlchemyPotionBrewer.handleInventoryMoveItem(event); + if (Config.getInstance().getEnabledForHoppers() && AlchemyPotionBrewer.isValidIngredient(null, item)) { + AlchemyPotionBrewer.scheduleCheck(null, (BrewingStand) holder); } } diff --git a/src/main/java/com/gmail/nossr50/runnables/skills/AlchemyBrewCheckTask.java b/src/main/java/com/gmail/nossr50/runnables/skills/AlchemyBrewCheckTask.java index 62e414223..d0a12bc76 100644 --- a/src/main/java/com/gmail/nossr50/runnables/skills/AlchemyBrewCheckTask.java +++ b/src/main/java/com/gmail/nossr50/runnables/skills/AlchemyBrewCheckTask.java @@ -12,8 +12,6 @@ import com.gmail.nossr50.skills.alchemy.Alchemy; import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer; public class AlchemyBrewCheckTask extends BukkitRunnable { - private final static int INGREDIENT_SLOT = 3; - private Player player; private BrewingStand brewingStand; private ItemStack[] oldInventory; @@ -30,7 +28,7 @@ public class AlchemyBrewCheckTask extends BukkitRunnable { ItemStack[] newInventory = Arrays.copyOfRange(((BrewingStand) block.getState()).getInventory().getContents(), 0, 4); if (Alchemy.brewingStandMap.containsKey(brewingStand)) { - if (oldInventory[INGREDIENT_SLOT] == null || newInventory[INGREDIENT_SLOT] == null || !oldInventory[INGREDIENT_SLOT].isSimilar(newInventory[INGREDIENT_SLOT]) || !AlchemyPotionBrewer.isValidBrew(player, newInventory)) { + if (oldInventory[Alchemy.INGREDIENT_SLOT] == null || newInventory[Alchemy.INGREDIENT_SLOT] == null || !oldInventory[Alchemy.INGREDIENT_SLOT].isSimilar(newInventory[Alchemy.INGREDIENT_SLOT]) || !AlchemyPotionBrewer.isValidBrew(player, newInventory)) { Alchemy.brewingStandMap.get(brewingStand).cancelBrew(); } } @@ -39,5 +37,4 @@ public class AlchemyBrewCheckTask extends BukkitRunnable { Alchemy.brewingStandMap.put(brewingStand, new AlchemyBrewTask(brewingStand, player)); } } - } diff --git a/src/main/java/com/gmail/nossr50/runnables/skills/AlchemyBrewTask.java b/src/main/java/com/gmail/nossr50/runnables/skills/AlchemyBrewTask.java index b100d5a06..0cde3181f 100644 --- a/src/main/java/com/gmail/nossr50/runnables/skills/AlchemyBrewTask.java +++ b/src/main/java/com/gmail/nossr50/runnables/skills/AlchemyBrewTask.java @@ -34,14 +34,11 @@ public class AlchemyBrewTask extends BukkitRunnable { brewTimer = DEFAULT_BREW_TICKS; if (player != null && !Misc.isNPCEntity(player) && Permissions.secondaryAbilityEnabled(player, SecondaryAbility.CATALYSIS)) { - double catalysis = UserManager.getPlayer(player).getAlchemyManager().getBrewSpeed(); - - if (Permissions.lucky(player, SkillType.ALCHEMY)) { - catalysis = UserManager.getPlayer(player).getAlchemyManager().getBrewSpeedLucky(); - } + double catalysis = UserManager.getPlayer(player).getAlchemyManager().calculateBrewSpeed(Permissions.lucky(player, SkillType.ALCHEMY)); McMMOPlayerCatalysisEvent event = new McMMOPlayerCatalysisEvent(player, catalysis); mcMMO.p.getServer().getPluginManager().callEvent(event); + if (!event.isCancelled()) { brewSpeed = catalysis; } diff --git a/src/main/java/com/gmail/nossr50/skills/alchemy/Alchemy.java b/src/main/java/com/gmail/nossr50/skills/alchemy/Alchemy.java index be7b0628b..57059b8c6 100644 --- a/src/main/java/com/gmail/nossr50/skills/alchemy/Alchemy.java +++ b/src/main/java/com/gmail/nossr50/skills/alchemy/Alchemy.java @@ -44,6 +44,8 @@ public final class Alchemy { } } + public static final int INGREDIENT_SLOT = 3; + public static int catalysisUnlockLevel = AdvancedConfig.getInstance().getCatalysisUnlockLevel(); public static int catalysisMaxBonusLevel = AdvancedConfig.getInstance().getCatalysisMaxBonusLevel(); public static double catalysisMinSpeed = AdvancedConfig.getInstance().getCatalysisMinSpeed(); @@ -53,26 +55,12 @@ public final class Alchemy { private Alchemy() {} - /** - * Calculate base brewing speed, given a skill level and ignoring all perks. - * - * @param skillLevel Skill level used for calculation. - * - * @return Base brewing speed for the level. - */ - public static double calculateBrewSpeed(int skillLevel) { - if (skillLevel < catalysisUnlockLevel) { - return catalysisMinSpeed; - } - - return Math.min(catalysisMaxSpeed, catalysisMinSpeed + (catalysisMaxSpeed - catalysisMinSpeed) * (skillLevel - catalysisUnlockLevel) / (catalysisMaxBonusLevel - catalysisUnlockLevel)); - } - /** * Finish all active brews. Used upon Disable to prevent vanilla potions from being brewed upon next Enable. */ public static void finishAllBrews() { mcMMO.p.debug("Completing " + brewingStandMap.size() + " unfinished Alchemy brews."); + for (AlchemyBrewTask alchemyBrewTask : brewingStandMap.values()) { alchemyBrewTask.finishImmediately(); } diff --git a/src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyManager.java b/src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyManager.java index a1fc7cf1c..27c7b2433 100644 --- a/src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyManager.java +++ b/src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyManager.java @@ -2,15 +2,14 @@ package com.gmail.nossr50.skills.alchemy; import java.util.List; +import com.gmail.nossr50.util.Permissions; import org.bukkit.inventory.ItemStack; import com.gmail.nossr50.config.experience.ExperienceConfig; import com.gmail.nossr50.config.skills.alchemy.PotionConfig; import com.gmail.nossr50.datatypes.player.McMMOPlayer; -import com.gmail.nossr50.datatypes.skills.SecondaryAbility; import com.gmail.nossr50.datatypes.skills.SkillType; import com.gmail.nossr50.skills.SkillManager; -import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.StringUtils; public class AlchemyManager extends SkillManager { @@ -20,23 +19,6 @@ public class AlchemyManager extends SkillManager { super(mcMMOPlayer, SkillType.ALCHEMY); } - public boolean canCatalysis() { - return Permissions.secondaryAbilityEnabled(getPlayer(), SecondaryAbility.CATALYSIS); - } - - public boolean canConcoctions() { - return Permissions.secondaryAbilityEnabled(getPlayer(), SecondaryAbility.CONCOCTIONS); - } - - public boolean canUseIngredient(ItemStack item) { - for (ItemStack ingredient : getIngredients()) { - if (item.isSimilar(ingredient)) { - return true; - } - } - return false; - } - public int getTier() { for (Alchemy.Tier tier : Alchemy.Tier.values()) { if (getSkillLevel() >= tier.getLevel()) { @@ -48,31 +30,17 @@ public class AlchemyManager extends SkillManager { } public List getIngredients() { - switch (Alchemy.Tier.fromNumerical(getTier())) { - case EIGHT: - return PotionConfig.getInstance().concoctionsIngredientsTierEight; - case SEVEN: - return PotionConfig.getInstance().concoctionsIngredientsTierSeven; - case SIX: - return PotionConfig.getInstance().concoctionsIngredientsTierSix; - case FIVE: - return PotionConfig.getInstance().concoctionsIngredientsTierFive; - case FOUR: - return PotionConfig.getInstance().concoctionsIngredientsTierFour; - case THREE: - return PotionConfig.getInstance().concoctionsIngredientsTierThree; - case TWO: - return PotionConfig.getInstance().concoctionsIngredientsTierTwo; - default: - return PotionConfig.getInstance().concoctionsIngredientsTierOne; - } + return PotionConfig.getInstance().getIngredients(getTier()); } public String getIngredientList() { StringBuilder list = new StringBuilder(); for (ItemStack ingredient : getIngredients()) { - String string = StringUtils.getPrettyItemString(ingredient.getType()) + (ingredient.getDurability() != 0 ? ":" + ingredient.getDurability() : ""); + short durability = ingredient.getDurability(); + + String string = StringUtils.getPrettyItemString(ingredient.getType()) + (durability != 0 ? ":" + durability : ""); + if (string.equals("Long Grass:2")) { string = "Fern"; } @@ -80,17 +48,20 @@ public class AlchemyManager extends SkillManager { string = "Pufferfish"; } - list.append(", " + string); + list.append(", ").append(string); } + return list.substring(2); } - public double getBrewSpeed() { - return Alchemy.calculateBrewSpeed(getSkillLevel()); - } + public double calculateBrewSpeed(boolean isLucky) { + int skillLevel = getSkillLevel(); - public double getBrewSpeedLucky() { - return LUCKY_MODIFIER * Alchemy.calculateBrewSpeed(getSkillLevel()); + if (skillLevel < Alchemy.catalysisUnlockLevel) { + return Alchemy.catalysisMinSpeed; + } + + return Math.min(Alchemy.catalysisMaxSpeed, Alchemy.catalysisMinSpeed + (Alchemy.catalysisMaxSpeed - Alchemy.catalysisMinSpeed) * (skillLevel - Alchemy.catalysisUnlockLevel) / (Alchemy.catalysisMaxBonusLevel - Alchemy.catalysisUnlockLevel)) * (isLucky ? LUCKY_MODIFIER : 1.0); } public void handlePotionBrewSuccesses(int amount) { diff --git a/src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyPotionBrewer.java b/src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyPotionBrewer.java index d41ac41d1..e79384296 100644 --- a/src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyPotionBrewer.java +++ b/src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyPotionBrewer.java @@ -8,10 +8,6 @@ import org.bukkit.block.BrewingStand; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryDragEvent; -import org.bukkit.event.inventory.InventoryMoveItemEvent; -import org.bukkit.event.inventory.InventoryType.SlotType; import org.bukkit.inventory.BrewerInventory; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryView; @@ -27,60 +23,54 @@ import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.player.UserManager; public final class AlchemyPotionBrewer { - private final static int[] BOTTLE_SLOTS = new int[]{0, 1, 2}; - private final static int INGREDIENT_SLOT = 3; - public static boolean isValidBrew(Player player, ItemStack[] contents) { - if (!isValidIngredient(player, contents[INGREDIENT_SLOT])) { + if (!isValidIngredient(player, contents[Alchemy.INGREDIENT_SLOT])) { return false; } - for (int bottle : BOTTLE_SLOTS) { - if (contents[bottle] != null && contents[bottle].getType() == Material.POTION) { - AlchemyPotion potion = PotionConfig.getInstance().potionMap.get(contents[bottle].getDurability()); + for (int i = 0; i < 3; i++) { + if (contents[i] == null || contents[i].getType() != Material.POTION) { + continue; + } - if (getChildPotion(potion, contents[INGREDIENT_SLOT]) != null) { - return true; - } + if (getChildPotion(PotionConfig.getInstance().getPotion(contents[i].getDurability()), contents[Alchemy.INGREDIENT_SLOT]) != null) { + return true; } } return false; - } private static AlchemyPotion getChildPotion(AlchemyPotion potion, ItemStack ingredient) { if (potion != null && potion.getChildDataValue(ingredient) != -1) { - return PotionConfig.getInstance().potionMap.get(potion.getChildDataValue(ingredient)); + return PotionConfig.getInstance().getPotion(potion.getChildDataValue(ingredient)); } return null; } - private static boolean isEmpty(ItemStack item) { + public static boolean isEmpty(ItemStack item) { return item == null || item.getType() == Material.AIR || item.getAmount() == 0; } private static boolean removeIngredient(BrewerInventory inventory, Player player) { - ItemStack ingredient = inventory.getIngredient(); + ItemStack ingredient = inventory.getIngredient().clone(); if (isEmpty(ingredient) || !isValidIngredient(player, ingredient)) { return false; } else if (ingredient.getAmount() <= 1) { - inventory.setItem(INGREDIENT_SLOT, null); - + inventory.setIngredient(null); return true; } else { ingredient.setAmount(ingredient.getAmount() - 1); - inventory.setItem(INGREDIENT_SLOT, ingredient); - + inventory.setIngredient(ingredient); return true; } } - private static boolean isValidIngredient(Player player, ItemStack item) { + public static boolean isValidIngredient(Player player, ItemStack item) { if (isEmpty(item)) { return false; } @@ -95,28 +85,7 @@ public final class AlchemyPotionBrewer { } private static List getValidIngredients(Player player) { - if (player == null || !Permissions.secondaryAbilityEnabled(player, SecondaryAbility.CONCOCTIONS)) { - return PotionConfig.getInstance().concoctionsIngredientsTierOne; - } - - switch (UserManager.getPlayer(player).getAlchemyManager().getTier()) { - case 8: - return PotionConfig.getInstance().concoctionsIngredientsTierEight; - case 7: - return PotionConfig.getInstance().concoctionsIngredientsTierSeven; - case 6: - return PotionConfig.getInstance().concoctionsIngredientsTierSix; - case 5: - return PotionConfig.getInstance().concoctionsIngredientsTierFive; - case 4: - return PotionConfig.getInstance().concoctionsIngredientsTierFour; - case 3: - return PotionConfig.getInstance().concoctionsIngredientsTierThree; - case 2: - return PotionConfig.getInstance().concoctionsIngredientsTierTwo; - default: - return PotionConfig.getInstance().concoctionsIngredientsTierOne; - } + return PotionConfig.getInstance().getIngredients((player == null || !Permissions.secondaryAbilityEnabled(player, SecondaryAbility.CONCOCTIONS)) ? 1 : UserManager.getPlayer(player).getAlchemyManager().getTier()); } public static void finishBrewing(BlockState brewingStand, Player player, boolean forced) { @@ -131,13 +100,15 @@ public final class AlchemyPotionBrewer { return; } - for (int bottle : BOTTLE_SLOTS) { - if (!isEmpty(inventory.getItem(bottle)) && PotionConfig.getInstance().potionMap.containsKey(inventory.getItem(bottle).getDurability())) { - AlchemyPotion input = PotionConfig.getInstance().potionMap.get(inventory.getItem(bottle).getDurability()); - AlchemyPotion output = PotionConfig.getInstance().potionMap.get(input.getChildDataValue(ingredient)); + for (int i = 0; i < 3; i++) { + ItemStack item = inventory.getItem(i); + + if (!isEmpty(item) && PotionConfig.getInstance().isValidPotion(item)) { + AlchemyPotion input = PotionConfig.getInstance().getPotion(item.getDurability()); + AlchemyPotion output = PotionConfig.getInstance().getPotion(input.getChildDataValue(ingredient)); if (output != null) { - inventory.setItem(bottle, output.toItemStack(inventory.getItem(bottle).getAmount()).clone()); + inventory.setItem(i, output.toItemStack(item.getAmount()).clone()); if (player != null) { UserManager.getPlayer(player).getAlchemyManager().handlePotionBrewSuccesses(1); @@ -151,18 +122,36 @@ public final class AlchemyPotionBrewer { } } + public static boolean transferItems(InventoryView view, int fromSlot, int toSlot, ClickType click) { + boolean success = false; + + if (click.isLeftClick()) { + success = transferOneItem(view, fromSlot, toSlot); + } + else if (click.isRightClick()) { + success = transferItems(view, fromSlot, toSlot); + } + + return success; + } + private static boolean transferOneItem(InventoryView view, int fromSlot, int toSlot) { ItemStack from = view.getItem(fromSlot).clone(); ItemStack to = view.getItem(toSlot).clone(); + boolean emptyFrom = isEmpty(from); - if (isEmpty(from)) { + if (emptyFrom) { return false; } - else if (!isEmpty(to) && from.getAmount() >= from.getType().getMaxStackSize()) { + + boolean emptyTo = isEmpty(to); + int fromAmount = from.getAmount(); + + if (!emptyTo && fromAmount >= from.getType().getMaxStackSize()) { return false; } - else if (isEmpty(to) || from.isSimilar(to)) { - if (isEmpty(to)) { + else if (emptyTo || from.isSimilar(to)) { + if (emptyTo) { to = from.clone(); to.setAmount(1); } @@ -170,9 +159,9 @@ public final class AlchemyPotionBrewer { to.setAmount(to.getAmount() + 1); } - from.setAmount(from.getAmount() - 1); - view.setItem(toSlot, isEmpty(to) ? null : to); - view.setItem(fromSlot, isEmpty(from) ? null : from); + from.setAmount(fromAmount - 1); + view.setItem(toSlot, emptyTo ? null : to); + view.setItem(fromSlot, emptyFrom ? null : from); return true; } @@ -184,171 +173,50 @@ public final class AlchemyPotionBrewer { * Transfer items between two ItemStacks, returning the leftover status */ private static boolean transferItems(InventoryView view, int fromSlot, int toSlot) { - if (isEmpty(view.getItem(fromSlot))) { + ItemStack from = view.getItem(fromSlot).clone(); + ItemStack to = view.getItem(toSlot).clone(); + + if (isEmpty(from)) { return false; } - else if (isEmpty(view.getItem(toSlot))) { - view.setItem(toSlot, view.getItem(fromSlot).clone()); + else if (isEmpty(to)) { + view.setItem(toSlot, from); view.setItem(fromSlot, null); return true; } - else if (view.getItem(fromSlot).isSimilar(view.getItem(toSlot))) { - if (view.getItem(fromSlot).getAmount() + view.getItem(toSlot).getAmount() > view.getItem(toSlot).getType().getMaxStackSize()) { - int left = view.getItem(fromSlot).getAmount() + view.getItem(toSlot).getAmount() - view.getItem(toSlot).getType().getMaxStackSize(); + else if (from.isSimilar(to)) { + int fromAmount = from.getAmount(); + int toAmount = to.getAmount(); + int maxSize = to.getType().getMaxStackSize(); - ItemStack to = new ItemStack(view.getItem(toSlot)); - to.setAmount(to.getType().getMaxStackSize()); + if (fromAmount + toAmount > maxSize) { + int left = fromAmount + toAmount - maxSize; + + to.setAmount(maxSize); view.setItem(toSlot, to); - ItemStack from = new ItemStack(view.getItem(fromSlot)); from.setAmount(left); view.setItem(fromSlot, from); return true; } - ItemStack to = new ItemStack(view.getItem(toSlot)); - to.setAmount(view.getItem(fromSlot).getAmount() + view.getItem(toSlot).getAmount()); + to.setAmount(fromAmount + toAmount); view.setItem(fromSlot, null); view.setItem(toSlot, to); return true; } + return false; } - public static void handleInventoryClick(InventoryClickEvent event) { - Player player = event.getWhoClicked() instanceof Player ? (Player) event.getWhoClicked() : null; - BrewingStand brewingStand = (BrewingStand) event.getInventory().getHolder(); - - ItemStack cursor = event.getCursor(); - ItemStack clicked = event.getCurrentItem(); - - if (clicked != null && clicked.getType() == Material.POTION) { - scheduleCheck(player, brewingStand); - - return; - } - - if (event.isShiftClick()) { - if (event.getSlotType() == SlotType.FUEL) { - scheduleCheck(player, brewingStand); - - return; - } - else if (event.getSlotType() == SlotType.CONTAINER || event.getSlotType() == SlotType.QUICKBAR) { - if (isValidIngredient(player, clicked)) { - if (event.isLeftClick()) { - transferItems(event.getView(), event.getRawSlot(), INGREDIENT_SLOT); - } - else if (event.isRightClick()) { - transferOneItem(event.getView(), event.getRawSlot(), INGREDIENT_SLOT); - } - - event.setCancelled(true); - - scheduleUpdate(brewingStand.getInventory()); - scheduleCheck(player, brewingStand); - - return; - } - } - } - else if (event.getRawSlot() == INGREDIENT_SLOT) { - if (isEmpty(cursor) && isEmpty(clicked)) { - if (event.getClick() == ClickType.NUMBER_KEY) { - scheduleCheck(player, brewingStand); - return; - } - return; - } - else if (isEmpty(cursor)) { - scheduleCheck(player, brewingStand); - - return; - } - else if (isEmpty(clicked)) { - if (isValidIngredient(player, event.getCursor())) { - if (event.getClick() == ClickType.LEFT || (event.getClick() == ClickType.RIGHT && event.getCursor().getAmount() == 1)) { - event.setCancelled(true); - - event.setCurrentItem(event.getCursor().clone()); - event.setCursor(null); - - scheduleUpdate(brewingStand.getInventory()); - scheduleCheck(player, brewingStand); - - return; - } - else if (event.getClick() == ClickType.RIGHT) { - event.setCancelled(true); - - ItemStack one = event.getCursor().clone(); - one.setAmount(1); - - ItemStack rest = event.getCursor().clone(); - rest.setAmount(event.getCursor().getAmount() - 1); - - event.setCurrentItem(one); - event.setCursor(rest); - - scheduleUpdate(brewingStand.getInventory()); - scheduleCheck(player, brewingStand); - - return; - } - } - return; - } - } - } - - public static void handleInventoryDrag(InventoryDragEvent event) { - Player player = event.getWhoClicked() instanceof Player ? (Player) event.getWhoClicked() : null; - BrewingStand brewingStand = (BrewingStand) event.getInventory().getHolder(); - - ItemStack cursor = event.getCursor(); - ItemStack ingredient = brewingStand.getInventory().getIngredient(); - - if (!event.getInventorySlots().contains(INGREDIENT_SLOT)) { - return; - } - - if (isEmpty(ingredient) || ingredient.isSimilar(cursor)) { - if (isValidIngredient(player, cursor)) { - // Not handled: dragging custom ingredients over ingredient slot (does not trigger any event) - scheduleCheck(player, brewingStand); - - return; - } - else { - event.setCancelled(true); - - scheduleUpdate(brewingStand.getInventory()); - - return; - } - } - - } - - public static void handleInventoryMoveItem(InventoryMoveItemEvent event) { - Player player = null; - BrewingStand brewingStand = (BrewingStand) event.getDestination().getHolder(); - - if (isValidIngredient(player, event.getItem())) { - scheduleCheck(player, brewingStand); - - return; - } - } - - private static void scheduleCheck(Player player, BrewingStand brewingStand) { + public static void scheduleCheck(Player player, BrewingStand brewingStand) { new AlchemyBrewCheckTask(player, brewingStand).runTask(mcMMO.p); } - private static void scheduleUpdate(Inventory inventory) { + public static void scheduleUpdate(Inventory inventory) { for (HumanEntity humanEntity : inventory.getViewers()) { if (humanEntity instanceof Player) { new PlayerUpdateInventoryTask((Player) humanEntity).runTask(mcMMO.p);