/*
* Copyright 2015 fromgate. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. You cannot use this file (or part of this file) in commercial projects.
*
* 2. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 3. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and contributors and should not be interpreted as representing official policies,
* either expressed or implied, of anybody else.
*/
package me.fromgate.reactions.util.item;
import org.bukkit.Color;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.block.banner.PatternType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BannerMeta;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.FireworkEffectMeta;
import org.bukkit.inventory.meta.FireworkMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.MapMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.inventory.meta.SkullMeta;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
public class VirtualItem18 extends VirtualItem {
private final static Pattern INT = Pattern.compile("\\d+");
/**
* Constructor Create new VirtualItem object
*
* @param type - Item type
*/
public VirtualItem18(Material type) {
super(type);
}
/**
* Constructor Create new VirtualItem object
*
* @param type - Item type
* @param data - durabiltity (data)
* @param amount - amount
*/
public VirtualItem18(Material type, int data, int amount) {
super(type);
this.setDurability((short) data);
this.setAmount(amount);
}
/**
* Constructor Create new VirtualItem object based on ItemStack
*
* @param item
*/
public VirtualItem18(ItemStack item) {
super(item);
}
public static VirtualItem18 fromItemStack(ItemStack item) {
if (item == null || item.getType() == Material.AIR)
return null;
return new VirtualItem18(item);
}
/**
* Create VirtualItem object based on parameter-string
*
* @param itemStr - String. Format: type:<Type> data:<Data> amount:<Amount>
* [AnotherParameters] item:<Type>:<Data>*<Amount>
* [AnotherParameters]
* @return - New VirtualItem object or null (if parse failed)
*/
public static VirtualItem18 fromString(String itemStr) {
Map<String, String> params = parseParams(itemStr);
VirtualItem18 vi = fromMap(params);
if (vi != null)
return vi;
ItemStack item = parseOldItemStack(itemStr);
if (item != null)
return new VirtualItem18(item);
return null;
}
/**
* Create VirtualItem object (deserialize from Map)
*
* @param params - Map of parameters and values
* @return - VirtualItem object
*/
@SuppressWarnings("deprecation")
public static VirtualItem18 fromMap(Map<String, String> params) {
if (params == null || params.isEmpty())
return null;
Material type;
int data;
int amount;
if (params.containsKey("item") || params.containsKey("default-param")) {
String itemStr = params.containsKey("item") ? params.get("item")
: params.get("default-param");
String dataStr = "0";
String amountStr = "1";
if (itemStr.contains("*")) {
itemStr = new String(itemStr.substring(0, itemStr.indexOf("*")));
amountStr = new String(itemStr.substring(itemStr.indexOf("*") + 1));
}
if (itemStr.contains(":")) {
itemStr = new String(itemStr.substring(0, itemStr.indexOf(":")));
dataStr = new String(itemStr.substring(itemStr.indexOf(":") + 1));
}
type = INT.matcher(itemStr).matches() ? Material.getMaterial(Integer
.valueOf(itemStr)) : Material.getMaterial(itemStr
.toUpperCase());
data = INT.matcher(dataStr).matches() ? Integer.valueOf(dataStr) : 0;
amount = getNumber(amountStr);
if (amount == 0) return null;
} else if (params.containsKey("type")) {
String typeStr = getParam(params, "type", "");
type = INT.matcher(typeStr).matches() ? Material.getMaterial(Integer
.valueOf(typeStr)) : Material.getMaterial(typeStr
.toUpperCase());
} else
return null;
if (type == null)
return null;
data = getNumber(getParam(params, "data", "0"));
amount = getNumber(getParam(params, "amount", "1"));
VirtualItem18 vi = new VirtualItem18(type, data, amount);
vi.setName(getParam(params, "name"));
vi.setLore(getParam(params, "lore"));
vi.setEnchantments(getParam(params, "enchantments"));
vi.setBook(getParam(params, "book-author"), getParam(params, "book-title"), getParam(params, "book-pages"));
vi.setFireworks(getNumber(getParam(params, "firework-power", "0")), getParam(params, "firework-effects"));
vi.setColor(getParam(params, "color"));
vi.setSkull(getParam(params, "skull-owner"));
vi.setPotionMeta(getParam(params, "potion-effects"));
vi.setMap(getParam(params, "map-scale", "false").equalsIgnoreCase("true"));
vi.setEnchantStorage(getParam(params, "stored-enchants"));
vi.setBanner(params);
vi.setFireworkEffect(getParam(params, "firework-effects"));
return vi;
}
/**
* Serialize VirtualItem to Map<String,String>
*
* @return
*/
public Map<String, String> toMap() {
Map<String, String> params = new LinkedHashMap<>();
params.put("type", this.getType().name());
params.put("data", Integer.toString(this.getDurability()));
params.put("amount", Integer.toString(this.getAmount()));
putEnchants(params, "enchantments", this.getEnchantments());
putItemMeta(params, this.getItemMeta());
if (ADD_REGEX) params.put("regex", "false");
return params;
}
@Override
protected void putItemMeta(Map<String, String> params, ItemMeta itemMeta) {
if (itemMeta == null)
return;
if (itemMeta.hasDisplayName())
put(params, "name", itemMeta.getDisplayName().replace('§', '&'));
if (itemMeta.hasLore())
put(params, "lore", itemMeta.getLore());
if (itemMeta instanceof BookMeta) {
BookMeta bm = (BookMeta) itemMeta;
put(params, "book-author", bm.getAuthor().replace('§', '&'));
put(params, "book-title", bm.getTitle().replace('§', '&'));
if (bm.getPages() != null && !bm.getPages().isEmpty()) {
List<String> pages = new ArrayList<>();
for (String page : bm.getPages()) {
String newPage = page.replaceAll("§0\n", "&z");
newPage = newPage.replace('§', '&');
pages.add(newPage);
}
put(params, "book-pages", pages);
}
}
if (itemMeta instanceof FireworkMeta) {
FireworkMeta fm = (FireworkMeta) itemMeta;
put(params, "firework-power", fm.getPower());
put(params, "firework-effects", fireworksToList(fm.getEffects()));
}
if (itemMeta instanceof LeatherArmorMeta) {
LeatherArmorMeta lm = (LeatherArmorMeta) itemMeta;
put(params, "color", colorToString(lm.getColor(), true));
}
if (itemMeta instanceof SkullMeta) {
SkullMeta sm = (SkullMeta) itemMeta;
if (sm.hasOwner())
put(params, "skull-owner", sm.getOwner());
}
if (itemMeta instanceof PotionMeta) {
PotionMeta pm = (PotionMeta) itemMeta;
if (pm.hasCustomEffects())
putEffects(params, "potion-effects", pm.getCustomEffects());
}
if (itemMeta instanceof MapMeta) {
MapMeta mm = (MapMeta) itemMeta;
if (mm.isScaling())
put(params, "map-scale", "true");
}
if (itemMeta instanceof EnchantmentStorageMeta) {
EnchantmentStorageMeta esm = (EnchantmentStorageMeta) itemMeta;
if (esm.hasStoredEnchants())
putEnchants(params, "stored-enchants", esm.getStoredEnchants());
}
if (itemMeta instanceof BannerMeta)
putBannerMeta(params, (BannerMeta) itemMeta);
if (itemMeta instanceof FireworkEffectMeta)
putFireworkEffectMeta(params, (FireworkEffectMeta) itemMeta);
}
private void putBannerMeta(Map<String, String> params, BannerMeta bm) {
put(params, "color", bm.getBaseColor().name());
StringBuilder sb = new StringBuilder();
for (org.bukkit.block.banner.Pattern p : bm.getPatterns()) {
if (sb.length() > 0)
sb.append(";");
sb.append(p.getPattern().name()).append(":")
.append(p.getColor().name());
}
if (sb.length() > 0)
put(params, "patterns", sb.toString());
}
protected static double getColorDistance(Color c1, Color c2) {
double rmean = (c1.getRed() + c2.getRed()) / 2.0;
double r = c1.getRed() - c2.getRed();
double g = c1.getGreen() - c2.getGreen();
int b = c1.getBlue() - c2.getBlue();
double weightR = 2 + rmean / 256.0;
double weightG = 4.0;
double weightB = 2 + (255 - rmean) / 256.0;
return weightR * r * r + weightG * g * g + weightB * b * b;
}
protected static DyeColor getClosestColor(Color color) {
int index = 0;
double best = -1;
for (int i = 0; i < DyeColor.values().length; i++) {
double distance = getColorDistance(color,
DyeColor.values()[i].getColor());
if (distance < best || best == -1) {
best = distance;
index = i;
}
}
return DyeColor.values()[index];
}
/**
* Deserialize banner parameters
*
* @param params
*/
private void setBanner(Map<String, String> params) {
if (!(this.getItemMeta() instanceof BannerMeta))
return;
BannerMeta bm = (BannerMeta) this.getItemMeta();
String colorStr = getParam(params, "color");
if (colorStr != null && !colorStr.isEmpty()) {
DyeColor dc = parseDyeColor(colorStr);
if (dc != null)
bm.setBaseColor(dc);
}
String patternStr = getParam(params, "patterns");
if (patternStr != null && !patternStr.isEmpty()) {
String[] ln = patternStr.split(";");
for (String pStr : ln) {
String pattern = pStr;
String dc = "";
if (pStr.contains(":")) {
dc = new String(pStr.substring(pStr.indexOf(":") + 1));
pattern = new String(pStr.substring(0, pStr.indexOf(":")));
}
PatternType pType = PatternType.getByIdentifier(pattern
.toUpperCase());
if (pType == null) {
for (PatternType p : PatternType.values())
if (p.name().equalsIgnoreCase(pattern))
pType = p;
}
if (pType == null)
continue;
DyeColor c = parseDyeColor(dc);
if (c == null)
continue;
bm.addPattern(new org.bukkit.block.banner.Pattern(c, pType));
}
}
this.setItemMeta(bm);
}
@SuppressWarnings("deprecation")
@Override
protected void setColor(String colorStr) {
if (colorStr == null || colorStr.isEmpty()) return;
if (this.getItemMeta() instanceof LeatherArmorMeta) {
Color c = parseColor(colorStr);
if (c == null) return;
LeatherArmorMeta lm = (LeatherArmorMeta) this.getItemMeta();
lm.setColor(c);
this.setItemMeta(lm);
} else {
DyeColor dc = parseDyeColor(colorStr);
if (dc == null) return;
switch (this.getType()) {
case WOOL:
case STAINED_GLASS:
case STAINED_CLAY:
case STAINED_GLASS_PANE:
this.setDurability(dc.getWoolData());
break;
case INK_SACK:
this.setDurability(dc.getDyeData());
default:
break;
}
}
}
}