Files
purpur-harvest/src/main/java/games/dmg/spigotharvest/HarvestSettings.java
T

180 lines
6.5 KiB
Java

package games.dmg.spigotharvest;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
/** Validated runtime configuration. */
public final class HarvestSettings {
private final int cropsPerTick;
private final int bossBarIdleTicks;
private final Map<CropType, HarvestProgression> progressions;
private final Set<GameMode> eligibleGameModes;
private final int titleFadeInTicks;
private final int titleStayTicks;
private final int titleFadeOutTicks;
public HarvestSettings(
int cropsPerTick,
int bossBarIdleTicks,
Map<CropType, HarvestProgression> progressions
) {
this(
cropsPerTick, bossBarIdleTicks, progressions, EnumSet.of(GameMode.SURVIVAL),
10, 70, 20
);
}
public HarvestSettings(
int cropsPerTick,
int bossBarIdleTicks,
Map<CropType, HarvestProgression> progressions,
Set<GameMode> eligibleGameModes,
int titleFadeInTicks,
int titleStayTicks,
int titleFadeOutTicks
) {
if (cropsPerTick <= 0 || cropsPerTick > 64) {
throw new IllegalArgumentException("crops-per-tick must be from 1 through 64");
}
if (bossBarIdleTicks < 0) {
throw new IllegalArgumentException("boss-bar-idle-ticks cannot be negative");
}
if (titleFadeInTicks < 0 || titleStayTicks < 0 || titleFadeOutTicks < 0) {
throw new IllegalArgumentException("title timing cannot be negative");
}
if (progressions.size() != CropType.values().length) {
throw new IllegalArgumentException("every supported crop requires progression settings");
}
if (eligibleGameModes.isEmpty()) {
throw new IllegalArgumentException("at least one eligible game mode is required");
}
this.cropsPerTick = cropsPerTick;
this.bossBarIdleTicks = bossBarIdleTicks;
this.progressions = new EnumMap<>(progressions);
this.eligibleGameModes = EnumSet.copyOf(eligibleGameModes);
this.titleFadeInTicks = titleFadeInTicks;
this.titleStayTicks = titleStayTicks;
this.titleFadeOutTicks = titleFadeOutTicks;
}
public static HarvestSettings defaults() {
return new HarvestSettings(1, 100, defaultProgressions());
}
public static Map<CropType, HarvestProgression> defaultProgressions() {
Map<CropType, HarvestProgression> values = new EnumMap<>(CropType.class);
for (CropType crop : CropType.values()) {
values.put(crop, HarvestProgression.defaults());
}
return values;
}
public static HarvestSettings from(ConfigurationSection configuration) {
int rate = configuration.getInt("crops-per-tick", 1);
int idleTicks = configuration.getInt("boss-bar-idle-ticks", 100);
Set<GameMode> modes = EnumSet.noneOf(GameMode.class);
for (String value : configuration.getStringList("eligible-game-modes")) {
try {
modes.add(GameMode.valueOf(value));
} catch (IllegalArgumentException exception) {
throw new IllegalArgumentException("unknown eligible game mode: " + value, exception);
}
}
if (modes.isEmpty() && !configuration.contains("eligible-game-modes")) {
modes.add(GameMode.SURVIVAL);
}
Map<CropType, HarvestProgression> paths = new EnumMap<>(CropType.class);
for (CropType crop : CropType.values()) {
String root = "crops." + crop.displayName();
validateCropDefinition(configuration, root, crop);
List<Long> requirements = configuration.getLongList(root + ".requirements");
List<Integer> caps = configuration.getIntegerList(root + ".caps");
if (requirements.isEmpty() && caps.isEmpty()) {
paths.put(crop, HarvestProgression.defaults());
} else {
paths.put(crop, new HarvestProgression(toLongArray(requirements), toIntArray(caps)));
}
}
return new HarvestSettings(
rate,
idleTicks,
paths,
modes,
configuration.getInt("title-fade-in-ticks", 10),
configuration.getInt("title-stay-ticks", 70),
configuration.getInt("title-fade-out-ticks", 20)
);
}
public int cropsPerTick() {
return cropsPerTick;
}
public int bossBarIdleTicks() {
return bossBarIdleTicks;
}
public HarvestProgression progression(CropType crop) {
return progressions.get(crop);
}
public boolean isEligible(GameMode gameMode) {
return eligibleGameModes.contains(gameMode);
}
public int titleFadeInTicks() {
return titleFadeInTicks;
}
public int titleStayTicks() {
return titleStayTicks;
}
public int titleFadeOutTicks() {
return titleFadeOutTicks;
}
private static void validateCropDefinition(
ConfigurationSection configuration,
String root,
CropType crop
) {
String blockName = configuration.getString(root + ".block-material");
String plantingName = configuration.getString(root + ".planting-material");
String maturity = configuration.getString(root + ".maturity");
if (blockName == null && plantingName == null && maturity == null) {
return;
}
Material block = blockName == null ? null : Material.matchMaterial(blockName);
Material planting = plantingName == null ? null : Material.matchMaterial(plantingName);
if (block != crop.blockMaterial() || planting != crop.plantingMaterial()) {
throw new IllegalArgumentException("invalid materials for crop " + crop.displayName());
}
if (!"maximum-age".equals(maturity)) {
throw new IllegalArgumentException("unsupported maturity rule for crop " + crop.displayName());
}
}
private static long[] toLongArray(List<Long> values) {
long[] result = new long[values.size()];
for (int index = 0; index < values.size(); index++) {
result[index] = values.get(index);
}
return result;
}
private static int[] toIntArray(List<Integer> values) {
int[] result = new int[values.size()];
for (int index = 0; index < values.size(); index++) {
result[index] = values.get(index);
}
return result;
}
}