package net.glowstone.constants;
import net.glowstone.inventory.MaterialMatcher;
import net.glowstone.util.WeightedRandom;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.inventory.ItemStack;
/**
* Definitions of enchantment types.
*/
public final class GlowEnchantment extends Enchantment implements WeightedRandom.Choice {
private final Impl impl;
private GlowEnchantment(Impl impl) {
super(impl.id);
this.impl = impl;
}
@Override
public String getName() {
// nb: returns enum name, not text name
return impl.name();
}
@Override
public int getMaxLevel() {
return impl.maxLevel;
}
@Override
public int getStartLevel() {
return 1;
}
@Override
public EnchantmentTarget getItemTarget() {
return impl.target;
}
@Override
public boolean conflictsWith(Enchantment other) {
return impl.group != GROUP_NONE && impl.group == ((GlowEnchantment) other).impl.group;
}
@Override
public boolean canEnchantItem(ItemStack item) {
return impl.matcher.matches(item.getType());
}
@Override
public int getWeight() {
return impl.weight;
}
public boolean isInRange(int level, int modifier) {
return modifier >= impl.getMinRange(level) && modifier <= impl.getMaxRange(level);
}
/**
* Register all enchantment types with Enchantment.
*/
public static void register() {
for (Impl impl : Impl.values()) {
registerEnchantment(new GlowEnchantment(impl));
}
stopAcceptingRegistrations();
}
private static final MaterialMatcher SWORD_OR_AXE = new MaterialMatcher() {
@Override
public boolean matches(Material item) {
return EnchantmentTarget.WEAPON.includes(item)
|| item.equals(Material.WOOD_AXE)
|| item.equals(Material.STONE_AXE)
|| item.equals(Material.IRON_AXE)
|| item.equals(Material.DIAMOND_AXE)
|| item.equals(Material.GOLD_AXE);
}
};
private static final MaterialMatcher BASE_TOOLS = new MaterialMatcher() {
@Override
public boolean matches(Material item) {
return item.equals(Material.WOOD_SPADE)
|| item.equals(Material.STONE_SPADE)
|| item.equals(Material.IRON_SPADE)
|| item.equals(Material.DIAMOND_SPADE)
|| item.equals(Material.GOLD_SPADE)
|| item.equals(Material.WOOD_PICKAXE)
|| item.equals(Material.STONE_PICKAXE)
|| item.equals(Material.IRON_PICKAXE)
|| item.equals(Material.DIAMOND_PICKAXE)
|| item.equals(Material.GOLD_PICKAXE)
|| item.equals(Material.WOOD_AXE)
|| item.equals(Material.STONE_AXE)
|| item.equals(Material.IRON_AXE)
|| item.equals(Material.DIAMOND_AXE)
|| item.equals(Material.GOLD_AXE);
}
};
private static final MaterialMatcher DIGGING_TOOLS = new MaterialMatcher() {
@Override
public boolean matches(Material material) {
return BASE_TOOLS.matches(material)
|| material == Material.SHEARS;
}
};
private static final MaterialMatcher ALL_THINGS = new MaterialMatcher() {
@Override
public boolean matches(Material material) {
return EnchantmentTarget.TOOL.includes(material)
|| EnchantmentTarget.WEAPON.includes(material)
|| EnchantmentTarget.ARMOR.includes(material)
|| material == Material.FISHING_ROD
|| material == Material.BOW
|| material == Material.CARROT_STICK;
}
};
private static final int GROUP_NONE = 0;
private static final int GROUP_PROTECT = 1;
private static final int GROUP_ATTACK = 2;
private static final int GROUP_DIG = 3;
private static enum Impl {
PROTECTION_ENVIRONMENTAL(0, "Protection", 4, 10, 1, 11, 20, EnchantmentTarget.ARMOR, GROUP_PROTECT),
PROTECTION_FIRE(1, "Fire Protection", 4, 5, 10, 8, 12, EnchantmentTarget.ARMOR, GROUP_PROTECT),
PROTECTION_FALL(2, "Feather Falling", 4, 5, 5, 6, 10, EnchantmentTarget.ARMOR_FEET, GROUP_PROTECT),
PROTECTION_EXPLOSIONS(3, "Blast Protection", 4, 2, 5, 8, 12, EnchantmentTarget.ARMOR),
PROTECTION_PROJECTILE(4, "Projectile Protection", 4, 5, 3, 6, 15, EnchantmentTarget.ARMOR, GROUP_PROTECT),
OXYGEN(5, "Respiration", 3, 2, 10, 10, 30, EnchantmentTarget.ARMOR_HEAD),
WATER_WORKER(6, "Aqua Affinity", 1, 2, 1, 0, 40, EnchantmentTarget.ARMOR_HEAD),
THORNS(7, "Thorns", 3, 1, 10, 20, 50, false, EnchantmentTarget.ARMOR_TORSO, new MatcherAdapter(EnchantmentTarget.ARMOR)),
DEPTH_STRIDER(8, "Depth Strider", 3, 2, 10, 10, 15, EnchantmentTarget.ARMOR_FEET),
DAMAGE_ALL(16, "Sharpness", 5, 10, 1, 11, 20, EnchantmentTarget.WEAPON, SWORD_OR_AXE, GROUP_ATTACK),
DAMAGE_UNDEAD(17, "Smite", 5, 5, 5, 8, 20, EnchantmentTarget.WEAPON, SWORD_OR_AXE, GROUP_ATTACK),
DAMAGE_ARTHROPODS(18, "Bane of Arthropods", 5, 5, 5, 8, 20, EnchantmentTarget.WEAPON, SWORD_OR_AXE, GROUP_ATTACK),
KNOCKBACK(19, "Knockback", 2, 5, 5, 20, 50, false, EnchantmentTarget.WEAPON),
FIRE_ASPECT(20, "Fire Aspect", 2, 2, 10, 20, 50, false, EnchantmentTarget.WEAPON),
LOOT_BONUS_MOBS(21, "Looting", 3, 2, 15, 9, 50, false, EnchantmentTarget.WEAPON),
DIG_SPEED(32, "Efficiency", 5, 10, 1, 10, 50, false, EnchantmentTarget.TOOL, DIGGING_TOOLS),
SILK_TOUCH(33, "Silk Touch", 1, 1, 15, 0, 50, false, EnchantmentTarget.TOOL, DIGGING_TOOLS, GROUP_DIG),
DURABILITY(34, "Unbreaking", 3, 5, 5, 8, 50, false, EnchantmentTarget.TOOL, ALL_THINGS),
LOOT_BONUS_BLOCKS(35, "Fortune", 3, 2, 15, 9, 50, EnchantmentTarget.TOOL, BASE_TOOLS, GROUP_DIG),
ARROW_DAMAGE(48, "Power", 5, 10, 1, 10, 15, EnchantmentTarget.BOW),
ARROW_KNOCKBACK(49, "Punch", 2, 2, 12, 20, 25, EnchantmentTarget.BOW),
ARROW_FIRE(50, "Flame", 1, 2, 20, 0, 30, EnchantmentTarget.BOW),
ARROW_INFINITE(51, "Infinity", 1, 1, 20, 0, 30, EnchantmentTarget.BOW),
LUCK(61, "Luck of the Sea", 3, 2, 15, 9, 50, false, EnchantmentTarget.FISHING_ROD),
LURE(62, "Lure", 3, 2, 15, 9, 50, false, EnchantmentTarget.FISHING_ROD);
private final int id;
private final String name;
private final int maxLevel;
private final EnchantmentTarget target;
private final MaterialMatcher matcher;
private final int group;
private final int weight;
private final int minValue, minIncrement;
private final int maxIncrement;
private final boolean simpleRange;
Impl(int id, String name, int max, int weight, int minValue, int minInc, int maxInc, EnchantmentTarget target) {
this(id, name, max, weight, minValue, minInc, maxInc, true, target);
}
Impl(int id, String name, int max, int weight, int minValue, int minInc, int maxInc, boolean simpleRange, EnchantmentTarget target) {
this(id, name, max, weight, minValue, minInc, maxInc, simpleRange, target, new MatcherAdapter(target), GROUP_NONE);
}
Impl(int id, String name, int max, int weight, int minValue, int minInc, int maxInc, EnchantmentTarget target, int group) {
this(id, name, max, weight, minValue, minInc, maxInc, true, target, new MatcherAdapter(target), group);
}
Impl(int id, String name, int max, int weight, int minValue, int minInc, int maxInc, boolean simpleRange, EnchantmentTarget target, MaterialMatcher matcher) {
this(id, name, max, weight, minValue, minInc, maxInc, simpleRange, target, matcher, GROUP_NONE);
}
Impl(int id, String name, int max, int weight, int minValue, int minInc, int maxInc, boolean simpleRange, EnchantmentTarget target, MatcherAdapter matcher) {
this(id, name, max, weight, minValue, minInc, maxInc, simpleRange, target, matcher, GROUP_NONE);
}
Impl(int id, String name, int max, int weight, int minValue, int minInc, int maxInc, EnchantmentTarget target, MaterialMatcher matcher, int group) {
this(id, name, max, weight, minValue, minInc, maxInc, true, target, matcher, group);
}
Impl(int id, String name, int max, int weight, int minValue, int minInc, int maxInc, boolean simpleRange, EnchantmentTarget target, MaterialMatcher matcher, int group) {
this.id = id;
this.name = name;
this.maxLevel = max;
this.weight = weight;
this.target = target;
this.matcher = matcher;
this.group = group;
this.minValue = minValue;
this.minIncrement = minInc;
this.maxIncrement = maxInc;
this.simpleRange = simpleRange;
}
int getMinRange(int modifier) {
modifier = modifier - 1; // Formula depends on input 1 being 0 for "no offset"
return (minIncrement * modifier) + minValue;
}
int getMaxRange(int modifier) {
return (simpleRange ? getMinRange(modifier) : 1 + modifier * 10) + maxIncrement;
}
}
private static class MatcherAdapter implements MaterialMatcher {
private final EnchantmentTarget target;
public MatcherAdapter(EnchantmentTarget target) {
this.target = target;
}
@Override
public boolean matches(Material material) {
return target.includes(material);
}
}
}