180 lines
6.5 KiB
Java
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;
|
|
}
|
|
}
|