package de.tobiyas.racesandclasses.traitcontainer.interfaces.skills; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.regex.Pattern; import org.bukkit.Material; public class SkillLevelConfig { /** * The Map of level -> container. */ private final Map<Integer,SkillLevelContainer> levelContainers = new HashMap<>(); /** * Parses the List of Prequisits. * @param toParse to parse. */ public SkillLevelConfig(List<String> toParse) { if(toParse != null) parse(toParse); } public SkillLevelConfig() { this(null); } /** * Parses the List and compiles it. * @param toParse to parse. */ public void parse(List<String> toParse){ this.levelContainers.clear(); if(toParse == null || toParse.isEmpty()) return; for(String line : toParse){ SkillLevelContainer container = SkillLevelContainer.parse(line); if(container != null && !levelContainers.containsKey(container.getLevel())){ this.levelContainers.put(container.getLevel(), container); } } } /** * Returns the Points for the level passed. */ public int getPointsForLevel(int level){ if(levelContainers.isEmpty()) return 1; SkillLevelContainer nearest = getNearest(level); return nearest == null ? 1 : nearest.getPoints(); } /** * Returns the Cast cost for the level passed. */ public double getCastCostForLevel(int level, double defaultValue){ if(levelContainers.isEmpty()) return defaultValue; SkillLevelContainer nearest = getNearest(level); double cost = nearest == null ? defaultValue : nearest.getCastCost(); return cost < 0 ? defaultValue : cost; } /** * Returns the Cast cost for the level passed. */ public Material getCastMaterialForLevel(int level, Material defaultValue){ if(levelContainers.isEmpty()) return defaultValue; SkillLevelContainer nearest = getNearest(level); Material mat = nearest == null ? Material.AIR : nearest.getCastMaterial(); return mat == Material.AIR ? defaultValue : nearest.getCastMaterial(); } /** * Returns the Cast cost for the level passed. */ public short getCastMaterialDamageForLevel(int level, short defaultValue){ if(levelContainers.isEmpty()) return defaultValue; SkillLevelContainer nearest = getNearest(level); short damage = nearest == null ? defaultValue : nearest.getCastMaterialDamage(); return damage <= 0 ? defaultValue : damage; } /** * Returns the Cast material name for the level passed. */ public String getCastMaterialNameForLevel(int level, String defaultValue){ if(levelContainers.isEmpty()) return defaultValue; SkillLevelContainer nearest = getNearest(level); String name = nearest == null ? defaultValue : nearest.getCastMaterialName(); return name.isEmpty() ? defaultValue : name; } /** * Returns the Points for the level passed. */ public List<String> getTraitPreForLevel(int level){ if(levelContainers.isEmpty()) return new LinkedList<>(); SkillLevelContainer nearest = getNearest(level); return nearest == null ? new LinkedList<String>() : nearest.getPreTraits(); } /** * Returns the Points for the level passed. */ public int getMinLevel(int level){ if(levelContainers.isEmpty()) return 1; SkillLevelContainer nearest = getNearest(level); return nearest == null ? 1 : nearest.getMinLevel(); } /** * Returns the Nearest. * @param level to search. * @return the nearest. */ private SkillLevelContainer getNearest(int level){ SkillLevelContainer container = null; for(SkillLevelContainer c : levelContainers.values()){ int cLevel = c.getLevel(); int oldLevel = container == null ? 0 : container.getLevel(); if(cLevel > oldLevel && cLevel <= level) container = c; } return container; } private static class SkillLevelContainer { private final int level; private final int points; private final int minLevel; private final List<String> preTraits = new LinkedList<String>(); private final double castCost; private final Material castMaterial; private final short castMaterialDamage; private final String castMaterialName; public SkillLevelContainer(int level, int minLevel, int points, List<String> preTraits, double castCost, Material castMaterial, short castMaterialDamage, String castMaterialName) { super(); this.level = level; this.minLevel = minLevel; this.points = points; this.preTraits.addAll(preTraits); this.castCost = castCost; this.castMaterial = castMaterial; this.castMaterialDamage = castMaterialDamage; this.castMaterialName = castMaterialName; } public int getLevel() { return level; } public int getPoints() { return points; } public List<String> getPreTraits() { return preTraits; } public int getMinLevel() { return minLevel; } public double getCastCost() { return castCost; } public Material getCastMaterial() { return castMaterial; } public short getCastMaterialDamage() { return castMaterialDamage; } public String getCastMaterialName() { return castMaterialName; } /** * Parses the Line to a container. * @param line to use. * @return the SkillLevel container or null if not parseable. */ public static SkillLevelContainer parse(String line) { String[] split = line.split(Pattern.quote("#")); int skillLevel = 1; int minLevel = 1; int points = 1; List<String> preTraits = new LinkedList<>(); //Casting cost: int castingCost = -1; Material castingMaterial = Material.AIR; short castingMaterialDamage = -1; String castingMaterialName = ""; for(String part : split){ if(!part.contains(":")) continue; String[] parts = part.split(":", 2); String label = parts[0]; String config = parts[1]; if("level".equalsIgnoreCase(label)){ try{ skillLevel = Integer.parseInt(config); }catch(Throwable exp){} continue; } if("minlevel".equalsIgnoreCase(label)){ try{ minLevel = Integer.parseInt(config); }catch(Throwable exp){} continue; } if("points".equalsIgnoreCase(label)){ try{ points = Integer.parseInt(config); }catch(Throwable exp){} continue; } if("traits".equalsIgnoreCase(label)){ try{ String[] preSplit = config.split(Pattern.quote(";")); for(String pre : preSplit) preTraits.add(pre); }catch(Throwable exp){} continue; } //Casting stuff: if("castingCost".equalsIgnoreCase(label)){ try{ castingCost = Integer.parseInt(config); }catch(Throwable exp){} } if("castingMaterial".equalsIgnoreCase(label)){ castingMaterial = Material.matchMaterial(config); if(castingMaterial == null) castingMaterial = Material.AIR; } if("castingMaterialDamage".equalsIgnoreCase(label)){ try{ castingMaterialDamage = Short.parseShort(config); }catch(Throwable exp){} } if("castingMaterialName".equalsIgnoreCase(label)){ castingMaterialName = config; } } return new SkillLevelContainer( skillLevel, minLevel, points, preTraits, castingCost, castingMaterial, castingMaterialDamage, castingMaterialName); } } }