package org.mctourney.autoreferee.util;
import java.util.Map;
import java.util.Set;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.apache.commons.lang.StringUtils;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.jdom2.Element;
import org.mctourney.autoreferee.AutoRefPlayer;
import org.mctourney.autoreferee.AutoReferee;
public class PlayerKit
{
// potion effects
private Set<PotionEffect> potionEffects = Sets.newHashSet();
// player gear
private Set<ItemStack> gear = Sets.newHashSet();
private ItemStack helmet = null;
private ItemStack chest = null;
private ItemStack leggings = null;
private ItemStack boots = null;
// colored gear (gear that needs special coloring)
private Set<ItemStack> teamColors = Sets.newHashSet();
// name of kit
private String name = "Custom Kit";
public PlayerKit() { }
public PlayerKit(String name)
{ super(); this.setName(name); }
private static Map<String, PotionEffectType> potionTypes = Maps.newHashMap();
static
{
for (PotionEffectType type : PotionEffectType.values()) if (type != null)
potionTypes.put(type.getName().toLowerCase().replaceAll("_", " "), type);
potionTypes.put("resistance", PotionEffectType.DAMAGE_RESISTANCE);
potionTypes.put("strength", PotionEffectType.INCREASE_DAMAGE);
potionTypes.put("jump boost", PotionEffectType.JUMP);
potionTypes.put("slowness", PotionEffectType.SLOW);
potionTypes.put("haste", PotionEffectType.FAST_DIGGING);
potionTypes.put("mining fatigue", PotionEffectType.SLOW_DIGGING);
}
public static PotionEffectType getPotionEffectType(String type)
{
try { return PotionEffectType.getById(Integer.parseInt(type)); }
catch (NumberFormatException e) { }
type = type.toLowerCase();
int bscore = Integer.MAX_VALUE; PotionEffectType best = null;
for (Map.Entry<String, PotionEffectType> e : potionTypes.entrySet())
{
int score = StringUtils.getLevenshteinDistance(type, e.getKey());
if (score < bscore) { bscore = score; best = e.getValue(); }
}
return best;
}
public static PotionEffect parsePotionEffect(Element element)
{
assert "effect".equalsIgnoreCase(element.getName());
PotionEffectType type = getPotionEffectType(element.getAttributeValue("type"));
int duration = -1, amplifier = 0;
try { duration = Integer.parseInt(element.getAttributeValue("duration")) * 20; }
catch (NumberFormatException e) { }
try { amplifier = Integer.parseInt(element.getAttributeValue("level")) - 1; }
catch (NumberFormatException e) { }
return new PotionEffect(type, duration, amplifier);
}
public static void addParsedEnchantment(ItemStack item, Element element)
{
assert "enchant".equalsIgnoreCase(element.getName());
String etype = element.getAttributeValue("type");
Enchantment enchantment = Enchantment.getByName(etype);
if (enchantment == null)
try { enchantment = Enchantment.getById(Integer.parseInt(etype)); }
catch (NumberFormatException e) { }
if (enchantment == null)
{
etype = etype.toLowerCase();
int bscore = Integer.MAX_VALUE;
for (Enchantment ench : Enchantment.values())
{
int score = StringUtils.getLevenshteinDistance(ench.getName().toLowerCase(), etype);
if (score < bscore) { bscore = score; enchantment = ench; }
}
}
int elevel = 1;
if (element.getAttribute("level") != null)
try { elevel = Integer.parseInt(element.getAttributeValue("level")); }
catch (NumberFormatException e) { e.printStackTrace(); }
item.addUnsafeEnchantment(enchantment, elevel);
}
public PlayerKit(Element elt)
{
assert "kit".equalsIgnoreCase(elt.getName());
this.setName(elt.getAttributeValue("name").trim());
Element effectsElement = elt.getChild("effects");
if (effectsElement != null)
for (Element effect : effectsElement.getChildren("effect"))
this.addPotionEffect(parsePotionEffect(effect));
Element gearElement = elt.getChild("gear");
if (gearElement != null)
for (Element gear : gearElement.getChildren())
{
String typename = gear.getAttributeValue("type");
Material type = Material.getMaterial(typename);
if (type == null)
try { type = Material.getMaterial(Integer.parseInt(typename)); }
catch (NumberFormatException e) { }
if (type == null)
{
typename = typename.toLowerCase();
int bscore = Integer.MAX_VALUE;
for (Material mat : Material.values())
{
int score = StringUtils.getLevenshteinDistance(mat.name().toLowerCase(), typename);
if (score < bscore) { bscore = score; type = mat; }
}
}
if (type == null) continue;
int count = 1, damage = 0;
// cheating here a bit. Exception covers both NumberFormatException and NullPointerException
try { count = Integer.parseInt(gear.getAttributeValue("count")); } catch (Exception ignored) { }
try { damage = Integer.parseInt(gear.getAttributeValue("damage")); } catch (Exception ignored) { }
// get item stack locally so we can inspect it a bit first
ItemStack item = new ItemStack(type, count, (short) damage);
Color color = null;
if (item.getItemMeta() instanceof LeatherArmorMeta)
{
// add this to the list of items that need to be team colored
if (gear.getChild("teamcolor") != null)
this.teamColors.add(item);
// add a specific coloring
else if (gear.getChild("color") != null)
{
Element colorElt = gear.getChild("color");
if (colorElt != null)
{
LeatherArmorMeta armorMeta = (LeatherArmorMeta) item.getItemMeta();
if (colorElt.getAttributeValue("hex") != null && color == null)
color = ColorConverter.hexToColor(colorElt.getAttributeValue("hex"));
if (colorElt.getAttributeValue("rgb") != null && color == null)
color = ColorConverter.rgbToColor(colorElt.getAttributeValue("rgb"));
if (color != null) armorMeta.setColor(color);
item.setItemMeta(armorMeta);
}
}
}
if (item.getItemMeta() instanceof PotionMeta)
{
PotionMeta potionMeta = (PotionMeta) item.getItemMeta();
for (Element effect : gear.getChildren("effect"))
potionMeta.addCustomEffect(parsePotionEffect(effect), true);
item.setItemMeta(potionMeta);
}
for (Element enchant : gear.getChildren("enchant"))
addParsedEnchantment(item, enchant);
if (gear.getChild("name") != null)
{
ItemMeta itemMeta = item.getItemMeta();
itemMeta.setDisplayName(gear.getChildTextTrim("name"));
item.setItemMeta(itemMeta);
}
// TODO Books
String gearmeta = gear.getName();
// if the gear is any of the armor slots, set those
if (gearmeta.startsWith("helm")) this.setHelmet(item);
else if (gearmeta.startsWith("chest")) this.setChest(item);
else if (gearmeta.startsWith("leg")) this.setLeggings(item);
else if (gearmeta.startsWith("boot")) this.setBoots(item);
// otherwise, default to adding the gear to the inventory
else this.addGear(item);
}
}
private ItemStack cloneItem(AutoRefPlayer apl, ItemStack item)
{
ItemStack clone = item.clone();
if (teamColors.contains(item) && apl.getTeam() != null
&& clone.getItemMeta() instanceof LeatherArmorMeta)
{
// get the team color
LeatherArmorMeta armorMeta = (LeatherArmorMeta) clone.getItemMeta();
String hex = ColorConverter.chatToHex(apl.getTeam().getColor());
// color the armor with the team color
armorMeta.setColor(ColorConverter.hexToColor(hex));
clone.setItemMeta(armorMeta);
}
return clone;
}
public void giveTo(AutoRefPlayer apl)
{
Player pl = apl.getPlayer();
if (pl == null) return;
PlayerInventory pinv = pl.getInventory();
pinv.clear();
// set armor slots
pinv.setHelmet(getHelmet() == null ? null : cloneItem(apl, getHelmet()));
pinv.setChestplate(getChest() == null ? null : cloneItem(apl, getChest()));
pinv.setLeggings(getLeggings() == null ? null : cloneItem(apl, getLeggings()));
pinv.setBoots(getBoots() == null ? null : cloneItem(apl, getBoots()));
// give items (cloned, adjusted)
for (ItemStack item : getGear())
pinv.addItem(cloneItem(apl, item));
// assign potion effects
for (PotionEffect effect : getPotionEffects())
pl.addPotionEffect(effect, true);
}
public Set<PotionEffect> getPotionEffects()
{ return potionEffects; }
public void addPotionEffect(PotionEffect effect)
{ potionEffects.add(effect); }
public Set<ItemStack> getGear()
{ return gear; }
public void addGear(ItemStack item)
{ gear.add(item); }
public ItemStack getHelmet()
{ return helmet; }
public void setHelmet(ItemStack helmet)
{ this.helmet = helmet; }
public ItemStack getChest()
{ return chest; }
public void setChest(ItemStack chest)
{ this.chest = chest; }
public ItemStack getLeggings()
{ return leggings; }
public void setLeggings(ItemStack leggings)
{ this.leggings = leggings; }
public ItemStack getBoots()
{ return boots; }
public void setBoots(ItemStack boots)
{ this.boots = boots; }
public String getName()
{ return name; }
public void setName(String name)
{ this.name = name; }
}