Java tutorial
/** * This file is part of MythicDrops, licensed under the MIT License. * * Copyright (C) 2013 Teal Cube Games * * Permission is hereby granted, free of charge, * to any person obtaining a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or * substantial portions of the Software. * * 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. 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package com.tealcube.minecraft.bukkit.mythicdrops.items; import com.google.common.base.Joiner; import com.google.common.base.Splitter; import com.tealcube.minecraft.bukkit.lumberjack.Lumberjack; import com.tealcube.minecraft.bukkit.lumberjack.shade.slf4j.Logger; import com.tealcube.minecraft.bukkit.mythicdrops.MythicDropsPlugin; import com.tealcube.minecraft.bukkit.mythicdrops.api.MythicDrops; import com.tealcube.minecraft.bukkit.mythicdrops.api.enchantments.MythicEnchantment; import com.tealcube.minecraft.bukkit.mythicdrops.api.items.ItemGenerationReason; import com.tealcube.minecraft.bukkit.mythicdrops.api.items.MythicItemStack; import com.tealcube.minecraft.bukkit.mythicdrops.api.items.NonrepairableItemStack; import com.tealcube.minecraft.bukkit.mythicdrops.api.items.builders.DropBuilder; import com.tealcube.minecraft.bukkit.mythicdrops.api.names.NameType; import com.tealcube.minecraft.bukkit.mythicdrops.api.tiers.Tier; import com.tealcube.minecraft.bukkit.mythicdrops.events.RandomItemGenerationEvent; import com.tealcube.minecraft.bukkit.mythicdrops.names.NameMap; import com.tealcube.minecraft.bukkit.mythicdrops.tiers.TierMap; import com.tealcube.minecraft.bukkit.mythicdrops.utils.ItemStackUtil; import com.tealcube.minecraft.bukkit.mythicdrops.utils.ItemUtil; import com.tealcube.minecraft.bukkit.mythicdrops.utils.RandomRangeUtil; import com.tealcube.minecraft.bukkit.mythicdrops.utils.StringUtil; import net.nunnerycode.bukkit.libraries.ivory.collections.IvoryStringList; import org.apache.commons.lang.Validate; import org.apache.commons.lang.math.RandomUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.commons.lang3.text.WordUtils; import org.bukkit.*; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.LeatherArmorMeta; import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.material.MaterialData; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public final class MythicDropBuilder implements DropBuilder { private static final Logger LOGGER = Lumberjack.loggerToFile(MythicDropBuilder.class, MythicDropsPlugin.getLoggerFile().getAbsolutePath()); private static final Pattern PERCENTAGE_PATTERN = Pattern.compile("%(?s)(.*?)%"); private static final Pattern DASH_PATTERN = Pattern.compile("\\s*[-]\\s*"); private MythicDrops mythicDrops; private Tier tier; private Material material; private ItemGenerationReason itemGenerationReason; private boolean useDurability; private boolean callEvent; public MythicDropBuilder(MythicDrops mythicDrops) { this.mythicDrops = mythicDrops; tier = null; itemGenerationReason = ItemGenerationReason.DEFAULT; useDurability = false; callEvent = true; } @Override public DropBuilder withTier(Tier tier) { this.tier = tier; return this; } @Override public DropBuilder withTier(String tierName) { this.tier = TierMap.getInstance().get(tierName); return this; } @Override public DropBuilder withMaterial(Material material) { this.material = material; return this; } @Override @Deprecated public DropBuilder withMaterialData(MaterialData materialData) { return withMaterial(materialData != null ? materialData.getItemType() : Material.AIR); } @Override @Deprecated public DropBuilder withMaterialData(String materialDataString) { // do nothing return this; } @Override public DropBuilder withItemGenerationReason(ItemGenerationReason reason) { this.itemGenerationReason = reason; return this; } @Override @Deprecated public DropBuilder inWorld(World world) { // do nothing return this; } @Override @Deprecated public DropBuilder inWorld(String worldName) { // do nothing return this; } @Override public DropBuilder useDurability(boolean b) { this.useDurability = b; return this; } @Override public ItemStack build() { Tier t = (tier != null) ? tier : TierMap.getInstance().getRandomWithChance(); if (t == null) { t = TierMap.getInstance().getRandomWithChance(); if (t == null) { return null; } } tier = t; Material mat = material != null ? material : ItemUtil.getRandomMaterialFromCollection(ItemUtil.getMaterialsFromTier(t)); if (mat == null || mat == Material.AIR) { return null; } NonrepairableItemStack nis = new NonrepairableItemStack(mat, 1, (short) 0, ""); ItemMeta im = nis.getItemMeta(); Map<Enchantment, Integer> baseEnchantmentMap = getBaseEnchantments(nis, t); Map<Enchantment, Integer> bonusEnchantmentMap = getBonusEnchantments(nis, t); for (Map.Entry<Enchantment, Integer> baseEnch : baseEnchantmentMap.entrySet()) { im.addEnchant(baseEnch.getKey(), baseEnch.getValue(), true); } for (Map.Entry<Enchantment, Integer> bonusEnch : bonusEnchantmentMap.entrySet()) { im.addEnchant(bonusEnch.getKey(), bonusEnch.getValue(), true); } if (useDurability) { nis.setDurability(ItemStackUtil.getDurabilityForMaterial(nis.getType(), t.getMinimumDurabilityPercentage(), t.getMaximumDurabilityPercentage())); } String name = generateName(nis, im); im.setDisplayName(name); List<String> lore = generateLore(nis, im); im.setLore(lore); if (nis.getItemMeta() instanceof LeatherArmorMeta) { ((LeatherArmorMeta) im).setColor( Color.fromRGB(RandomUtils.nextInt(255), RandomUtils.nextInt(255), RandomUtils.nextInt(255))); } if (nis.getItemMeta() instanceof SkullMeta) { ((SkullMeta) im).setOwner("ToppleTheNun"); } nis.setItemMeta(im); if (callEvent) { RandomItemGenerationEvent rige = new RandomItemGenerationEvent(t, nis, itemGenerationReason); Bukkit.getPluginManager().callEvent(rige); if (rige.isCancelled()) { return null; } return rige.getItemStack(); } return nis; } private Map<Enchantment, Integer> getBonusEnchantments(MythicItemStack is, Tier t) { Validate.notNull(is, "MythicItemStack cannot be null"); Validate.notNull(t, "Tier cannot be null"); if (t.getBonusEnchantments() == null || t.getBonusEnchantments().isEmpty()) { return new HashMap<>(); } Map<Enchantment, Integer> map = new HashMap<>(); int added = 0; int attempts = 0; int range = RandomRangeUtil.randomRange(t.getMinimumBonusEnchantments(), t.getMaximumBonusEnchantments()); MythicEnchantment[] array = t.getBonusEnchantments() .toArray(new MythicEnchantment[t.getBonusEnchantments().size()]); while (added < range && attempts < 10) { MythicEnchantment chosenEnch = array[RandomUtils.nextInt(array.length)]; if (chosenEnch == null || chosenEnch.getEnchantment() == null) { attempts++; continue; } Enchantment e = chosenEnch.getEnchantment(); int randLevel = RandomRangeUtil.randomRange(chosenEnch.getMinimumLevel(), chosenEnch.getMaximumLevel()); if (map.containsKey(e)) { if (randLevel + map.get(e) > chosenEnch.getMaximumLevel()) { attempts++; continue; } randLevel += map.get(e); } if (t.isSafeBonusEnchantments()) { if (e.getItemTarget() == null) { attempts++; continue; } if (!e.getItemTarget().includes(is.getType())) { attempts++; continue; } if (!t.isAllowHighBonusEnchantments()) { randLevel = getAcceptableEnchantmentLevel(e, randLevel); } } else { if (!t.isAllowHighBonusEnchantments()) { randLevel = getAcceptableEnchantmentLevel(e, randLevel); } } map.put(e, randLevel); added++; } return map; } private Map<Enchantment, Integer> getBaseEnchantments(MythicItemStack is, Tier t) { Validate.notNull(is, "MythicItemStack cannot be null"); Validate.notNull(t, "Tier cannot be null"); if (t.getBaseEnchantments() == null || t.getBaseEnchantments().isEmpty()) { return new HashMap<>(); } Map<Enchantment, Integer> map = new HashMap<>(); for (MythicEnchantment me : t.getBaseEnchantments()) { if (me == null) { continue; } Enchantment e = me.getEnchantment(); if (e == null) { continue; } int minimumLevel = Math.max(me.getMinimumLevel(), e.getStartLevel()); int maximumLevel = Math.min(me.getMaximumLevel(), e.getMaxLevel()); if (t.isSafeBaseEnchantments() && e.canEnchantItem(is)) { if (t.isAllowHighBaseEnchantments()) { map.put(e, RandomRangeUtil.randomRange(minimumLevel, me.getMaximumLevel())); } else { map.put(e, getAcceptableEnchantmentLevel(e, RandomRangeUtil.randomRange(minimumLevel, maximumLevel))); } } else if (!t.isSafeBaseEnchantments()) { map.put(e, RandomRangeUtil.randomRange(me.getMinimumLevel(), me.getMaximumLevel())); } } return map; } private int getAcceptableEnchantmentLevel(Enchantment ench, int level) { return Math.max(Math.min(level, ench.getMaxLevel()), ench.getStartLevel()); } private List<String> generateLore(ItemStack itemStack, ItemMeta itemMeta) { IvoryStringList tempLore = new IvoryStringList(); if (itemStack == null || tier == null || itemMeta == null) { return tempLore; } List<String> tooltipFormat = mythicDrops.getConfigSettings().getTooltipFormat(); String minecraftName = getMinecraftMaterialName(itemStack.getData().getItemType()); String mythicName = getMythicMaterialName(itemStack.getType()); String itemType = getItemTypeName(ItemUtil.getItemTypeFromMaterial(itemStack.getType())); String materialType = getItemTypeName(ItemUtil.getMaterialTypeFromMaterial(itemStack.getType())); String tierName = tier.getDisplayName(); String enchantment = getEnchantmentTypeName(itemMeta); String generalLoreString = NameMap.getInstance().getRandom(NameType.GENERAL_LORE, ""); String materialLoreString = NameMap.getInstance().getRandom(NameType.MATERIAL_LORE, itemStack.getType().name().toLowerCase()); String tierLoreString = NameMap.getInstance().getRandom(NameType.TIER_LORE, tier.getName().toLowerCase()); String enchantmentLoreString = NameMap.getInstance().getRandom(NameType.ENCHANTMENT_LORE, enchantment != null ? enchantment.toLowerCase() : ""); String itemTypeLoreString = NameMap.getInstance().getRandom(NameType.ITEMTYPE_LORE, ItemUtil.getItemTypeFromMaterial(itemStack.getType())); List<String> generalLore = Arrays.asList(generalLoreString.split("/n")); List<String> materialLore = Arrays.asList(materialLoreString.split("/n")); List<String> tierLore = Arrays.asList(tierLoreString.split("/n")); List<String> enchantmentLore = Arrays.asList(enchantmentLoreString.split("/n")); List<String> itemTypeLore = Arrays.asList(itemTypeLoreString.split("/n")); tempLore.addAll(tooltipFormat); List<String> baseLore = new ArrayList<>(); for (String s : tier.getBaseLore()) { String[] strings = s.split("/n"); baseLore.addAll(Arrays.asList(strings)); } List<String> bonusLore = new ArrayList<>(); int numOfBonusLore = RandomRangeUtil.randomRange(tier.getMinimumBonusLore(), tier.getMaximumBonusLore()); List<String> chosenLore = new ArrayList<>(); for (int i = 0; i < numOfBonusLore; i++) { if (tier.getBonusLore() == null || tier.getBonusLore().isEmpty() || chosenLore.size() == tier.getBonusLore().size()) { continue; } // choose a random String out of the tier's bonus lore String s = tier.getBonusLore().get(RandomUtils.nextInt(tier.getBonusLore().size())); if (chosenLore.contains(s)) { i--; continue; } chosenLore.add(s); // split on the next line /n String[] strings = s.split("/n"); bonusLore.addAll(Arrays.asList(strings)); } double c = MythicDropsPlugin.getInstance().getRandom().nextDouble(); List<String> socketLore = new ArrayList<>(); if (mythicDrops.getConfigSettings().isSockettingEnabled() && c < tier.getChanceToHaveSockets()) { int numberOfSockets = RandomRangeUtil.randomRange(tier.getMinimumSockets(), tier.getMaximumSockets()); if (numberOfSockets > 0) { for (int i = 0; i < numberOfSockets; i++) { String line = mythicDrops.getSockettingSettings().getSockettedItemString(); socketLore.add(line); } socketLore.addAll(mythicDrops.getSockettingSettings().getSockettedItemLore()); } } List<String> relationLore = new ArrayList<>(); for (String s : ChatColor.stripColor(itemMeta.getDisplayName()).split(" ")) { relationLore.addAll(mythicDrops.getRelationSettings().getLoreFromName(s)); } tempLore.replaceWithList("%baselore%", baseLore); tempLore.replaceWithList("%generallore%", generalLore); tempLore.replaceWithList("%materiallore%", materialLore); tempLore.replaceWithList("%tierlore%", tierLore); tempLore.replaceWithList("%enchantmentlore%", enchantmentLore); tempLore.replaceWithList("%itemtypelore%", itemTypeLore); tempLore.replaceWithList("%baselore%", baseLore); tempLore.replaceWithList("%bonuslore%", bonusLore); tempLore.replaceWithList("%socketlore%", socketLore); tempLore.replaceWithList("%relationlore%", relationLore); String[][] args = { { "%basematerial%", minecraftName != null ? minecraftName : "" }, { "%mythicmaterial%", mythicName != null ? mythicName : "" }, { "%mythicmaterial%", mythicName != null ? mythicName : "" }, { "%itemtype%", itemType != null ? itemType : "" }, { "%materialtype%", materialType != null ? materialType : "" }, { "%tiername%", tierName != null ? tierName : "" }, { "%enchantment%", enchantment != null ? enchantment : "" }, { "%tiercolor%", tier.getDisplayColor() + "" } }; List<String> lore = new ArrayList<>(); for (String s : tempLore) { lore.add(StringUtil.colorString(StringUtil.replaceArgs(s, args))); } return randomVariableReplace(lore); } private List<String> randomVariableReplace(List<String> list) { List<String> newList = new ArrayList<>(); for (String s : list) { Matcher matcher = PERCENTAGE_PATTERN.matcher(s); while (matcher.find()) { String check = matcher.group(); String replacedCheck = StringUtils.replace(StringUtils.replace(check, "%rand", ""), "%", ""); List<String> split = Splitter.on(DASH_PATTERN).omitEmptyStrings().trimResults() .splitToList(replacedCheck); LOGGER.debug(String.format("%s | %s | %s", s, check, split.toString())); int first = NumberUtils.toInt(split.get(0)); int second = NumberUtils.toInt(split.get(1)); int min = Math.min(first, second); int max = Math.max(first, second); int random = (int) Math.round((Math.random() * (max - min) + min)); newList.add(s.replace(check, String.valueOf(random))); } if (s.contains("%rand")) { continue; } newList.add(s); } return newList; } private String getEnchantmentTypeName(ItemMeta itemMeta) { Enchantment enchantment = ItemStackUtil.getHighestEnchantment(itemMeta); if (enchantment == null) { return mythicDrops.getConfigSettings().getFormattedLanguageString("displayNames.Ordinary"); } String ench = mythicDrops.getConfigSettings() .getFormattedLanguageString("displayNames." + enchantment.getName()); if (ench != null) { return ench; } return "Ordinary"; } private String getMythicMaterialName(Material matData) { String comb = matData.name(); String mythicMatName = mythicDrops.getConfigSettings().getFormattedLanguageString("displayNames." + comb); if (mythicMatName == null || mythicMatName.equals("displayNames." + comb)) { mythicMatName = getMinecraftMaterialName(matData); } return WordUtils.capitalize(mythicMatName); } private String getMinecraftMaterialName(Material material) { String matName = material.name(); String[] split = matName.split("_"); String prettyMaterialName = Joiner.on(" ").skipNulls().join(split); return WordUtils.capitalizeFully(prettyMaterialName); } private String getItemTypeName(String itemType) { if (itemType == null) { return ""; } String mythicMatName = mythicDrops.getConfigSettings() .getFormattedLanguageString("displayNames." + itemType.toLowerCase()); if (mythicMatName == null) { mythicMatName = itemType; } return WordUtils.capitalizeFully(mythicMatName); } private String generateName(ItemStack itemStack, ItemMeta itemMeta) { Validate.notNull(itemStack, "ItemStack cannot be null"); Validate.notNull(tier, "Tier cannot be null"); String format = mythicDrops.getConfigSettings().getItemDisplayNameFormat(); if (format == null || format.isEmpty()) { return "Mythic Item"; } String minecraftName = getMinecraftMaterialName(itemStack.getData().getItemType()); String mythicName = getMythicMaterialName(itemStack.getType()); String generalPrefix = NameMap.getInstance().getRandom(NameType.GENERAL_PREFIX, ""); String generalSuffix = NameMap.getInstance().getRandom(NameType.GENERAL_SUFFIX, ""); String materialPrefix = NameMap.getInstance().getRandom(NameType.MATERIAL_PREFIX, itemStack.getType().name().toLowerCase()); String materialSuffix = NameMap.getInstance().getRandom(NameType.MATERIAL_SUFFIX, itemStack.getType().name().toLowerCase()); String tierPrefix = NameMap.getInstance().getRandom(NameType.TIER_PREFIX, tier.getName().toLowerCase()); String tierSuffix = NameMap.getInstance().getRandom(NameType.TIER_SUFFIX, tier.getName().toLowerCase()); String itemType = getItemTypeName(ItemUtil.getItemTypeFromMaterial(itemStack.getType())); String materialType = getItemTypeName(ItemUtil.getMaterialTypeFromMaterial(itemStack.getType())); String tierName = tier.getDisplayName(); String enchantment = getEnchantmentTypeName(itemMeta); Enchantment highestEnch = ItemStackUtil.getHighestEnchantment(itemMeta); String enchantmentPrefix = NameMap.getInstance().getRandom(NameType.ENCHANTMENT_PREFIX, highestEnch != null ? highestEnch.getName().toLowerCase() : ""); String enchantmentSuffix = NameMap.getInstance().getRandom(NameType.ENCHANTMENT_SUFFIX, highestEnch != null ? highestEnch.getName().toLowerCase() : ""); String itemTypePrefix = NameMap.getInstance().getRandom(NameType.ITEMTYPE_PREFIX, ItemUtil.getItemTypeFromMaterial(itemStack.getType())); String itemTypeSuffix = NameMap.getInstance().getRandom(NameType.ITEMTYPE_SUFFIX, ItemUtil.getItemTypeFromMaterial(itemStack.getType())); String[][] args = { { "%basematerial%", minecraftName }, { "%mythicmaterial%", mythicName }, { "%generalprefix%", generalPrefix }, { "%generalsuffix%", generalSuffix }, { "%materialprefix%", materialPrefix }, { "%materialsuffix%", materialSuffix }, { "%tierprefix%", tierPrefix }, { "%tiersuffix%", tierSuffix }, { "%itemtypeprefix%", itemTypePrefix }, { "%itemtypesuffix%", itemTypeSuffix }, { "%itemtype%", itemType }, { "%materialtype%", materialType }, { "%tiername%", tierName }, { "%enchantment%", enchantment }, { "%enchantmentprefix%", enchantmentPrefix }, { "%enchantmentsuffix%", enchantmentSuffix } }; return tier.getDisplayColor() + StringUtil.colorString(StringUtil.replaceArgs(format, args)).trim() + tier.getIdentificationColor(); } }