diff --git a/src/main/java/com/garbagemule/MobArena/waves/WaveManager.java b/src/main/java/com/garbagemule/MobArena/waves/WaveManager.java index 1a91606..5e8fd3c 100644 --- a/src/main/java/com/garbagemule/MobArena/waves/WaveManager.java +++ b/src/main/java/com/garbagemule/MobArena/waves/WaveManager.java @@ -2,7 +2,6 @@ package com.garbagemule.MobArena.waves; import com.garbagemule.MobArena.framework.Arena; import com.garbagemule.MobArena.waves.enums.WaveBranch; -import com.garbagemule.MobArena.waves.enums.WaveError; import org.bukkit.configuration.ConfigurationSection; import java.util.SortedSet; @@ -48,13 +47,18 @@ public class WaveManager finalWave = section.getParent().getInt("settings.final-wave", 0); if (recurrentWaves.isEmpty()) { - arena.getPlugin().getLogger().warning(WaveError.NO_RECURRENT_WAVES.format(arena.configName())); - - Wave def = WaveParser.createDefaultWave(); - recurrentWaves.add(def); + if (singleWaves.isEmpty()) { + arena.getPlugin().getLogger().warning("Found no waves for arena " + arena.configName() + ", using default wave."); + } else { + arena.getPlugin().getLogger().info("Found no 'recurrent' waves for arena " + arena.configName() + ", using default wave."); + } + defaultWave = WaveParser.createDefaultWave(); + } else { + if (singleWaves.isEmpty()) { + arena.getPlugin().getLogger().info("Found no 'single' waves for arena " + arena.configName()); + } + defaultWave = recurrentWaves.first(); } - - defaultWave = recurrentWaves.first(); } /** diff --git a/src/main/java/com/garbagemule/MobArena/waves/WaveParser.java b/src/main/java/com/garbagemule/MobArena/waves/WaveParser.java index 6e4c746..7459116 100644 --- a/src/main/java/com/garbagemule/MobArena/waves/WaveParser.java +++ b/src/main/java/com/garbagemule/MobArena/waves/WaveParser.java @@ -13,7 +13,6 @@ import com.garbagemule.MobArena.waves.ability.AbilityManager; import com.garbagemule.MobArena.waves.enums.BossHealth; import com.garbagemule.MobArena.waves.enums.SwarmAmount; import com.garbagemule.MobArena.waves.enums.WaveBranch; -import com.garbagemule.MobArena.waves.enums.WaveError; import com.garbagemule.MobArena.waves.enums.WaveGrowth; import com.garbagemule.MobArena.waves.enums.WaveType; import com.garbagemule.MobArena.waves.types.BossWave; @@ -33,7 +32,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; @@ -48,14 +46,12 @@ public class WaveParser // If the config is null, return the empty set. if (config == null) { - arena.getPlugin().getLogger().warning(WaveError.BRANCH_MISSING.format(branch.toString().toLowerCase(), arena.configName())); return result; } // If no waves were found, return the empty set. Set waves = config.getKeys(false); if (waves == null) { - arena.getPlugin().getLogger().warning(WaveError.BRANCH_MISSING.format(branch.toString().toLowerCase(), arena.configName())); return result; } @@ -63,12 +59,6 @@ public class WaveParser for (String wave : waves) { ConfigurationSection waveSection = config.getConfigurationSection(wave); Wave w = parseWave(arena, wave, waveSection, branch); - - // Only add properly parsed waves. - if (w == null) { - continue; - } - result.add(w); } @@ -81,8 +71,7 @@ public class WaveParser WaveType type = WaveType.fromString(t); if (type == null) { - arena.getPlugin().getLogger().warning(WaveError.INVALID_TYPE.format(t, name, arena.configName())); - return null; + throw new ConfigError("Invalid wave type for wave " + name + " of arena " + arena.configName() + ": " + t); } // Prepare the result @@ -110,12 +99,6 @@ public class WaveParser break; } - // Check that the result isn't null - if (result == null) { - arena.getPlugin().getLogger().warning(WaveError.INVALID_WAVE.format(name, arena.configName())); - return null; - } - // Grab the branch-specific nodes. int priority = config.getInt("priority", -1); int frequency = config.getInt("frequency", -1); @@ -139,12 +122,15 @@ public class WaveParser List effects = getPotionEffects(arena, name, config); // Recurrent must have priority + frequency, single must have firstWave - if (branch == WaveBranch.RECURRENT && (priority == -1 || frequency <= 0)) { - arena.getPlugin().getLogger().warning(WaveError.RECURRENT_NODES.format(name, arena.configName())); - return null; + if (branch == WaveBranch.RECURRENT) { + if (priority <= 0) { + throw new ConfigError("Missing or invalid 'priority' node for recurrent wave " + name + " of arena " + arena.configName()); + } + if (frequency <= 0) { + throw new ConfigError("Missing or invalid 'frequency' node for recurrent wave " + name + " of arena " + arena.configName()); + } } else if (branch == WaveBranch.SINGLE && firstWave <= 0) { - arena.getPlugin().getLogger().warning(WaveError.SINGLE_NODES.format(name, arena.configName())); - return null; + throw new ConfigError("Missing or invalid 'wave' node for single wave " + name + " of arena " + arena.configName()); } // Set the important required values. @@ -169,11 +155,7 @@ public class WaveParser private static Wave parseDefaultWave(Arena arena, String name, ConfigurationSection config) { // Grab the monster map. - SortedMap monsters = getMonsterMap(config); - if (monsters == null || monsters.isEmpty()) { - arena.getPlugin().getLogger().warning(WaveError.MONSTER_MAP_MISSING.format(name, arena.configName())); - return null; - } + SortedMap monsters = getMonsterMap(arena, name, config); // Create the wave. DefaultWave result = new DefaultWave(monsters); @@ -186,53 +168,72 @@ public class WaveParser } // Grab the WaveGrowth - String grw = config.getString("growth"); - WaveGrowth growth = WaveGrowth.fromString(grw); - result.setGrowth(growth); + String grw = config.getString("growth", null); + if (grw != null && !grw.isEmpty()) { + try { + WaveGrowth growth = WaveGrowth.valueOf(grw.toUpperCase()); + result.setGrowth(growth); + } catch (IllegalArgumentException e) { + throw new ConfigError("Failed to parse wave growth for wave " + name + " of arena " + arena.configName() + ": " + grw); + } + } else { + result.setGrowth(WaveGrowth.MEDIUM); + } return result; } private static Wave parseSpecialWave(Arena arena, String name, ConfigurationSection config) { - SortedMap monsters = getMonsterMap(config); - if (monsters == null || monsters.isEmpty()) { - arena.getPlugin().getLogger().warning(WaveError.MONSTER_MAP_MISSING.format(name, arena.configName())); - return null; - } + SortedMap monsters = getMonsterMap(arena, name, config); - SpecialWave result = new SpecialWave(monsters); - return result; + return new SpecialWave(monsters); } private static Wave parseSwarmWave(Arena arena, String name, ConfigurationSection config) { - MACreature monster = getSingleMonster(config); - if (monster == null) { - arena.getPlugin().getLogger().warning(WaveError.SINGLE_MONSTER_MISSING.format(name, arena.configName())); - return null; - } + MACreature monster = getSingleMonster(arena, name, config); SwarmWave result = new SwarmWave(monster); // Grab SwarmAmount - String amnt = config.getString("amount"); - SwarmAmount amount = SwarmAmount.fromString(amnt); - result.setAmount(amount); + String amnt = config.getString("amount", null); + if (amnt != null && !amnt.isEmpty()) { + try { + SwarmAmount amount = SwarmAmount.valueOf(amnt.toUpperCase()); + result.setAmount(amount); + } catch (IllegalArgumentException e) { + throw new ConfigError("Failed to parse wave amount for wave " + name + " of arena " + arena.configName() + ": " + amnt); + } + } else { + result.setAmount(SwarmAmount.LOW); + } return result; } private static Wave parseSupplyWave(Arena arena, String name, ConfigurationSection config) { - SortedMap monsters = getMonsterMap(config); - if (monsters == null || monsters.isEmpty()) { - arena.getPlugin().getLogger().warning(WaveError.MONSTER_MAP_MISSING.format(name, arena.configName())); - return null; - } + SortedMap monsters = getMonsterMap(arena, name, config); SupplyWave result = new SupplyWave(monsters); // Grab the loot. - String loot = config.getString("drops"); - List stacks = ItemParser.parseItems(loot); + List loot = config.getStringList("drops"); + if (loot == null || loot.isEmpty()) { + String value = config.getString("drops", null); + if (value == null) { + throw new ConfigError("Missing 'drops' node for wave " + name + " of arena " + arena.configName()); + } + loot = Arrays.asList(value.split(",")); + } + List stacks = loot.stream() + .map(String::trim) + .map(value -> { + ItemStack stack = ItemParser.parseItem(value, false); + if (stack == null) { + throw new ConfigError("Failed to parse loot for wave " + name + " of arena " + arena.configName() + ": " + value); + } + return stack; + }) + .collect(Collectors.toList()); result.setDropList(stacks); return result; @@ -241,72 +242,69 @@ public class WaveParser private static Wave parseUpgradeWave(Arena arena, String name, ConfigurationSection config) { ThingManager thingman = arena.getPlugin().getThingManager(); Map> upgrades = getUpgradeMap(config, name, arena, thingman); - if (upgrades == null || upgrades.isEmpty()) { - arena.getPlugin().getLogger().warning(WaveError.UPGRADE_MAP_MISSING.format(name, arena.configName())); - return null; - } + return new UpgradeWave(upgrades); } private static Wave parseBossWave(Arena arena, String name, ConfigurationSection config) { - MACreature monster = getSingleMonster(config); - if (monster == null) { - arena.getPlugin().getLogger().warning(WaveError.SINGLE_MONSTER_MISSING.format(name, arena.configName())); - return null; - } + MACreature monster = getSingleMonster(arena, name, config); BossWave result = new BossWave(monster); // Check if there's a specific boss name - String bossName = config.getString("name"); - if (bossName != null && !bossName.equals("")) { + String bossName = config.getString("name", null); + if (bossName != null && !bossName.isEmpty()) { result.setBossName(bossName); } // Grab the boss health - String healthString = config.getString("health"); - if (healthString == null) { - String warning = "No health value found for boss '%s' in arena '%s'. Defaulting to medium."; - arena.getPlugin().getLogger().warning(String.format(warning, name, arena.configName())); - result.setHealth(BossHealth.MEDIUM); - } else { - BossHealth health = BossHealth.fromString(healthString); - if (health != null) { + String healthString = config.getString("health", null); + if (healthString != null && !healthString.isEmpty()) { + try { + BossHealth health = BossHealth.valueOf(healthString.toUpperCase()); result.setHealth(health); - } else { - int flatHealth = config.getInt("health", 0); - if (flatHealth <= 0) { - String warning = "Unable to parse health of boss '%s' in arena '%s'. Defaulting to medium. Value was '%s'"; - arena.getPlugin().getLogger().warning(String.format(warning, name, arena.configName(), healthString)); - result.setHealth(BossHealth.MEDIUM); - } else { - result.setFlatHealth(flatHealth); + } catch (IllegalArgumentException e) { + int flatHealth = config.getInt("health", -1); + if (flatHealth < 0) { + throw new ConfigError("Failed to parse boss health for wave " + name + " of arena " + arena.configName() + ": " + healthString); } + result.setFlatHealth(flatHealth); } + } else { + result.setHealth(BossHealth.MEDIUM); } // And the abilities. - String ablts = config.getString("abilities"); - if (ablts != null) { - String[] parts = ablts.split(","); - for (String ability : parts) { - Ability a = AbilityManager.getAbility(ability.trim()); - if (a == null) { - arena.getPlugin().getLogger().warning(WaveError.BOSS_ABILITY.format(ability.trim(), name, arena.configName())); - continue; - } - - result.addBossAbility(a); + List abilities = config.getStringList("abilities"); + if (abilities == null || abilities.isEmpty()) { + String value = config.getString("abilities", null); + if (value == null) { + abilities = Collections.emptyList(); + } else { + abilities = Arrays.asList(value.split(",")); } } + if (abilities.isEmpty()) { + arena.getPlugin().getLogger().warning("No boss abilities for boss wave " + name + " of arena " + arena.configName()); + } + abilities.stream() + .map(String::trim) + .map(value -> { + Ability ability = AbilityManager.getAbility(value); + if (ability == null) { + throw new ConfigError("Failed to parse boss ability for boss wave " + name + " of arena " + arena.configName() + ": " + value); + } + return ability; + }) + .forEach(result::addBossAbility); // As well as the ability interval and ability announce. result.setAbilityInterval(config.getInt("ability-interval", 3) * 20); result.setAbilityAnnounce(config.getBoolean("ability-announce", true)); // Rewards! - String rew = config.getString("reward"); - if (rew != null) { + String rew = config.getString("reward", null); + if (rew != null && !rew.isEmpty()) { try { Thing thing = arena.getPlugin().getThingManager().parse(rew.trim()); result.setReward(thing); @@ -316,9 +314,26 @@ public class WaveParser } // Drops! - String drp = config.getString("drops"); - List drops = ItemParser.parseItems(drp); - result.setDrops(drops); + List drops = config.getStringList("drops"); + if (drops == null || drops.isEmpty()) { + String value = config.getString("drops", null); + if (value == null) { + drops = Collections.emptyList(); + } else { + drops = Arrays.asList(value.split(",")); + } + } + List stacks = drops.stream() + .map(String::trim) + .map(value -> { + ItemStack stack = ItemParser.parseItem(value, false); + if (stack == null) { + throw new ConfigError("Failed to parse boss drop in wave " + name + " of arena " + arena.configName() + ": " + value); + } + return stack; + }) + .collect(Collectors.toList()); + result.setDrops(stacks); return result; } @@ -329,13 +344,16 @@ public class WaveParser * @param config a ConfigSection * @return an MACreature, if the monster node contains one that is valid */ - private static MACreature getSingleMonster(ConfigurationSection config) { - String monster = config.getString("monster"); - if (monster == null) { - return null; + private static MACreature getSingleMonster(Arena arena, String name, ConfigurationSection config) { + String monster = config.getString("monster", null); + if (monster == null || monster.isEmpty()) { + throw new ConfigError("Missing 'monster' node for wave " + name + " of arena " + arena.configName()); } MACreature result = MACreature.fromString(monster); + if (result == null) { + throw new ConfigError("Failed to parse monster for wave " + name + " of arena " + arena.configName() + ": " + monster); + } return result; } @@ -345,15 +363,15 @@ public class WaveParser * @param config * @return a "reverse" map of monsters and numbers */ - private static SortedMap getMonsterMap(ConfigurationSection config) { + private static SortedMap getMonsterMap(Arena arena, String name, ConfigurationSection config) { ConfigurationSection section = config.getConfigurationSection("monsters"); if (section == null) { - return null; + throw new ConfigError("Missing 'monsters' node for wave " + name + " of arena " + arena.configName()); } Set monsters = section.getKeys(false); if (monsters == null || monsters.isEmpty()) { - return null; + throw new ConfigError("Empty 'monsters' node for wave " + name + " of arena " + arena.configName()); } // Prepare the map. @@ -364,10 +382,14 @@ public class WaveParser // Check all the monsters. for (String monster : monsters) { MACreature creature = MACreature.fromString(monster); - if (creature == null) continue; + if (creature == null) { + throw new ConfigError("Failed to parse monster for wave " + name + " of arena " + arena.configName() + ": " + monster); + } - int prob = config.getInt(path + monster, 0); - if (prob == 0) continue; + int prob = config.getInt(path + monster, -1); + if (prob < 0) { + throw new ConfigError("Failed to parse probability for monster " + monster + " in wave " + name + " of arena " + arena.configName()); + } sum += prob; monsterMap.put(sum, creature); @@ -377,29 +399,26 @@ public class WaveParser } private static List getSpawnpoints(Arena arena, String name, ConfigurationSection config) { - List result = new ArrayList<>(); - - String spawnString = config.getString("spawnpoints"); - if (spawnString == null) { - return result; + List spawnpoints = config.getStringList("spawnpoints"); + if (spawnpoints == null || spawnpoints.isEmpty()) { + String value = config.getString("spawnpoints", null); + if (value == null || value.isEmpty()) { + return Collections.emptyList(); + } + spawnpoints = Arrays.asList(value.split(";")); } - // Split the string by semicolons - String[] spawns = spawnString.split(";"); - ArenaRegion region = arena.getRegion(); - for (String spawn : spawns) { - Location spawnpoint = region.getSpawnpoint(spawn.trim()); - - if (spawnpoint == null) { - arena.getPlugin().getLogger().warning("Spawnpoint '" + spawn + "' in wave '" + name + "' for arena '" + arena.configName() + "' could not be parsed!"); - continue; - } - - result.add(spawnpoint); - } - - return result; + return spawnpoints.stream() + .map(String::trim) + .map(value -> { + Location spawnpoint = region.getSpawnpoint(value); + if (spawnpoint == null) { + throw new ConfigError("Spawnpoint '" + value + "' in wave '" + name + "' for arena '" + arena.configName() + "' could not be parsed!"); + } + return spawnpoint; + }) + .collect(Collectors.toList()); } private static List getPotionEffects(Arena arena, String name, ConfigurationSection config) { @@ -439,12 +458,12 @@ public class WaveParser private static Map> getUpgradeMap(ConfigurationSection config, String name, Arena arena, ThingManager thingman) { ConfigurationSection section = config.getConfigurationSection("upgrades"); if (section == null) { - return null; + throw new ConfigError("Missing 'upgrades' node for wave " + name + " of arena " + arena.configName()); } Set classes = section.getKeys(false); if (classes == null || classes.isEmpty()) { - return null; + throw new ConfigError("Empty 'upgrades' node for wave " + name + " of arena " + arena.configName()); } Map> upgrades = new HashMap<>(); diff --git a/src/main/java/com/garbagemule/MobArena/waves/enums/BossHealth.java b/src/main/java/com/garbagemule/MobArena/waves/enums/BossHealth.java index d7c0e35..9f6fbc0 100644 --- a/src/main/java/com/garbagemule/MobArena/waves/enums/BossHealth.java +++ b/src/main/java/com/garbagemule/MobArena/waves/enums/BossHealth.java @@ -1,7 +1,5 @@ package com.garbagemule.MobArena.waves.enums; -import com.garbagemule.MobArena.waves.WaveUtils; - public enum BossHealth { VERYLOW(4), LOW(8), MEDIUM(15), HIGH(25), VERYHIGH(40), PSYCHO(60); @@ -18,8 +16,4 @@ public enum BossHealth public int getMultiplier() { return multiplier; } - - public static BossHealth fromString(String string) { - return WaveUtils.getEnumFromString(BossHealth.class, string, null); - } } \ No newline at end of file diff --git a/src/main/java/com/garbagemule/MobArena/waves/enums/SwarmAmount.java b/src/main/java/com/garbagemule/MobArena/waves/enums/SwarmAmount.java index 086d7cb..dbbc8c4 100644 --- a/src/main/java/com/garbagemule/MobArena/waves/enums/SwarmAmount.java +++ b/src/main/java/com/garbagemule/MobArena/waves/enums/SwarmAmount.java @@ -1,7 +1,5 @@ package com.garbagemule.MobArena.waves.enums; -import com.garbagemule.MobArena.waves.WaveUtils; - public enum SwarmAmount { LOW(10), MEDIUM(20), HIGH(30), PSYCHO(60); @@ -14,8 +12,4 @@ public enum SwarmAmount public int getAmount(int playerCount) { return Math.max(1, playerCount / 2) * multiplier; } - - public static SwarmAmount fromString(String string) { - return WaveUtils.getEnumFromString(SwarmAmount.class, string, LOW); - } } \ No newline at end of file diff --git a/src/main/java/com/garbagemule/MobArena/waves/enums/WaveError.java b/src/main/java/com/garbagemule/MobArena/waves/enums/WaveError.java deleted file mode 100644 index 828142f..0000000 --- a/src/main/java/com/garbagemule/MobArena/waves/enums/WaveError.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.garbagemule.MobArena.waves.enums; - -public enum WaveError -{ - INVALID_WAVE("Wave '%s' for arena '%s' could not be parsed."), - NO_RECURRENT_WAVES("No valid recurrent waves found for arena '%s'. Check the config-file. Using implicit default wave."), - - BRANCH_MISSING("The '%s' branch for arena '%s' is empty. Check the config-file."), - INVALID_TYPE("Invalid type '%s' for wave '%s' in arena '%s'. Skipping..."), - - RECURRENT_NODES("Recurrent wave '%s' in arena '%s' is missing either the 'frequency' or the 'priority' node. Skipping..."), - SINGLE_NODES("Single wave '%s' in arena '%s' is missing the 'wave' node. Skipping..."), - - MONSTER_MAP_MISSING("Missing 'monsters' node for wave '%s' in arena '%s'."), - SINGLE_MONSTER_MISSING("Missing 'monster' node for wave '%s' in arena '%s'."), - - BOSS_ABILITY("Invalid boss ability '%s' for wave '%s' in arena '%s'."), - - SUPPLY_DROPS("Missing 'drops' node for wave '%s' in arena '%s'."), - - UPGRADE_MAP_MISSING("Missing 'upgrades' node for wave '%s' in arena '%s'."); - - private String msg; - - WaveError(String msg) { - this.msg = msg; - } - - public String format(Object... args) { - return String.format(msg, args); - } -} \ No newline at end of file diff --git a/src/main/java/com/garbagemule/MobArena/waves/enums/WaveGrowth.java b/src/main/java/com/garbagemule/MobArena/waves/enums/WaveGrowth.java index f34f7af..9b42da3 100644 --- a/src/main/java/com/garbagemule/MobArena/waves/enums/WaveGrowth.java +++ b/src/main/java/com/garbagemule/MobArena/waves/enums/WaveGrowth.java @@ -1,7 +1,5 @@ package com.garbagemule.MobArena.waves.enums; -import com.garbagemule.MobArena.waves.WaveUtils; - public enum WaveGrowth { OLD(0), SLOW(0.5), MEDIUM(0.65), FAST(0.8), PSYCHO(1.2); @@ -11,10 +9,6 @@ public enum WaveGrowth this.exp = exp; } - public static WaveGrowth fromString(String string) { - return WaveUtils.getEnumFromString(WaveGrowth.class, string, OLD); - } - public int getAmount(int wave, int playerCount) { if (this == OLD) return wave + playerCount; diff --git a/src/main/java/com/garbagemule/MobArena/waves/enums/WaveType.java b/src/main/java/com/garbagemule/MobArena/waves/enums/WaveType.java index dbfd47f..7babcd2 100644 --- a/src/main/java/com/garbagemule/MobArena/waves/enums/WaveType.java +++ b/src/main/java/com/garbagemule/MobArena/waves/enums/WaveType.java @@ -51,6 +51,10 @@ public enum WaveType public abstract void announce(Arena arena, int wave); public static WaveType fromString(String string) { - return WaveUtils.getEnumFromString(WaveType.class, string); + try { + return WaveType.valueOf(string.toUpperCase()); + } catch (IllegalArgumentException e) { + return null; + } } } \ No newline at end of file