diff --git a/api/src/main/java/me/pikamug/quests/player/Quester.java b/api/src/main/java/me/pikamug/quests/player/Quester.java index d0a313d2c..905b500bf 100644 --- a/api/src/main/java/me/pikamug/quests/player/Quester.java +++ b/api/src/main/java/me/pikamug/quests/player/Quester.java @@ -15,6 +15,7 @@ import me.pikamug.quests.quests.components.Stage; import me.pikamug.quests.quests.components.Objective; import me.pikamug.quests.enums.ObjectiveType; import me.pikamug.quests.module.CustomObjective; +import me.pikamug.quests.util.stack.BlockItemStack; import org.bukkit.DyeColor; import org.bukkit.Location; import org.bukkit.OfflinePlayer; @@ -145,16 +146,31 @@ public interface Quester extends Comparable { void showCurrentConditions(final Quest quest, final Quester quester); + @Deprecated void breakBlock(final Quest quest, final ItemStack itemStack); + void breakBlock(final Quest quest, final BlockItemStack blockItemStack); + + @Deprecated void damageBlock(final Quest quest, final ItemStack itemStack); + void damageBlock(final Quest quest, final BlockItemStack blockItemStack); + + @Deprecated void placeBlock(final Quest quest, final ItemStack itemStack); + void placeBlock(final Quest quest, final BlockItemStack blockItemStack); + + @Deprecated void useBlock(final Quest quest, final ItemStack itemStack); + void useBlock(final Quest quest, final BlockItemStack blockItemStack); + + @Deprecated void cutBlock(final Quest quest, final ItemStack itemStack); + void cutBlock(final Quest quest, final BlockItemStack blockItemStack); + void craftItem(final Quest quest, final ItemStack itemStack); void smeltItem(final Quest quest, final ItemStack itemStack); diff --git a/api/src/main/java/me/pikamug/quests/util/stack/BlockItemStack.java b/api/src/main/java/me/pikamug/quests/util/stack/BlockItemStack.java new file mode 100644 index 000000000..19f432579 --- /dev/null +++ b/api/src/main/java/me/pikamug/quests/util/stack/BlockItemStack.java @@ -0,0 +1,39 @@ +package me.pikamug.quests.util.stack; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.inventory.ItemStack; + +public interface BlockItemStack { + + static BlockItemStack of(final ItemStack original) { + if (original == null) { + return null; + } + + return of(original.getType(), original.getAmount(), original.getDurability()); + } + + static BlockItemStack of(final Block block) { + return BlockItemStacks.getFactory().of(block); + } + + static BlockItemStack of(final Material type, final int amount, final short durability) { + return BlockItemStacks.getFactory().of(type, amount, durability); + } + + static BlockItemStack clone(final BlockItemStack original, final int amount) { + return BlockItemStacks.getFactory().clone(original, amount); + } + + static BlockItemStack clone(final BlockItemStack original, final int amount, final short durability) { + return BlockItemStacks.getFactory().clone(original, amount, durability); + } + + Material getType(); + int getAmount(); + short getDurability(); + + boolean matches(BlockItemStack other); + +} diff --git a/api/src/main/java/me/pikamug/quests/util/stack/BlockItemStackFactory.java b/api/src/main/java/me/pikamug/quests/util/stack/BlockItemStackFactory.java new file mode 100644 index 000000000..8d68ddbc6 --- /dev/null +++ b/api/src/main/java/me/pikamug/quests/util/stack/BlockItemStackFactory.java @@ -0,0 +1,12 @@ +package me.pikamug.quests.util.stack; + +import org.bukkit.Material; +import org.bukkit.block.Block; + +public interface BlockItemStackFactory { + + BlockItemStack of(final Block block); + BlockItemStack of(final Material type, final int amount, final short durability); + BlockItemStack clone(final BlockItemStack original, final int amount); + BlockItemStack clone(final BlockItemStack original, final int amount, final short durability); +} diff --git a/api/src/main/java/me/pikamug/quests/util/stack/BlockItemStacks.java b/api/src/main/java/me/pikamug/quests/util/stack/BlockItemStacks.java new file mode 100644 index 000000000..3e20e8c7c --- /dev/null +++ b/api/src/main/java/me/pikamug/quests/util/stack/BlockItemStacks.java @@ -0,0 +1,32 @@ +package me.pikamug.quests.util.stack; + +import me.pikamug.quests.util.stack.impl.LegacyBlockItemStack; +import me.pikamug.quests.util.stack.impl.ModernBlockItemStack; + +public final class BlockItemStacks { + + private BlockItemStacks() { + } + + private static BlockItemStackFactory factory; + + public static BlockItemStackFactory getFactory() { + return factory; + } + + private static void setFactory(final BlockItemStackFactory factory) { + if (BlockItemStacks.factory != null) { + throw new IllegalStateException("Factory is already set"); + } + + BlockItemStacks.factory = factory; + } + + public static void init(final boolean modern) { + if (modern) { + setFactory(ModernBlockItemStack.FACTORY); + } else { + setFactory(LegacyBlockItemStack.FACTORY); + } + } +} diff --git a/api/src/main/java/me/pikamug/quests/util/stack/impl/LegacyBlockItemStack.java b/api/src/main/java/me/pikamug/quests/util/stack/impl/LegacyBlockItemStack.java new file mode 100644 index 000000000..2b48fb7fd --- /dev/null +++ b/api/src/main/java/me/pikamug/quests/util/stack/impl/LegacyBlockItemStack.java @@ -0,0 +1,90 @@ +package me.pikamug.quests.util.stack.impl; + +import me.pikamug.quests.util.stack.BlockItemStack; +import me.pikamug.quests.util.stack.BlockItemStackFactory; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.material.MaterialData; + +@SuppressWarnings("deprecation") +public class LegacyBlockItemStack implements BlockItemStack { + + public static final BlockItemStackFactory FACTORY = new Factory(); + + private final MaterialData materialData; + private int amount; + + private LegacyBlockItemStack(final MaterialData materialData, final int amount) { + this.materialData = materialData; + this.amount = amount; + } + + public MaterialData getMaterialData() { + return materialData; + } + + @Override + public int getAmount() { + return amount; + } + + @Override + public short getDurability() { + return materialData.getData(); + } + + @Override + public Material getType() { + return materialData.getItemType(); + } + + @Override + public boolean matches(BlockItemStack other) { + if (other == null) { + return false; + } + + final MaterialData blockData = Factory.getBlockData(other); + return this.materialData.equals(blockData) && (getDurability() == 0 || getDurability() == other.getDurability()); + } + + public void setAmount(int amount) { + this.amount = amount; + } + + public static class Factory implements BlockItemStackFactory { + + @Override + public BlockItemStack of(final Block block) { + final MaterialData data = block.getState().getData(); + return new LegacyBlockItemStack(data, 1); + } + + @Override + public BlockItemStack of(final Material type, final int amount, final short durability) { + final MaterialData data = type.getNewData((byte) durability); + return new LegacyBlockItemStack(data, amount); + } + + @Override + public BlockItemStack clone(final BlockItemStack original, final int amount) { + final MaterialData data = getBlockData(original); + return new LegacyBlockItemStack(data, amount); + } + + @Override + public BlockItemStack clone(final BlockItemStack original, final int amount, final short durability) { + final MaterialData data = getBlockData(original); + data.setData((byte) durability); + return new LegacyBlockItemStack(data, amount); + } + + private static MaterialData getBlockData(final BlockItemStack stack) { + if (stack instanceof LegacyBlockItemStack) { + return ((LegacyBlockItemStack)stack).materialData; + } + + return stack.getType().getNewData((byte) stack.getDurability()); + } + } +} diff --git a/api/src/main/java/me/pikamug/quests/util/stack/impl/ModernBlockItemStack.java b/api/src/main/java/me/pikamug/quests/util/stack/impl/ModernBlockItemStack.java new file mode 100644 index 000000000..ee691777a --- /dev/null +++ b/api/src/main/java/me/pikamug/quests/util/stack/impl/ModernBlockItemStack.java @@ -0,0 +1,103 @@ +package me.pikamug.quests.util.stack.impl; + +import me.pikamug.quests.util.stack.BlockItemStack; +import me.pikamug.quests.util.stack.BlockItemStackFactory; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.Ageable; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Powerable; + +public class ModernBlockItemStack implements BlockItemStack { + + public static final BlockItemStackFactory FACTORY = new Factory(); + + private final BlockData blockData; + private int amount; + private final short durability; + + private ModernBlockItemStack(final BlockData blockData, final int amount, final short durability) { + this.blockData = blockData; + this.amount = amount; + this.durability = durability; + } + + + private static short getDurability(BlockData data) { + if (data instanceof Ageable) { + return (short) ((Ageable)data).getAge(); + } + + if (data instanceof Powerable) { + return (short) (((Powerable)data).isPowered() ? 1 : 0); + } + + return 0; + } + + public BlockData getBlockData() { + return blockData; + } + + @Override + public int getAmount() { + return amount; + } + + @Override + public short getDurability() { + return durability; + } + + @Override + public Material getType() { + return blockData.getMaterial(); + } + + @Override + public boolean matches(BlockItemStack other) { + if (other == null) { + return false; + } + + final BlockData blockData = Factory.getBlockData(other); + return this.blockData.matches(blockData) && (durability == 0 || durability == other.getDurability()); + } + + public void setAmount(int amount) { + this.amount = amount; + } + + public static class Factory implements BlockItemStackFactory { + + @Override + public BlockItemStack of(final Block block) { + return new ModernBlockItemStack(block.getBlockData(), 1, getDurability(block.getBlockData())); + } + + @Override + public BlockItemStack of(final Material type, final int amount, final short durability) { + return new ModernBlockItemStack(type.createBlockData(), amount, durability); + } + + @Override + public BlockItemStack clone(final BlockItemStack original, final int amount) { + final BlockData data = getBlockData(original); + return new ModernBlockItemStack(data, amount, original.getDurability()); + } + + @Override + public BlockItemStack clone(final BlockItemStack original, final int amount, final short durability) { + final BlockData data = getBlockData(original); + return new ModernBlockItemStack(data, amount, durability); + } + + private static BlockData getBlockData(final BlockItemStack stack) { + if (stack instanceof ModernBlockItemStack) { + return ((ModernBlockItemStack)stack).getBlockData(); + } + + return stack.getType().createBlockData(); + } + } +} diff --git a/core/src/main/java/me/pikamug/quests/BukkitQuestsPlugin.java b/core/src/main/java/me/pikamug/quests/BukkitQuestsPlugin.java index b14bc4662..8cf612dc3 100644 --- a/core/src/main/java/me/pikamug/quests/BukkitQuestsPlugin.java +++ b/core/src/main/java/me/pikamug/quests/BukkitQuestsPlugin.java @@ -53,6 +53,7 @@ import me.pikamug.quests.tasks.BukkitNpcEffectThread; import me.pikamug.quests.tasks.BukkitPlayerMoveThread; import me.pikamug.quests.util.BukkitLang; import me.pikamug.quests.util.BukkitUpdateChecker; +import me.pikamug.quests.util.stack.BlockItemStacks; import org.apache.logging.log4j.LogManager; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -143,9 +144,11 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { try { Class.forName("me.pikamug.quests.libs.localelib.LocaleManager"); localeManager = new LocaleManager(); + BlockItemStacks.init(!localeManager.isBelow113()); } catch (final Exception ignored) { getLogger().warning("LocaleLib not present! Is this a debug environment?"); } + convoListener = new BukkitConvoListener(); blockListener = new BukkitBlockListener(this); itemListener = new BukkitItemListener(this); diff --git a/core/src/main/java/me/pikamug/quests/listeners/BukkitBlockListener.java b/core/src/main/java/me/pikamug/quests/listeners/BukkitBlockListener.java index 4eb40f6bd..63037bf3b 100644 --- a/core/src/main/java/me/pikamug/quests/listeners/BukkitBlockListener.java +++ b/core/src/main/java/me/pikamug/quests/listeners/BukkitBlockListener.java @@ -22,7 +22,7 @@ import me.pikamug.quests.player.Quester; import me.pikamug.quests.quests.Quest; import me.pikamug.quests.quests.components.BukkitObjective; import me.pikamug.quests.quests.components.BukkitStage; -import me.pikamug.quests.util.BukkitItemUtil; +import me.pikamug.quests.util.stack.BlockItemStack; import me.pikamug.quests.util.BukkitLang; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -61,10 +61,8 @@ public class BukkitBlockListener implements Listener { } final Player player = event.getPlayer(); if (plugin.canUseQuests(player.getUniqueId())) { - final ItemStack blockItemStack = getItemEquivalent(event.getBlock()); - if (blockItemStack == null) { - return; - } + final BlockItemStack blockItem = BlockItemStack.of(event.getBlock()); + final BukkitQuester quester = plugin.getQuester(player.getUniqueId()); final ObjectiveType breakType = ObjectiveType.BREAK_BLOCK; final ObjectiveType placeType = ObjectiveType.PLACE_BLOCK; @@ -89,12 +87,12 @@ public class BukkitBlockListener implements Listener { BukkitActionBarProvider.sendActionBar(player, ChatColor.RED + BukkitLang .get(player, "optionSilkTouchFail").replace("", quest.getName())); } else { - quester.breakBlock(quest, blockItemStack); + quester.breakBlock(quest, blockItem); dispatchedBreakQuestIDs.addAll(quester.dispatchMultiplayerEverything(quest, breakType, (final Quester q, final Quest cq) -> { if (!dispatchedBreakQuestIDs.contains(cq.getId())) { - q.breakBlock(cq, blockItemStack); + q.breakBlock(cq, blockItem); } return null; })); @@ -109,11 +107,11 @@ public class BukkitBlockListener implements Listener { if (progress < 0) { break; } - final ItemStack is = currentStage.getBlocksToPlace().get(i); + final BlockItemStack is = currentStage.getBlocksToPlace().get(i); if (event.getBlock().getType().equals(is.getType()) && is.getAmount() > 0) { - ItemStack goal = new ItemStack(is.getType(), 64); - for (final ItemStack stack : currentStage.getBlocksToPlace()) { - if (BukkitItemUtil.compareItems(is, stack, true) == 0) { + BlockItemStack goal = BlockItemStack.clone(is, 64); + for (final BlockItemStack stack : currentStage.getBlocksToPlace()) { + if (stack.matches(goal)) { goal = stack; } } @@ -142,11 +140,11 @@ public class BukkitBlockListener implements Listener { if (progress < 0) { break; } - final ItemStack is = currentStage.getBlocksToPlace().get(i); + final BlockItemStack is = currentStage.getBlocksToPlace().get(i); if (event.getBlock().getType().equals(is.getType()) && is.getAmount() > 0) { - ItemStack goal = new ItemStack(is.getType(), 64); - for (final ItemStack stack : ((BukkitStage) quester.getCurrentStage(cq)).getBlocksToPlace()) { - if (BukkitItemUtil.compareItems(is, stack, true) == 0) { + BlockItemStack goal = BlockItemStack.clone(is, 64); + for (final BlockItemStack stack : ((BukkitStage) quester.getCurrentStage(cq)).getBlocksToPlace()) { + if (stack.matches(goal)) { goal = stack; } } @@ -170,14 +168,14 @@ public class BukkitBlockListener implements Listener { } if (currentStage.containsObjective(cutType)) { if (player.getItemInHand().getType().equals(Material.SHEARS)) { - quester.cutBlock(quest, blockItemStack); + quester.cutBlock(quest, blockItem); } } dispatchedCutQuestIDs.addAll(quester.dispatchMultiplayerEverything(quest, cutType, (final Quester q, final Quest cq) -> { if (!dispatchedCutQuestIDs.contains(cq.getId())) { if (player.getItemInHand().getType().equals(Material.SHEARS)) { - q.cutBlock(cq, blockItemStack); + q.cutBlock(cq, blockItem); } } return null; @@ -195,10 +193,8 @@ public class BukkitBlockListener implements Listener { } final Player player = event.getPlayer(); if (plugin.canUseQuests(player.getUniqueId())) { - final ItemStack blockItemStack = getItemEquivalent(event.getBlock()); - if (blockItemStack == null) { - return; - } + final BlockItemStack blockItemStack = BlockItemStack.of(event.getBlock()); + final Quester quester = plugin.getQuester(player.getUniqueId()); final ObjectiveType type = ObjectiveType.DAMAGE_BLOCK; final Set dispatchedQuestIDs = new HashSet<>(); @@ -231,10 +227,8 @@ public class BukkitBlockListener implements Listener { } final Player player = event.getPlayer(); if (plugin.canUseQuests(player.getUniqueId())) { - final ItemStack blockItemStack = getItemEquivalent(event.getBlock()); - if (blockItemStack == null) { - return; - } + final BlockItemStack blockItemStack = BlockItemStack.of(event.getBlock()); + final BukkitQuester quester = plugin.getQuester(player.getUniqueId()); final ObjectiveType placeType = ObjectiveType.PLACE_BLOCK; final ObjectiveType breakType = ObjectiveType.BREAK_BLOCK; @@ -261,11 +255,11 @@ public class BukkitBlockListener implements Listener { if (progress < 0) { break; } - final ItemStack is = currentStage.getBlocksToBreak().get(i); + final BlockItemStack is = currentStage.getBlocksToBreak().get(i); if (event.getBlock().getType().equals(is.getType()) && is.getAmount() > 0) { - ItemStack goal = new ItemStack(is.getType(), 64); - for (final ItemStack stack : currentStage.getBlocksToBreak()) { - if (BukkitItemUtil.compareItems(is, stack, true) == 0) { + BlockItemStack goal = BlockItemStack.clone(is, 64); + for (final BlockItemStack stack : currentStage.getBlocksToBreak()) { + if (stack.matches(goal)) { goal = stack; } } @@ -294,11 +288,11 @@ public class BukkitBlockListener implements Listener { if (progress < 0) { break; } - final ItemStack is = currentStage.getBlocksToBreak().get(i); + final BlockItemStack is = currentStage.getBlocksToBreak().get(i); if (event.getBlock().getType().equals(is.getType()) && is.getAmount() > 0) { - ItemStack goal = new ItemStack(is.getType(), 64); - for (final ItemStack stack : ((BukkitStage) quester.getCurrentStage(cq)).getBlocksToBreak()) { - if (BukkitItemUtil.compareItems(is, stack, true) == 0) { + BlockItemStack goal = BlockItemStack.clone(is, 64); + for (final BlockItemStack stack : ((BukkitStage) quester.getCurrentStage(cq)).getBlocksToBreak()) { + if (stack.matches(goal)) { goal = stack; } } @@ -354,10 +348,8 @@ public class BukkitBlockListener implements Listener { } if (event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) { if (!event.isCancelled() && event.getClickedBlock() != null) { - final ItemStack blockItemStack = getItemEquivalent(event.getClickedBlock()); - if (blockItemStack == null) { - return; - } + final BlockItemStack blockItemStack = BlockItemStack.of(event.getClickedBlock()); + final ObjectiveType type = ObjectiveType.USE_BLOCK; final Set dispatchedQuestIDs = new HashSet<>(); for (final Quest quest : plugin.getLoadedQuests()) { diff --git a/core/src/main/java/me/pikamug/quests/player/BukkitQuester.java b/core/src/main/java/me/pikamug/quests/player/BukkitQuester.java index 67f146453..f89c3d007 100644 --- a/core/src/main/java/me/pikamug/quests/player/BukkitQuester.java +++ b/core/src/main/java/me/pikamug/quests/player/BukkitQuester.java @@ -2,9 +2,9 @@ * Copyright (c) PikaMug and contributors * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT - * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ @@ -14,7 +14,6 @@ import com.alessiodp.parties.api.interfaces.Party; import com.alessiodp.parties.api.interfaces.PartyPlayer; import com.gmail.nossr50.datatypes.skills.SkillType; import com.gmail.nossr50.util.player.UserManager; -import de.tr7zw.changeme.nbtapi.NBT; import io.github.znetworkw.znpcservers.npc.NPC; import lol.pyr.znpcsplus.api.npc.Npc; import me.clip.placeholderapi.PlaceholderAPI; @@ -48,6 +47,7 @@ import me.pikamug.quests.quests.components.Objective; import me.pikamug.quests.quests.components.Planner; import me.pikamug.quests.quests.components.Stage; import me.pikamug.quests.tasks.BukkitStageTimer; +import me.pikamug.quests.util.stack.BlockItemStack; import me.pikamug.quests.util.BukkitConfigUtil; import me.pikamug.quests.util.BukkitInventoryUtil; import me.pikamug.quests.util.BukkitItemUtil; @@ -75,7 +75,6 @@ import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.EnchantmentStorageMeta; -import org.bukkit.material.Crops; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -148,7 +147,7 @@ public class BukkitQuester implements Quester { updateJournal(); return b; } - + @Override public boolean addAll(final @NotNull Collection c) { final boolean b = super.addAll(c); @@ -168,7 +167,7 @@ public class BukkitQuester implements Quester { updateJournal(); return b; } - + @Override public boolean removeAll(final Collection c) { final boolean b = super.removeAll(c); @@ -237,7 +236,7 @@ public class BukkitQuester implements Quester { updateJournal(); } }; - + public BukkitQuester(final BukkitQuestsPlugin plugin, final UUID uuid) { this.plugin = plugin; this.id = uuid; @@ -731,10 +730,10 @@ public class BukkitQuester implements Quester { } return true; } - + /** * Start a quest for this Quester - * + * * @param quest The quest to start * @param ignoreRequirements Whether to ignore Requirements */ @@ -884,10 +883,10 @@ public class BukkitQuester implements Quester { } return false; } - + /** * End a quest for this Quester - * + * * @param quest The quest to start * @param message Message to inform player, can be left null or empty * @since 3.8.6 @@ -895,10 +894,10 @@ public class BukkitQuester implements Quester { public void quitQuest(final Quest quest, final String message) { quitQuest(quest, new String[] {message}); } - + /** * End a quest for this Quester - * + * * @param quest The quest to start * @param messages Messages to inform player, can be left null or empty * @since 3.8.6 @@ -1026,7 +1025,7 @@ public class BukkitQuester implements Quester { message = PlaceholderAPI.setPlaceholders(getPlayer(), message); } current.add(message); - + } return current; } @@ -1112,7 +1111,7 @@ public class BukkitQuester implements Quester { if (player.isOnline()) { final Inventory fakeInv = Bukkit.createInventory(null, InventoryType.PLAYER); fakeInv.setContents(getPlayer().getInventory().getContents().clone()); - + int num = 0; for (final ItemStack is : requirements.getItems()) { if (BukkitInventoryUtil.canRemoveItem(fakeInv, is)) { @@ -1126,14 +1125,14 @@ public class BukkitQuester implements Quester { } num = 0; } - + for (final String perm :requirements.getPermissions()) { if (getPlayer().hasPermission(perm)) { finishedRequirements.add(ChatColor.GREEN + BukkitLang.get("permissionDisplay") + " " + perm); } else { unfinishedRequirements.add(ChatColor.GRAY + BukkitLang.get("permissionDisplay") + " " + perm); } - + } for (final Entry> m : requirements.getCustomRequirements().entrySet()) { for (final CustomRequirement cr : plugin.getCustomRequirements()) { @@ -1159,16 +1158,16 @@ public class BukkitQuester implements Quester { } } } - } + } } current.addAll(unfinishedRequirements); current.addAll(finishedRequirements); return current; } - + /** * Get current objectives for a quest, both finished and unfinished - * + * * @param quest The quest to get objectives of * @param ignoreOverrides Whether to ignore objective-overrides * @param formatNames Whether to format item/entity names, if applicable @@ -1207,7 +1206,7 @@ public class BukkitQuester implements Quester { for (int i = 0; i < data.getBlocksBroken().size(); i++) { final int progress = data.getBlocksBroken().get(i); if (i >= stage.getBlocksToBreak().size()) { break; } - final ItemStack goal = stage.getBlocksToBreak().get(i); + final BlockItemStack goal = stage.getBlocksToBreak().get(i); final ChatColor color = progress < goal.getAmount() ? ChatColor.GREEN : ChatColor.GRAY; String message = formatCurrentObjectiveMessage(color, BukkitLang.get(getPlayer(), "break"), progress, goal.getAmount()); @@ -1219,7 +1218,7 @@ public class BukkitQuester implements Quester { for (int i = 0; i < data.getBlocksDamaged().size(); i++) { final int progress = data.getBlocksDamaged().get(i); if (i >= stage.getBlocksToDamage().size()) { break; } - final ItemStack goal = stage.getBlocksToDamage().get(i); + final BlockItemStack goal = stage.getBlocksToDamage().get(i); final ChatColor color = progress < goal.getAmount() ? ChatColor.GREEN : ChatColor.GRAY; String message = formatCurrentObjectiveMessage(color, BukkitLang.get(getPlayer(), "damage"), progress, goal.getAmount()); @@ -1231,7 +1230,7 @@ public class BukkitQuester implements Quester { for (int i = 0; i < data.getBlocksPlaced().size(); i++) { final int progress = data.getBlocksPlaced().get(i); if (i >= stage.getBlocksToPlace().size()) { break; } - final ItemStack goal = stage.getBlocksToPlace().get(i); + final BlockItemStack goal = stage.getBlocksToPlace().get(i); final ChatColor color = progress < goal.getAmount() ? ChatColor.GREEN : ChatColor.GRAY; String message = formatCurrentObjectiveMessage(color, BukkitLang.get(getPlayer(), "place"), progress, goal.getAmount()); @@ -1243,7 +1242,7 @@ public class BukkitQuester implements Quester { for (int i = 0; i < data.getBlocksUsed().size(); i++) { final int progress = data.getBlocksUsed().get(i); if (i >= stage.getBlocksToUse().size()) { break; } - final ItemStack goal = stage.getBlocksToUse().get(i); + final BlockItemStack goal = stage.getBlocksToUse().get(i); final ChatColor color = progress < goal.getAmount() ? ChatColor.GREEN : ChatColor.GRAY; String message = formatCurrentObjectiveMessage(color, BukkitLang.get(getPlayer(), "use"), progress, goal.getAmount()); @@ -1255,7 +1254,7 @@ public class BukkitQuester implements Quester { for (int i = 0; i < data.getBlocksCut().size(); i++) { final int progress = data.getBlocksCut().get(i); if (i >= stage.getBlocksToCut().size()) { break; } - final ItemStack goal = stage.getBlocksToCut().get(i); + final BlockItemStack goal = stage.getBlocksToCut().get(i); final ChatColor color = progress < goal.getAmount() ? ChatColor.GREEN : ChatColor.GRAY; String message = formatCurrentObjectiveMessage(color, BukkitLang.get(getPlayer(), "cut"), progress, goal.getAmount()); @@ -1601,7 +1600,16 @@ public class BukkitQuester implements Quester { final BukkitObjective objective = (BukkitObjective) obj; String message = "- " + BukkitLang.BukkitFormatToken.convertString(quester.getPlayer(), objective.getMessage()); - if (objective.getGoalAsItem() != null) { + if (objective.getGoalAsBlockItem() != null) { + final int progress = objective.getProgress(); + final BlockItemStack goal = objective.getGoalAsBlockItem(); + if (!settings.canShowCompletedObjs() && progress >= goal.getAmount()) { + continue; + } + if (localeManager != null && settings.canTranslateNames()) { + localeManager.sendMessage(quester.getPlayer(), message, goal.getType(), goal.getDurability(), null); + } + } else if (objective.getGoalAsItem() != null) { final int progress = objective.getProgress(); final ItemStack goal = objective.getGoalAsItem(); if (!settings.canShowCompletedObjs() && progress >= goal.getAmount()) { @@ -1795,20 +1803,32 @@ public class BukkitQuester implements Quester { } } } - + + @Override + public void breakBlock(Quest quest, ItemStack itemStack) { + breakBlock(quest, BlockItemStack.of(itemStack)); + } + /** * Marks block as broken if Quester has such an objective - * + * * @param quest The quest for which the block is being broken * @param broken The block being broken */ @SuppressWarnings("deprecation") - public void breakBlock(final Quest quest, final ItemStack broken) { - ItemStack goal = null; - for (final ItemStack toBreak : ((BukkitStage) getCurrentStage(quest)).getBlocksToBreak()) { + public void breakBlock(final Quest quest, final BlockItemStack broken) { + BlockItemStack goal = null; + for (final BlockItemStack toBreak : ((BukkitStage) getCurrentStage(quest)).getBlocksToBreak()) { if (goal != null) { break; } + + if (broken.matches(toBreak)) { + goal = toBreak; + } else { + continue; // TODO + } + if (broken.getType() == toBreak.getType()) { if (broken.getType().isSolid() && toBreak.getType().isSolid()) { // Blocks are solid so check for durability @@ -1818,7 +1838,7 @@ public class BukkitQuester implements Quester { // Ignore durability for 1.13+ goal = toBreak; } - } else if (broken.getData() instanceof Crops && toBreak.getData() instanceof Crops) { + } /*else if (broken.getBlockData() instanceof Ageable && toBreak.getBlockData() instanceof Ageable) { if (toBreak.getDurability() > 0) { // Age toBreak specified so check for durability if (broken.getDurability() == toBreak.getDurability()) { @@ -1828,10 +1848,10 @@ public class BukkitQuester implements Quester { // Age toBreak unspecified so ignore durability goal = toBreak; } - } else if (Material.getMaterial("CRAFTER") != null && broken.getType().isEdible()) { + } */ else if (Material.getMaterial("CRAFTER") != null && broken.getType().isEdible()) { // Paper 1.21+ is special case - final short toBreakAge = NBT.get(toBreak, nbt -> (short) nbt.getShort("quests_age")); - final short brokenAge = NBT.get(broken, nbt -> (short) nbt.getShort("quests_age")); + final short toBreakAge = /* NBT.get(toBreak, nbt -> (short) nbt.getShort("quests_age")); */ 0; + final short brokenAge = broken.getDurability(); if (toBreakAge > 0) { // Age toBreak specified so check for durability if (brokenAge == toBreakAge) { @@ -1875,7 +1895,7 @@ public class BukkitQuester implements Quester { null, null, null, null); // Multiplayer - final ItemStack finalGoal = goal; + final BlockItemStack finalGoal = goal; dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (final Quester q) -> { ((BukkitQuestProgress) q.getQuestProgressOrDefault(quest)).blocksBroken.set(breakIndex, progress); q.finishObjective(quest, new BukkitObjective(type, null, progress, finalGoal), null, null, null, @@ -1888,17 +1908,22 @@ public class BukkitQuester implements Quester { new BukkitObjective(type, null, progress, goal.getAmount())); plugin.getServer().getPluginManager().callEvent(postEvent); } - + + @Override + public void damageBlock(Quest quest, ItemStack itemStack) { + damageBlock(quest, BlockItemStack.of(itemStack)); + } + /** * Marks block as damaged if Quester has such an objective - * + * * @param quest The quest for which the block is being damaged * @param damaged The block being damaged */ @SuppressWarnings("deprecation") - public void damageBlock(final Quest quest, final ItemStack damaged) { - ItemStack goal = null; - for (final ItemStack toDamage : ((BukkitStage) getCurrentStage(quest)).getBlocksToDamage()) { + public void damageBlock(final Quest quest, final BlockItemStack damaged) { + BlockItemStack goal = null; + for (final BlockItemStack toDamage : ((BukkitStage) getCurrentStage(quest)).getBlocksToDamage()) { if (goal != null) { break; } @@ -1927,7 +1952,7 @@ public class BukkitQuester implements Quester { // No match found return; } - + final ObjectiveType type = ObjectiveType.DAMAGE_BLOCK; final BukkitQuesterPreUpdateObjectiveEvent preEvent = new BukkitQuesterPreUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, damaged.getAmount(), goal.getAmount())); @@ -1945,7 +1970,7 @@ public class BukkitQuester implements Quester { null, null, null, null); // Multiplayer - final ItemStack finalGoal = goal; + final BlockItemStack finalGoal = goal; dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (final Quester q) -> { ((BukkitQuestProgress) q.getQuestProgressOrDefault(quest)).blocksDamaged.set(damageIndex, progress); q.finishObjective(quest, new BukkitObjective(type, null, progress, finalGoal), null, null, null, @@ -1953,22 +1978,27 @@ public class BukkitQuester implements Quester { return null; }); } - + final BukkitQuesterPostUpdateObjectiveEvent postEvent = new BukkitQuesterPostUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, progress, goal.getAmount())); plugin.getServer().getPluginManager().callEvent(postEvent); } + @Override + public void placeBlock(Quest quest, ItemStack itemStack) { + placeBlock(quest, BlockItemStack.of(itemStack)); + } + /** * Marks block as placed if Quester has such an objective - * + * * @param quest The quest for which the block is being placed * @param placed The block being placed */ @SuppressWarnings("deprecation") - public void placeBlock(final Quest quest, final ItemStack placed) { - ItemStack goal = null; - for (final ItemStack toPlace : ((BukkitStage) getCurrentStage(quest)).getBlocksToPlace()) { + public void placeBlock(final Quest quest, final BlockItemStack placed) { + BlockItemStack goal = null; + for (final BlockItemStack toPlace : ((BukkitStage) getCurrentStage(quest)).getBlocksToPlace()) { if (goal != null) { break; } @@ -1997,7 +2027,7 @@ public class BukkitQuester implements Quester { // No match found return; } - + final ObjectiveType type = ObjectiveType.PLACE_BLOCK; final BukkitQuesterPreUpdateObjectiveEvent preEvent = new BukkitQuesterPreUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, placed.getAmount(), goal.getAmount())); @@ -2015,7 +2045,7 @@ public class BukkitQuester implements Quester { null, null, null, null); // Multiplayer - final ItemStack finalGoal = goal; + final BlockItemStack finalGoal = goal; dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (final Quester q) -> { ((BukkitQuestProgress) q.getQuestProgressOrDefault(quest)).blocksPlaced.set(placeIndex, progress); q.finishObjective(quest, new BukkitObjective(type, null, progress, finalGoal), null, null, null, @@ -2023,22 +2053,27 @@ public class BukkitQuester implements Quester { return null; }); } - + final BukkitQuesterPostUpdateObjectiveEvent postEvent = new BukkitQuesterPostUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, progress, goal.getAmount())); plugin.getServer().getPluginManager().callEvent(postEvent); } + @Override + public void useBlock(Quest quest, ItemStack itemStack) { + useBlock(quest, BlockItemStack.of(itemStack)); + } + /** * Marks block as used if Quester has such an objective - * + * * @param quest The quest for which the block is being used * @param used The block being used */ @SuppressWarnings("deprecation") - public void useBlock(final Quest quest, final ItemStack used) { - ItemStack goal = null; - for (final ItemStack toUse : ((BukkitStage) getCurrentStage(quest)).getBlocksToUse()) { + public void useBlock(final Quest quest, final BlockItemStack used) { + BlockItemStack goal = null; + for (final BlockItemStack toUse : ((BukkitStage) getCurrentStage(quest)).getBlocksToUse()) { if (goal != null) { break; } @@ -2067,7 +2102,7 @@ public class BukkitQuester implements Quester { // No match found return; } - + final ObjectiveType type = ObjectiveType.USE_BLOCK; final BukkitQuesterPreUpdateObjectiveEvent preEvent = new BukkitQuesterPreUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, used.getAmount(), goal.getAmount())); @@ -2085,7 +2120,7 @@ public class BukkitQuester implements Quester { null, null, null, null); // Multiplayer - final ItemStack finalGoal = goal; + final BlockItemStack finalGoal = goal; dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (final Quester q) -> { ((BukkitQuestProgress) q.getQuestProgressOrDefault(quest)).blocksUsed.set(useIndex, progress); q.finishObjective(quest, new BukkitObjective(type, null, progress, finalGoal), null, null, null, @@ -2093,22 +2128,27 @@ public class BukkitQuester implements Quester { return null; }); } - + final BukkitQuesterPostUpdateObjectiveEvent postEvent = new BukkitQuesterPostUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, progress, goal.getAmount())); plugin.getServer().getPluginManager().callEvent(postEvent); } + @Override + public void cutBlock(Quest quest, ItemStack itemStack) { + cutBlock(quest, BlockItemStack.of(itemStack)); + } + /** * Marks block as cut if Quester has such an objective - * + * * @param quest The quest for which the block is being cut * @param cut The block being cut */ @SuppressWarnings("deprecation") - public void cutBlock(final Quest quest, final ItemStack cut) { - ItemStack goal = null; - for (final ItemStack toCut : ((BukkitStage) getCurrentStage(quest)).getBlocksToCut()) { + public void cutBlock(final Quest quest, final BlockItemStack cut) { + BlockItemStack goal = null; + for (final BlockItemStack toCut : ((BukkitStage) getCurrentStage(quest)).getBlocksToCut()) { if (goal != null) { break; } @@ -2137,7 +2177,7 @@ public class BukkitQuester implements Quester { // No match found return; } - + final ObjectiveType type = ObjectiveType.CUT_BLOCK; final BukkitQuesterPreUpdateObjectiveEvent preEvent = new BukkitQuesterPreUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, cut.getAmount(), goal.getAmount())); @@ -2155,7 +2195,7 @@ public class BukkitQuester implements Quester { null, null, null, null); // Multiplayer - final ItemStack finalGoal = goal; + final BlockItemStack finalGoal = goal; dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (final Quester q) -> { ((BukkitQuestProgress) q.getQuestProgressOrDefault(quest)).blocksCut.set(cutIndex, progress); q.finishObjective(quest, new BukkitObjective(type, null, progress, finalGoal), null, null, null, @@ -2163,15 +2203,15 @@ public class BukkitQuester implements Quester { return null; }); } - + final BukkitQuesterPostUpdateObjectiveEvent postEvent = new BukkitQuesterPostUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, progress, goal.getAmount())); plugin.getServer().getPluginManager().callEvent(postEvent); } - + /** * Mark item as crafted if Quester has such an objective - * + * * @param quest The quest for which the item is being crafted * @param crafted The item being crafted */ @@ -2217,10 +2257,10 @@ public class BukkitQuester implements Quester { plugin.getServer().getPluginManager().callEvent(postEvent); } } - + /** * Mark item as smelted if Quester has such an objective - * + * * @param quest The quest for which the item is being smelted * @param smelted The item being smelted */ @@ -2321,7 +2361,7 @@ public class BukkitQuester implements Quester { /** * Mark item as enchanted if Quester has such an objective - * + * * @param quest The quest for which the item is being enchanted * @param enchanted The item being enchanted */ @@ -2375,10 +2415,10 @@ public class BukkitQuester implements Quester { plugin.getServer().getPluginManager().callEvent(postEvent); } } - + /** * Mark item as brewed if Quester has such an objective - * + * * @param quest The quest for which the item is being brewed * @param brewed The item being brewed */ @@ -2424,10 +2464,10 @@ public class BukkitQuester implements Quester { plugin.getServer().getPluginManager().callEvent(postEvent); } } - + /** * Mark item as consumed if Quester has such an objective - * + * * @param quest The quest for which the item is being consumed * @param consumed The item being consumed */ @@ -2447,12 +2487,12 @@ public class BukkitQuester implements Quester { for (final Integer match : matches) { final int amount = bukkitQuestProgress.itemsConsumed.get(match); final ItemStack goal = ((BukkitStage) getCurrentStage(quest)).getItemsToConsume().get(match); - + final ObjectiveType type = ObjectiveType.CONSUME_ITEM; final BukkitQuesterPreUpdateObjectiveEvent preEvent = new BukkitQuesterPreUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, amount, goal)); plugin.getServer().getPluginManager().callEvent(preEvent); - + final int progress = consumed.getAmount() + amount; bukkitQuestProgress.itemsConsumed.set(match, progress); if (progress >= goal.getAmount()) { @@ -2467,16 +2507,16 @@ public class BukkitQuester implements Quester { return null; }); } - + final BukkitQuesterPostUpdateObjectiveEvent postEvent = new BukkitQuesterPostUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, progress, goal)); plugin.getServer().getPluginManager().callEvent(postEvent); } } - + /** * Mark item as delivered to a NPC if Quester has such an objective - * + * * @param quest The quest for which the item is being delivered * @param npc UUID of the NPC being delivered to * @param delivered The item being delivered @@ -2505,13 +2545,13 @@ public class BukkitQuester implements Quester { } final int amount = bukkitQuestProgress.itemsDelivered.get(match); final ItemStack goal = ((BukkitStage) getCurrentStage(quest)).getItemsToDeliver().get(match); - + final ObjectiveType type = ObjectiveType.DELIVER_ITEM; final Set dispatchedQuestIDs = new HashSet<>(); final BukkitQuesterPreUpdateObjectiveEvent preEvent = new BukkitQuesterPreUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, amount, goal)); plugin.getServer().getPluginManager().callEvent(preEvent); - + final int progress = delivered.getAmount() + amount; final int index = player.getInventory().first(delivered); if (index == -1) { @@ -2551,16 +2591,16 @@ public class BukkitQuester implements Quester { } return null; })); - + final BukkitQuesterPostUpdateObjectiveEvent postEvent = new BukkitQuesterPostUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, progress, goal)); plugin.getServer().getPluginManager().callEvent(postEvent); } } - + /** * Mark NPC as interacted with if Quester has such an objective - * + * * @param quest The quest for which the NPC is being interacted with * @param npc UUID of the NPC being interacted with */ @@ -2594,7 +2634,7 @@ public class BukkitQuester implements Quester { } return null; })); - + final BukkitQuesterPostUpdateObjectiveEvent postEvent = new BukkitQuesterPostUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, 1, 1)); plugin.getServer().getPluginManager().callEvent(postEvent); @@ -2603,7 +2643,7 @@ public class BukkitQuester implements Quester { /** * Mark NPC as killed if the Quester has such an objective - * + * * @param quest The quest for which the NPC is being killed * @param npc UUID of the NPC being killed */ @@ -2611,18 +2651,18 @@ public class BukkitQuester implements Quester { if (!getCurrentStage(quest).getNpcsToKill().contains(npc)) { return; } - + final int index = getCurrentStage(quest).getNpcsToKill().indexOf(npc); final BukkitQuestProgress bukkitQuestProgress = (BukkitQuestProgress) getQuestProgressOrDefault(quest); final int npcsKilled = bukkitQuestProgress.npcsNumKilled.get(index); final int npcsToKill = getCurrentStage(quest).getNpcNumToKill().get(index); - + final ObjectiveType type = ObjectiveType.KILL_NPC; final Set dispatchedQuestIDs = new HashSet<>(); final BukkitQuesterPreUpdateObjectiveEvent preEvent = new BukkitQuesterPreUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, npcsKilled, npcsToKill)); plugin.getServer().getPluginManager().callEvent(preEvent); - + final int newNpcsKilled = bukkitQuestProgress.npcsNumKilled.get(index) + 1; if (npcsKilled < npcsToKill) { bukkitQuestProgress.npcsNumKilled.set(index, newNpcsKilled); @@ -2643,15 +2683,15 @@ public class BukkitQuester implements Quester { return null; })); } - + final BukkitQuesterPostUpdateObjectiveEvent postEvent = new BukkitQuesterPostUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, newNpcsKilled, npcsToKill)); plugin.getServer().getPluginManager().callEvent(postEvent); } - + /** * Marks cow as milked if Quester has such an objective - * + * * @param quest The quest for which the fish is being caught */ public void milkCow(final Quest quest) { @@ -2666,20 +2706,20 @@ public class BukkitQuester implements Quester { if (currentStage.getCowsToMilk() == null) { return; } - + final int cowsMilked = questProgress.getCowsMilked(); final int cowsToMilk = currentStage.getCowsToMilk(); - + final ObjectiveType type = ObjectiveType.MILK_COW; final Set dispatchedQuestIDs = new HashSet<>(); final BukkitQuesterPreUpdateObjectiveEvent preEvent = new BukkitQuesterPreUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, cowsMilked, cowsToMilk)); plugin.getServer().getPluginManager().callEvent(preEvent); - + final int newCowsMilked = cowsMilked + 1; if (cowsMilked < cowsToMilk) { questProgress.setCowsMilked(newCowsMilked); - + if (newCowsMilked >= cowsToMilk) { finishObjective(quest, new BukkitObjective(type, null, new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, cowsToMilk)), null, null, null, null, null, null, null); @@ -2696,15 +2736,15 @@ public class BukkitQuester implements Quester { return null; })); } - + final BukkitQuesterPostUpdateObjectiveEvent postEvent = new BukkitQuesterPostUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, newCowsMilked, cowsToMilk)); plugin.getServer().getPluginManager().callEvent(postEvent); } - + /** * Marks fish as caught if Quester has such an objective - * + * * @param quest The quest for which the fish is being caught */ public void catchFish(final Quest quest) { @@ -2719,20 +2759,20 @@ public class BukkitQuester implements Quester { if (currentStage.getFishToCatch() == null) { return; } - + final int fishCaught = questProgress.getFishCaught(); final int fishToCatch = currentStage.getFishToCatch(); - + final ObjectiveType type = ObjectiveType.CATCH_FISH; final Set dispatchedQuestIDs = new HashSet<>(); final BukkitQuesterPreUpdateObjectiveEvent preEvent = new BukkitQuesterPreUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, fishCaught, fishToCatch)); plugin.getServer().getPluginManager().callEvent(preEvent); - + final int newFishCaught = fishCaught + 1; if (fishCaught < fishToCatch) { questProgress.setFishCaught(newFishCaught); - + if (newFishCaught >= fishToCatch) { finishObjective(quest, new BukkitObjective(type, null, new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, fishToCatch)), null, null, null, null, null, null, null); @@ -2749,7 +2789,7 @@ public class BukkitQuester implements Quester { return null; })); } - + final BukkitQuesterPostUpdateObjectiveEvent postEvent = new BukkitQuesterPostUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, newFishCaught, fishToCatch)); plugin.getServer().getPluginManager().callEvent(postEvent); @@ -2757,7 +2797,7 @@ public class BukkitQuester implements Quester { /** * Mark mob as killed if Quester has such an objective - * + * * @param quest The quest for which the mob is being killed * @param killedLocation The optional location to kill at * @param entityType The mob to be killed @@ -2804,7 +2844,7 @@ public class BukkitQuester implements Quester { final BukkitQuesterPreUpdateObjectiveEvent preEvent = new BukkitQuesterPreUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, mobsKilled, mobsToKill)); plugin.getServer().getPluginManager().callEvent(preEvent); - + final int newMobsKilled = mobsKilled + 1; if (mobsKilled < mobsToKill) { bukkitQuestProgress.mobNumKilled.set(index, newMobsKilled); @@ -2829,7 +2869,7 @@ public class BukkitQuester implements Quester { return null; })); } - + final BukkitQuesterPostUpdateObjectiveEvent postEvent = new BukkitQuesterPostUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, newMobsKilled, mobsToKill)); plugin.getServer().getPluginManager().callEvent(postEvent); @@ -2837,7 +2877,7 @@ public class BukkitQuester implements Quester { /** * Mark player as killed if Quester has such an objective - * + * * @param quest The quest for which the player is being killed * @param player The player to be killed */ @@ -2853,16 +2893,16 @@ public class BukkitQuester implements Quester { if (currentStage.getPlayersToKill() == null) { return; } - + final int playersKilled = bukkitQuestProgress.getPlayersKilled(); final int playersToKill = currentStage.getPlayersToKill(); - + final ObjectiveType type = ObjectiveType.KILL_PLAYER; final Set dispatchedQuestIDs = new HashSet<>(); final BukkitQuesterPreUpdateObjectiveEvent preEvent = new BukkitQuesterPreUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, playersKilled, playersToKill)); plugin.getServer().getPluginManager().callEvent(preEvent); - + final int newPlayersKilled = playersKilled + 1; if (playersKilled < playersToKill) { bukkitQuestProgress.setPlayersKilled(newPlayersKilled); @@ -2883,7 +2923,7 @@ public class BukkitQuester implements Quester { return null; })); } - + final BukkitQuesterPostUpdateObjectiveEvent postEvent = new BukkitQuesterPostUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, newPlayersKilled, playersToKill)); plugin.getServer().getPluginManager().callEvent(postEvent); @@ -2891,7 +2931,7 @@ public class BukkitQuester implements Quester { /** * Mark location as reached if the Quester has such an objective - * + * * @param quest The quest for which the location is being reached * @param location The location being reached */ @@ -2956,7 +2996,7 @@ public class BukkitQuester implements Quester { /** * Mark mob as tamed if the Quester has such an objective - * + * * @param quest The quest for which the mob is being tamed * @param entityType The type of mob being tamed */ @@ -2977,13 +3017,13 @@ public class BukkitQuester implements Quester { final int mobsToTame = currentStage.getMobNumToTame().get(index); final int mobsTamed = bukkitQuestProgress.mobsTamed.get(index); - + final ObjectiveType type = ObjectiveType.TAME_MOB; final Set dispatchedQuestIDs = new HashSet<>(); final BukkitQuesterPreUpdateObjectiveEvent preEvent = new BukkitQuesterPreUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, mobsToTame, mobsTamed)); plugin.getServer().getPluginManager().callEvent(preEvent); - + final int newMobsToTame = mobsTamed + 1; if (mobsTamed < mobsToTame) { bukkitQuestProgress.mobsTamed.set(index, newMobsToTame); @@ -3003,7 +3043,7 @@ public class BukkitQuester implements Quester { return null; })); } - + final BukkitQuesterPostUpdateObjectiveEvent postEvent = new BukkitQuesterPostUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, newMobsToTame, mobsTamed)); plugin.getServer().getPluginManager().callEvent(postEvent); @@ -3011,7 +3051,7 @@ public class BukkitQuester implements Quester { /** * Mark sheep as sheared if the Quester has such an objective - * + * * @param quest The quest for which the sheep is being sheared * @param color The wool color of the sheep being sheared */ @@ -3032,13 +3072,13 @@ public class BukkitQuester implements Quester { final int sheepToShear = getCurrentStage(quest).getSheepNumToShear().get(index); final int sheepSheared = bukkitQuestProgress.sheepSheared.get(index); - + final ObjectiveType type = ObjectiveType.SHEAR_SHEEP; final Set dispatchedQuestIDs = new HashSet<>(); final BukkitQuesterPreUpdateObjectiveEvent preEvent = new BukkitQuesterPreUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, sheepSheared, sheepToShear)); plugin.getServer().getPluginManager().callEvent(preEvent); - + final int newSheepSheared = sheepSheared + 1; if (sheepSheared < sheepToShear) { bukkitQuestProgress.sheepSheared.set(index, newSheepSheared); @@ -3059,7 +3099,7 @@ public class BukkitQuester implements Quester { return null; })); } - + final BukkitQuesterPostUpdateObjectiveEvent postEvent = new BukkitQuesterPostUpdateObjectiveEvent(this, quest, new BukkitObjective(type, null, newSheepSheared, sheepToShear)); plugin.getServer().getPluginManager().callEvent(postEvent); @@ -3067,7 +3107,7 @@ public class BukkitQuester implements Quester { /** * Mark password as entered if the Quester has such an objective - * + * * @param quest The quest for which the password is being entered * @param evt The event during which the password was entered */ @@ -3112,10 +3152,10 @@ public class BukkitQuester implements Quester { plugin.getServer().getPluginManager().callEvent(postEvent); }); } - + /** * Complete a quest objective - * + * * @param quest * Quest containing the objective * @param objective @@ -3146,6 +3186,10 @@ public class BukkitQuester implements Quester { final ObjectiveType type = objective.getType(); final ItemStack goal = objective.getGoalObject() instanceof ItemStack ? (ItemStack) objective.getGoalObject() : new ItemStack(Material.AIR, objective.getGoal()); + final BlockItemStack goalBlock = objective.getGoalObject() instanceof BlockItemStack + ? (BlockItemStack) objective.getGoalObject() + : BlockItemStack.of(Material.AIR, objective.getGoal(), (short) 0); + if (!getCurrentStage(quest).getObjectiveOverrides().isEmpty()) { for (final String s: getCurrentStage(quest).getObjectiveOverrides()) { String message = ChatColor.GREEN + "(" + BukkitLang.get(p, "completed") + ") " @@ -3156,59 +3200,54 @@ public class BukkitQuester implements Quester { sendMessage(message); } } else if (type.equals(ObjectiveType.BREAK_BLOCK)) { - final String message = formatCompletedObjectiveMessage("break", goal.getAmount()); - if (plugin.getConfigSettings().canTranslateNames() && !goal.hasItemMeta() - && !goal.getItemMeta().hasDisplayName()) { - if (!plugin.getLocaleManager().sendMessage(p, message, goal.getType(), goal.getDurability(), - null)) { - sendMessage(message.replace("", BukkitItemUtil.getName(goal))); + final String message = formatCompletedObjectiveMessage("break", goalBlock.getAmount()); + if (plugin.getConfigSettings().canTranslateNames()) { + if (!plugin.getLocaleManager().sendMessage(p, message, + goalBlock.getType(), goalBlock.getDurability(), null)) { + sendMessage(message.replace("", BukkitItemUtil.getName(goalBlock))); } } else { - sendMessage(message.replace("", BukkitItemUtil.getName(goal))); + sendMessage(message.replace("", BukkitItemUtil.getName(goalBlock))); } } else if (type.equals(ObjectiveType.DAMAGE_BLOCK)) { - final String message = formatCompletedObjectiveMessage("damage", goal.getAmount()); - if (plugin.getConfigSettings().canTranslateNames() && !goal.hasItemMeta() - && !goal.getItemMeta().hasDisplayName()) { - if (!plugin.getLocaleManager().sendMessage(p, message, goal.getType(), goal.getDurability(), - null)) { - sendMessage(message.replace("", BukkitItemUtil.getName(goal))); + final String message = formatCompletedObjectiveMessage("damage", goalBlock.getAmount()); + if (plugin.getConfigSettings().canTranslateNames()) { + if (!plugin.getLocaleManager().sendMessage(p, message, + goalBlock.getType(), goalBlock.getDurability(), null)) { + sendMessage(message.replace("", BukkitItemUtil.getName(goalBlock))); } } else { - sendMessage(message.replace("", BukkitItemUtil.getName(goal))); + sendMessage(message.replace("", BukkitItemUtil.getName(goalBlock))); } } else if (type.equals(ObjectiveType.PLACE_BLOCK)) { - final String message = formatCompletedObjectiveMessage("place", goal.getAmount()); - if (plugin.getConfigSettings().canTranslateNames() && !goal.hasItemMeta() - && !goal.getItemMeta().hasDisplayName()) { - if (!plugin.getLocaleManager().sendMessage(p, message, goal.getType(), goal.getDurability(), - null)) { - sendMessage(message.replace("", BukkitItemUtil.getName(goal))); + final String message = formatCompletedObjectiveMessage("place", goalBlock.getAmount()); + if (plugin.getConfigSettings().canTranslateNames()) { + if (!plugin.getLocaleManager().sendMessage(p, message, + goalBlock.getType(), goalBlock.getDurability(), null)) { + sendMessage(message.replace("", BukkitItemUtil.getName(goalBlock))); } } else { - sendMessage(message.replace("", BukkitItemUtil.getName(goal))); + sendMessage(message.replace("", BukkitItemUtil.getName(goalBlock))); } } else if (type.equals(ObjectiveType.USE_BLOCK)) { final String message = formatCompletedObjectiveMessage("use", goal.getAmount()); - if (plugin.getConfigSettings().canTranslateNames() && !goal.hasItemMeta() - && !goal.getItemMeta().hasDisplayName()) { - if (!plugin.getLocaleManager().sendMessage(p, message, goal.getType(), goal.getDurability(), - null)) { - sendMessage(message.replace("", BukkitItemUtil.getName(goal))); + if (plugin.getConfigSettings().canTranslateNames()) { + if (!plugin.getLocaleManager().sendMessage(p, message, + goalBlock.getType(), goalBlock.getDurability(), null)) { + sendMessage(message.replace("", BukkitItemUtil.getName(goalBlock))); } } else { - sendMessage(message.replace("", BukkitItemUtil.getName(goal))); + sendMessage(message.replace("", BukkitItemUtil.getName(goalBlock))); } } else if (type.equals(ObjectiveType.CUT_BLOCK)) { final String message = formatCompletedObjectiveMessage("cut", goal.getAmount()); - if (plugin.getConfigSettings().canTranslateNames() && !goal.hasItemMeta() - && !goal.getItemMeta().hasDisplayName()) { - if (!plugin.getLocaleManager().sendMessage(p, message, goal.getType(), goal.getDurability(), - null)) { - sendMessage(message.replace("", BukkitItemUtil.getName(goal))); + if (plugin.getConfigSettings().canTranslateNames()) { + if (!plugin.getLocaleManager().sendMessage(p, message, + goalBlock.getType(), goalBlock.getDurability(), null)) { + sendMessage(message.replace("", BukkitItemUtil.getName(goalBlock))); } } else { - sendMessage(message.replace("", BukkitItemUtil.getName(goal))); + sendMessage(message.replace("", BukkitItemUtil.getName(goalBlock))); } } else if (type.equals(ObjectiveType.CRAFT_ITEM)) { final ItemStack is = ((BukkitStage) getCurrentStage(quest)).getItemsToCraft().get(getCurrentStage(quest) @@ -3373,7 +3412,7 @@ public class BukkitQuester implements Quester { obj = obj.replace("", getCurrentStage(quest).getLocationNames().get(getCurrentStage(quest) .getLocationsToReach().indexOf(location))); } catch (final IndexOutOfBoundsException e) { - plugin.getLogger().severe("Unable to get final location " + location + " for quest ID " + plugin.getLogger().severe("Unable to get final location " + location + " for quest ID " + quest.getId() + ", please report on Github"); obj = obj.replace("", "ERROR"); } @@ -3397,7 +3436,7 @@ public class BukkitQuester implements Quester { for (final Entry dataMap : end) { message = message.replace("%" + (dataMap.getKey()) + "%", String.valueOf(dataMap.getValue())); } - + if (co.canShowCount()) { message = message.replace("%count%", goal.getAmount() + "/" + goal.getAmount()); } @@ -3429,10 +3468,10 @@ public class BukkitQuester implements Quester { } return message; } - + /** * Check whether this Quester has completed all objectives for their current stage - * + * * @param quest The quest with the current stage being checked * @return true if all stage objectives are marked complete */ @@ -3444,10 +3483,10 @@ public class BukkitQuester implements Quester { } return true; } - + /** * Add empty map values per Quest stage - * + * * @param quest Quest with at least one stage * @param stage Where first stage is '0' */ @@ -3464,27 +3503,27 @@ public class BukkitQuester implements Quester { } final BukkitStage bukkitStage = (BukkitStage) quest.getStage(stage); if (!bukkitStage.getBlocksToBreak().isEmpty()) { - for (final ItemStack ignored : bukkitStage.getBlocksToBreak()) { + for (final BlockItemStack ignored : bukkitStage.getBlocksToBreak()) { data.blocksBroken.add(0); } } if (!bukkitStage.getBlocksToDamage().isEmpty()) { - for (final ItemStack ignored : bukkitStage.getBlocksToDamage()) { + for (final BlockItemStack ignored : bukkitStage.getBlocksToDamage()) { data.blocksDamaged.add(0); } } if (!bukkitStage.getBlocksToPlace().isEmpty()) { - for (final ItemStack ignored : bukkitStage.getBlocksToPlace()) { + for (final BlockItemStack ignored : bukkitStage.getBlocksToPlace()) { data.blocksPlaced.add(0); } } if (!bukkitStage.getBlocksToUse().isEmpty()) { - for (final ItemStack ignored : bukkitStage.getBlocksToUse()) { + for (final BlockItemStack ignored : bukkitStage.getBlocksToUse()) { data.blocksUsed.add(0); } } if (!bukkitStage.getBlocksToCut().isEmpty()) { - for (final ItemStack ignored : bukkitStage.getBlocksToCut()) { + for (final BlockItemStack ignored : bukkitStage.getBlocksToCut()) { data.blocksCut.add(0); } } @@ -3564,11 +3603,11 @@ public class BukkitQuester implements Quester { data.setDoJournalUpdate(true); hardDataPut(quest, data); } - + /** * Save data of the Quester to file - * + * * @return true if successful */ public boolean saveData() { @@ -3579,10 +3618,10 @@ public class BukkitQuester implements Quester { } return true; } - + /** * Get the difference between System.currentTimeMillis() and the last completed time for a quest - * + * * @param quest The quest to get the last completed time of * @return Difference between now and then in milliseconds */ @@ -3597,10 +3636,10 @@ public class BukkitQuester implements Quester { } return currentTime - lastTime; } - + /** * Get the amount of time left before Quester may take a completed quest again - * + * * @param quest The quest to calculate the cooldown for * @return Length of time in milliseconds */ @@ -3740,10 +3779,10 @@ public class BukkitQuester implements Quester { data.set("lastKnownName", representedPlayer.getName()); return data; } - + /** * Load data of the Quester from storage - * + * * @deprecated Use {@link #hasData()} * @return true if successful */ @@ -3751,19 +3790,19 @@ public class BukkitQuester implements Quester { public boolean loadData() { return plugin.getStorage().loadQuester(id) != null; } - + /** * Check whether the Quester has data saved to hard storage - * + * * @return true if successful */ public boolean hasData() { return plugin.getStorage().loadQuester(id) != null; } - + /** * Check whether the Quester has base data in memory, indicating they have participated in quests - * + * * @return false if empty */ public boolean hasBaseData() { @@ -3791,7 +3830,7 @@ public class BukkitQuester implements Quester { } getQuestProgressOrDefault(quest).setDelayStartTime(System.currentTimeMillis()); } - + /** * Pause the stage timer. Useful when a player quits * @param quest The quest of which the timer is for @@ -3805,7 +3844,7 @@ public class BukkitQuester implements Quester { - getQuestProgressOrDefault(quest).getDelayStartTime())); } } - + /** * Get remaining stage delay time * @param quest The quest of which the timer is for @@ -3820,10 +3859,10 @@ public class BukkitQuester implements Quester { - getQuestProgressOrDefault(quest).getDelayStartTime()); } } - + /** * Check whether the provided quest is valid and, if not, inform the Quester - * + * * @param quest The quest to check */ public void checkQuest(final Quest quest) { @@ -3854,7 +3893,7 @@ public class BukkitQuester implements Quester { /** * Show an inventory GUI with quest items to the specified player - * + * * @param npc UUID of the NPC from which the GUI is bound * @param quests List of quests to use for displaying items */ @@ -3876,7 +3915,7 @@ public class BukkitQuester implements Quester { return; } final Player player = getPlayer(); - final Inventory inv = plugin.getServer().createInventory(player, ((quests.size() / 9) + 1) * 9, + final Inventory inv = plugin.getServer().createInventory(player, ((quests.size() / 9) + 1) * 9, BukkitLang.get(player, "quests") + " | " + name); int i = 0; for (final Quest quest : quests) { @@ -3895,9 +3934,9 @@ public class BukkitQuester implements Quester { /** * Force Quester to quit the specified quest (canceling any timers), then update Quest Journal

- * + * * Does not save changes to disk. Consider {@link #quitQuest(Quest, String)} or {@link #quitQuest(Quest, String[])} - * + * * @param quest The quest to quit */ public void hardQuit(final Quest quest) { @@ -3922,9 +3961,9 @@ public class BukkitQuester implements Quester { /** * Forcibly remove quest from Quester's list of completed quests, then update Quest Journal

- * + * * Does not save changes to disk. Consider calling {@link #saveData()} followed by {@link #loadData()} - * + * * @param quest The quest to remove */ public void hardRemove(final Quest quest) { @@ -3937,7 +3976,7 @@ public class BukkitQuester implements Quester { /** * Forcibly clear Quester's list of current quests and data, then update Quest Journal

- * + * * Does not save changes to disk. Consider calling {@link #saveData()} followed by {@link #loadData()} */ public void hardClear() { @@ -3953,7 +3992,7 @@ public class BukkitQuester implements Quester { /** * Forcibly set Quester's current stage, then update Quest Journal
* Does not save changes to disk. Consider calling {@link #saveData()} followed by {@link #loadData()} - * + * * @param key The quest to set stage of * @param val The stage number to set */ @@ -3967,9 +4006,9 @@ public class BukkitQuester implements Quester { /** * Forcibly set Quester's quest data, then update Quest Journal

- * + * * Does not save changes to disk. Consider calling {@link #saveData()} followed by {@link #loadData()} - * + * * @param key The quest to set stage of * @param val The data to set */ @@ -3980,7 +4019,7 @@ public class BukkitQuester implements Quester { ex.printStackTrace(); } } - + public boolean canUseCompass() { if (getPlayer() != null) { if (!getPlayer().hasPermission("worldedit.navigation.jumpto")) { @@ -3992,7 +4031,7 @@ public class BukkitQuester implements Quester { /** * Reset compass target to Quester's bed spawn location

- * + * * Will set to Quester's spawn location if bed spawn does not exist */ public void resetCompass() { @@ -4004,7 +4043,7 @@ public class BukkitQuester implements Quester { if (!canUseCompass()) { return; } - + Location defaultLocation = player.getBedSpawnLocation(); if (defaultLocation == null) { defaultLocation = player.getWorld().getSpawnLocation(); @@ -4033,10 +4072,10 @@ public class BukkitQuester implements Quester { } } } - + /** * Update compass target to current stage of next available current quest, if possible - * + * * @param notify Whether to notify this quester of result */ public void findNextCompassTarget(final boolean notify) { @@ -4084,12 +4123,12 @@ public class BukkitQuester implements Quester { } }); } - + /** * Check whether the Quester's inventory contains the specified item - * + * * @param is The item with a specified amount to check - * @return true if the inventory contains at least the amount of the specified stack + * @return true if the inventory contains at least the amount of the specified stack */ public boolean hasItem(final ItemStack is) { final Inventory inv = getPlayer().getInventory(); @@ -4103,7 +4142,7 @@ public class BukkitQuester implements Quester { } return playerAmount >= is.getAmount(); } - + /** * Dispatch player event to fellow questers

* @@ -4148,7 +4187,7 @@ public class BukkitQuester implements Quester { } return appliedQuestIDs; } - + /** * Dispatch finish objective to fellow questers * @@ -4175,10 +4214,10 @@ public class BukkitQuester implements Quester { } return appliedQuestIDs; } - + /** * Get a list of fellow Questers in a party or group - * + * * @param quest The quest which uses a linked plugin, i.e. Parties or DungeonsXL * @return Potentially empty list of Questers or null for invalid quest */ diff --git a/core/src/main/java/me/pikamug/quests/quests/BukkitQuestFactory.java b/core/src/main/java/me/pikamug/quests/quests/BukkitQuestFactory.java index aae488ea6..010416aef 100644 --- a/core/src/main/java/me/pikamug/quests/quests/BukkitQuestFactory.java +++ b/core/src/main/java/me/pikamug/quests/quests/BukkitQuestFactory.java @@ -22,6 +22,7 @@ import me.pikamug.quests.quests.components.Planner; import me.pikamug.quests.quests.components.Requirements; import me.pikamug.quests.quests.components.Rewards; import me.pikamug.quests.quests.components.Stage; +import me.pikamug.quests.util.stack.BlockItemStack; import me.pikamug.quests.util.BukkitConfigUtil; import me.pikamug.quests.util.BukkitFakeConversable; import me.pikamug.quests.util.BukkitLang; @@ -303,7 +304,7 @@ public class BukkitQuestFactory implements QuestFactory, ConversationAbandonedLi final LinkedList names = new LinkedList<>(); final LinkedList amounts = new LinkedList<>(); final LinkedList durability = new LinkedList<>(); - for (final ItemStack e : bukkitStage.getBlocksToBreak()) { + for (final BlockItemStack e : bukkitStage.getBlocksToBreak()) { names.add(e.getType().name()); amounts.add(e.getAmount()); durability.add(e.getDurability()); @@ -316,7 +317,7 @@ public class BukkitQuestFactory implements QuestFactory, ConversationAbandonedLi final LinkedList names = new LinkedList<>(); final LinkedList amounts = new LinkedList<>(); final LinkedList durability = new LinkedList<>(); - for (final ItemStack e : bukkitStage.getBlocksToDamage()) { + for (final BlockItemStack e : bukkitStage.getBlocksToDamage()) { names.add(e.getType().name()); amounts.add(e.getAmount()); durability.add(e.getDurability()); @@ -329,7 +330,7 @@ public class BukkitQuestFactory implements QuestFactory, ConversationAbandonedLi final LinkedList names = new LinkedList<>(); final LinkedList amounts = new LinkedList<>(); final LinkedList durability = new LinkedList<>(); - for (final ItemStack e : bukkitStage.getBlocksToPlace()) { + for (final BlockItemStack e : bukkitStage.getBlocksToPlace()) { names.add(e.getType().name()); amounts.add(e.getAmount()); durability.add(e.getDurability()); @@ -342,7 +343,7 @@ public class BukkitQuestFactory implements QuestFactory, ConversationAbandonedLi final LinkedList names = new LinkedList<>(); final LinkedList amounts = new LinkedList<>(); final LinkedList durability = new LinkedList<>(); - for (final ItemStack e : bukkitStage.getBlocksToUse()) { + for (final BlockItemStack e : bukkitStage.getBlocksToUse()) { names.add(e.getType().name()); amounts.add(e.getAmount()); durability.add(e.getDurability()); @@ -355,7 +356,7 @@ public class BukkitQuestFactory implements QuestFactory, ConversationAbandonedLi final LinkedList names = new LinkedList<>(); final LinkedList amounts = new LinkedList<>(); final LinkedList durability = new LinkedList<>(); - for (final ItemStack e : bukkitStage.getBlocksToCut()) { + for (final BlockItemStack e : bukkitStage.getBlocksToCut()) { names.add(e.getType().name()); amounts.add(e.getAmount()); durability.add(e.getDurability()); diff --git a/core/src/main/java/me/pikamug/quests/quests/components/BukkitObjective.java b/core/src/main/java/me/pikamug/quests/quests/components/BukkitObjective.java index 779906d1c..28f22bb6e 100644 --- a/core/src/main/java/me/pikamug/quests/quests/components/BukkitObjective.java +++ b/core/src/main/java/me/pikamug/quests/quests/components/BukkitObjective.java @@ -12,6 +12,7 @@ package me.pikamug.quests.quests.components; import me.pikamug.quests.entity.BukkitCountableMob; import me.pikamug.quests.enums.ObjectiveType; +import me.pikamug.quests.util.stack.BlockItemStack; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -46,6 +47,8 @@ public class BukkitObjective implements Objective { this.progress = ((BukkitCountableMob) progressObj).getCount(); } else if (progressObj instanceof Integer) { this.progress = (int) progress; + } else if (progressObj instanceof BlockItemStack) { + this.progress = ((BlockItemStack) progressObj).getAmount(); } else { this.progress = 0; } @@ -55,6 +58,8 @@ public class BukkitObjective implements Objective { this.goal = ((BukkitCountableMob) goalObj).getCount(); } else if (goalObj instanceof Integer) { this.goal = (int) goalObj; + } else if (progressObj instanceof BlockItemStack) { + this.goal = ((BlockItemStack) progressObj).getAmount(); } else { this.goal = 0; } @@ -90,6 +95,10 @@ public class BukkitObjective implements Objective { return goalObj; } + public @Nullable BlockItemStack getGoalAsBlockItem() { + return goalObj instanceof BlockItemStack ? (BlockItemStack) goalObj : null; + } + /** * @deprecated Paper 1.21 builds do not allow ItemStack with 0 amount */ diff --git a/core/src/main/java/me/pikamug/quests/quests/components/BukkitStage.java b/core/src/main/java/me/pikamug/quests/quests/components/BukkitStage.java index c2a78a0c7..63035cc6f 100644 --- a/core/src/main/java/me/pikamug/quests/quests/components/BukkitStage.java +++ b/core/src/main/java/me/pikamug/quests/quests/components/BukkitStage.java @@ -14,7 +14,7 @@ import me.pikamug.quests.actions.Action; import me.pikamug.quests.conditions.Condition; import me.pikamug.quests.enums.ObjectiveType; import me.pikamug.quests.module.CustomObjective; -import me.pikamug.quests.quests.components.Stage; +import me.pikamug.quests.util.stack.BlockItemStack; import org.bukkit.DyeColor; import org.bukkit.Location; import org.bukkit.World; @@ -30,11 +30,11 @@ import java.util.UUID; public class BukkitStage implements Stage { - private LinkedList blocksToBreak = new LinkedList<>(); - private LinkedList blocksToDamage = new LinkedList<>(); - private LinkedList blocksToPlace = new LinkedList<>(); - private LinkedList blocksToUse = new LinkedList<>(); - private LinkedList blocksToCut = new LinkedList<>(); + private LinkedList blocksToBreak = new LinkedList<>(); + private LinkedList blocksToDamage = new LinkedList<>(); + private LinkedList blocksToPlace = new LinkedList<>(); + private LinkedList blocksToUse = new LinkedList<>(); + private LinkedList blocksToCut = new LinkedList<>(); private LinkedList itemsToCraft = new LinkedList<>(); private LinkedList itemsToSmelt = new LinkedList<>(); private LinkedList itemsToEnchant = new LinkedList<>(); @@ -137,63 +137,63 @@ public class BukkitStage implements Stage { private final LinkedList customObjectiveDisplays = new LinkedList<>(); private final LinkedList> customObjectiveData = new LinkedList<>(); - public LinkedList getBlocksToBreak() { + public LinkedList getBlocksToBreak() { return blocksToBreak; } - public boolean addBlockToBreak(@NotNull ItemStack blockToBreak) { + public boolean addBlockToBreak(@NotNull BlockItemStack blockToBreak) { return blocksToBreak.add(blockToBreak); } - public void setBlocksToBreak(final LinkedList blocksToBreak) { + public void setBlocksToBreak(final LinkedList blocksToBreak) { this.blocksToBreak = blocksToBreak; } - public LinkedList getBlocksToDamage() { + public LinkedList getBlocksToDamage() { return blocksToDamage; } - public boolean addBlockToDamage(@NotNull ItemStack blockToDamage) { + public boolean addBlockToDamage(@NotNull BlockItemStack blockToDamage) { return blocksToDamage.add(blockToDamage); } - public void setBlocksToDamage(final LinkedList blocksToDamage) { + public void setBlocksToDamage(final LinkedList blocksToDamage) { this.blocksToDamage = blocksToDamage; } - public LinkedList getBlocksToPlace() { + public LinkedList getBlocksToPlace() { return blocksToPlace; } - public boolean addBlockToPlace(@NotNull ItemStack blockToPlace) { + public boolean addBlockToPlace(@NotNull BlockItemStack blockToPlace) { return blocksToPlace.add(blockToPlace); } - public void setBlocksToPlace(final LinkedList blocksToPlace) { + public void setBlocksToPlace(final LinkedList blocksToPlace) { this.blocksToPlace = blocksToPlace; } - public LinkedList getBlocksToUse() { + public LinkedList getBlocksToUse() { return blocksToUse; } - public boolean addBlockToUse(@NotNull ItemStack blockToUse) { + public boolean addBlockToUse(@NotNull BlockItemStack blockToUse) { return blocksToUse.add(blockToUse); } - public void setBlocksToUse(final LinkedList blocksToUse) { + public void setBlocksToUse(final LinkedList blocksToUse) { this.blocksToUse = blocksToUse; } - public LinkedList getBlocksToCut() { + public LinkedList getBlocksToCut() { return blocksToCut; } - public boolean addBlockToCut(@NotNull ItemStack blockToCut) { + public boolean addBlockToCut(@NotNull BlockItemStack blockToCut) { return blocksToCut.add(blockToCut); } - public void setBlocksToCut(final LinkedList blocksToCut) { + public void setBlocksToCut(final LinkedList blocksToCut) { this.blocksToCut = blocksToCut; } diff --git a/core/src/main/java/me/pikamug/quests/storage/implementation/file/BukkitQuestYamlStorage.java b/core/src/main/java/me/pikamug/quests/storage/implementation/file/BukkitQuestYamlStorage.java index bab57f038..30d1905d3 100644 --- a/core/src/main/java/me/pikamug/quests/storage/implementation/file/BukkitQuestYamlStorage.java +++ b/core/src/main/java/me/pikamug/quests/storage/implementation/file/BukkitQuestYamlStorage.java @@ -16,6 +16,7 @@ import me.pikamug.quests.quests.components.BukkitStage; import me.pikamug.quests.quests.components.Options; import me.pikamug.quests.quests.components.Planner; import me.pikamug.quests.storage.implementation.QuestStorageImpl; +import me.pikamug.quests.util.stack.BlockItemStack; import me.pikamug.quests.util.BukkitConfigUtil; import me.pikamug.quests.util.BukkitItemUtil; import me.pikamug.quests.util.BukkitMiscUtil; @@ -877,12 +878,12 @@ public class BukkitQuestYamlStorage implements QuestStorageImpl { } for (int i = 0; i < breakNames.size(); i++) { final String name = breakNames.get(i); - final ItemStack is; + final BlockItemStack is; if (i < breakDurability.size() && breakDurability.get(i) != -1) { - is = BukkitItemUtil.processItemStack(name, breakAmounts.get(i), breakDurability.get(i)); + is = BukkitItemUtil.processBlockItemStack(name, breakAmounts.get(i), breakDurability.get(i)); } else { // Legacy - is = BukkitItemUtil.processItemStack(name, breakAmounts.get(i), (short) 0); + is = BukkitItemUtil.processBlockItemStack(name, breakAmounts.get(i), (short) 0); } if (is != null && Material.matchMaterial(name) != null) { bukkitStage.addBlockToBreak(is); @@ -919,12 +920,12 @@ public class BukkitQuestYamlStorage implements QuestStorageImpl { } for (int i = 0; i < damageNames.size(); i++) { final String name = damageNames.get(i); - final ItemStack is; + final BlockItemStack is; if (i < damageDurability.size() && damageDurability.get(i) != -1) { - is = BukkitItemUtil.processItemStack(name, damageAmounts.get(i), damageDurability.get(i)); + is = BukkitItemUtil.processBlockItemStack(name, damageAmounts.get(i), damageDurability.get(i)); } else { // Legacy - is = BukkitItemUtil.processItemStack(name, damageAmounts.get(i), (short) 0); + is = BukkitItemUtil.processBlockItemStack(name, damageAmounts.get(i), (short) 0); } if (is != null && Material.matchMaterial(name) != null) { bukkitStage.addBlockToDamage(is); @@ -960,12 +961,12 @@ public class BukkitQuestYamlStorage implements QuestStorageImpl { } for (int i = 0; i < placeNames.size(); i++) { final String name = placeNames.get(i); - final ItemStack is; + final BlockItemStack is; if (i < placeDurability.size() && placeDurability.get(i) != -1) { - is = BukkitItemUtil.processItemStack(name, placeAmounts.get(i), placeDurability.get(i)); + is = BukkitItemUtil.processBlockItemStack(name, placeAmounts.get(i), placeDurability.get(i)); } else { // Legacy - is = BukkitItemUtil.processItemStack(name, placeAmounts.get(i), (short) 0); + is = BukkitItemUtil.processBlockItemStack(name, placeAmounts.get(i), (short) 0); } if (is != null && Material.matchMaterial(name) != null) { bukkitStage.addBlockToPlace(is); @@ -1001,12 +1002,12 @@ public class BukkitQuestYamlStorage implements QuestStorageImpl { } for (int i = 0; i < useNames.size(); i++) { final String name = useNames.get(i); - final ItemStack is; + final BlockItemStack is; if (i < useDurability.size() && useDurability.get(i) != -1) { - is = BukkitItemUtil.processItemStack(name, useAmounts.get(i), useDurability.get(i)); + is = BukkitItemUtil.processBlockItemStack(name, useAmounts.get(i), useDurability.get(i)); } else { // Legacy - is = BukkitItemUtil.processItemStack(name, useAmounts.get(i), (short) 0); + is = BukkitItemUtil.processBlockItemStack(name, useAmounts.get(i), (short) 0); } if (is != null && Material.matchMaterial(name) != null) { bukkitStage.addBlockToUse(is); @@ -1042,12 +1043,12 @@ public class BukkitQuestYamlStorage implements QuestStorageImpl { } for (int i = 0; i < cutNames.size(); i++) { final String name = cutNames.get(i); - final ItemStack is; + final BlockItemStack is; if (i < cutDurability.size() && cutDurability.get(i) != -1) { - is = BukkitItemUtil.processItemStack(name, cutAmounts.get(i), cutDurability.get(i)); + is = BukkitItemUtil.processBlockItemStack(name, cutAmounts.get(i), cutDurability.get(i)); } else { // Legacy - is = BukkitItemUtil.processItemStack(name, cutAmounts.get(i), (short) 0); + is = BukkitItemUtil.processBlockItemStack(name, cutAmounts.get(i), (short) 0); } if (is != null && Material.matchMaterial(name) != null) { bukkitStage.addBlockToCut(is); diff --git a/core/src/main/java/me/pikamug/quests/util/BukkitItemUtil.java b/core/src/main/java/me/pikamug/quests/util/BukkitItemUtil.java index 34bcb2007..61726bb31 100644 --- a/core/src/main/java/me/pikamug/quests/util/BukkitItemUtil.java +++ b/core/src/main/java/me/pikamug/quests/util/BukkitItemUtil.java @@ -11,6 +11,7 @@ package me.pikamug.quests.util; import de.tr7zw.changeme.nbtapi.NBT; +import me.pikamug.quests.util.stack.BlockItemStack; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Color; @@ -257,6 +258,34 @@ public class BukkitItemUtil { } } + public static BlockItemStack processBlockItemStack(final String material, final int amount, final short durability) { + if (material == null) { + return null; + } + try { + Material mat = Material.getMaterial(material.toUpperCase()); + if (mat == null) { + return null; + } + return BlockItemStack.of(mat, amount, durability); + } catch (final Exception e) { + try { + Bukkit.getLogger().warning(material + " x " + amount + + " is invalid! You may need to update your quests.yml or actions.yml " + + "in accordance with https://bit.ly/2BkBNNN"); + final Material mat = Material.matchMaterial(material, true); + if (mat == null) { + return null; + } + return BlockItemStack.of(mat, amount, durability); + } catch (final Exception e2) { + Bukkit.getLogger().severe("Unable to use LEGACY_" + material + " as item name"); + e2.printStackTrace(); + return null; + } + } + } + /** * Get ItemStack from formatted string. See #serializeItemStack for reverse function. * @@ -623,6 +652,19 @@ public class BukkitItemUtil { return text; } + /** + * Returns a formatted display name. If none exists, returns item name. + * + * @param itemStack BlockItemStack to check + * @return true display or item name, if stack is not null + */ + public static String getName(final BlockItemStack itemStack) { + if (itemStack == null) { + return null; + } + return ChatColor.AQUA + getPrettyItemName(itemStack.getType().name()); + } + /** * Ensures that an ItemStack is a valid, non-AIR material *