Files
Terra/src/main/java/com/dfsek/terra/Terra.java
2020-12-10 00:25:15 -07:00

212 lines
9.7 KiB
Java

package com.dfsek.terra;
import com.dfsek.tectonic.loading.TypeRegistry;
import com.dfsek.terra.api.bukkit.BukkitWorldHandle;
import com.dfsek.terra.api.generic.TerraPlugin;
import com.dfsek.terra.api.generic.world.WorldHandle;
import com.dfsek.terra.biome.grid.master.TerraBiomeGrid;
import com.dfsek.terra.biome.palette.PaletteHolder;
import com.dfsek.terra.biome.palette.PaletteLayer;
import com.dfsek.terra.carving.CarverPalette;
import com.dfsek.terra.command.TerraCommand;
import com.dfsek.terra.command.structure.LocateCommand;
import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.config.base.PluginConfig;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.config.loaders.ImageLoaderLoader;
import com.dfsek.terra.config.loaders.MaterialSetLoader;
import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader;
import com.dfsek.terra.config.loaders.RangeLoader;
import com.dfsek.terra.config.loaders.config.FloraLayerLoader;
import com.dfsek.terra.config.loaders.config.GridSpawnLoader;
import com.dfsek.terra.config.loaders.config.NoiseBuilderLoader;
import com.dfsek.terra.config.loaders.config.OreConfigLoader;
import com.dfsek.terra.config.loaders.config.OreHolderLoader;
import com.dfsek.terra.config.loaders.config.StructureFeatureLoader;
import com.dfsek.terra.config.loaders.config.TreeLayerLoader;
import com.dfsek.terra.config.loaders.palette.CarverPaletteLoader;
import com.dfsek.terra.config.loaders.palette.PaletteHolderLoader;
import com.dfsek.terra.config.loaders.palette.PaletteLayerLoader;
import com.dfsek.terra.debug.Debug;
import com.dfsek.terra.generation.TerraChunkGenerator;
import com.dfsek.terra.generation.config.NoiseBuilder;
import com.dfsek.terra.generation.items.flora.FloraLayer;
import com.dfsek.terra.generation.items.flora.TerraFlora;
import com.dfsek.terra.generation.items.ores.Ore;
import com.dfsek.terra.generation.items.ores.OreConfig;
import com.dfsek.terra.generation.items.ores.OreHolder;
import com.dfsek.terra.generation.items.tree.TreeLayer;
import com.dfsek.terra.image.ImageLoader;
import com.dfsek.terra.listeners.EventListener;
import com.dfsek.terra.listeners.SpigotListener;
import com.dfsek.terra.procgen.GridSpawn;
import com.dfsek.terra.registry.ConfigRegistry;
import com.dfsek.terra.structure.features.Feature;
import com.dfsek.terra.util.MaterialSet;
import com.dfsek.terra.util.PaperUtil;
import com.dfsek.terra.util.StructureTypeEnum;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.EntityType;
import org.bukkit.generator.ChunkGenerator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.polydev.gaea.GaeaPlugin;
import org.polydev.gaea.generation.GaeaChunkGenerator;
import org.polydev.gaea.lang.Language;
import org.polydev.gaea.math.ProbabilityCollection;
import org.polydev.gaea.math.Range;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class Terra extends GaeaPlugin implements TerraPlugin {
private final Map<String, TerraChunkGenerator> generatorMap = new HashMap<>();
private final Map<World, TerraWorld> worldMap = new HashMap<>();
private final Map<String, ConfigPack> worlds = new HashMap<>();
private final ConfigRegistry registry = new ConfigRegistry();
private final PluginConfig config = new PluginConfig();
private WorldHandle handle = new BukkitWorldHandle();
public void reload() {
Map<World, TerraWorld> newMap = new HashMap<>();
worldMap.forEach((world, tw) -> {
String packID = tw.getConfig().getTemplate().getID();
newMap.put(world, new TerraWorld(world, registry.get(packID)));
});
worldMap.clear();
worldMap.putAll(newMap);
}
public void setHandle(WorldHandle handle) {
getLogger().warning("|-------------------------------------------------------|");
getLogger().warning("A third-party addon has injected a custom WorldHandle!");
getLogger().warning("If you encounter issues, try *without* the addon before");
getLogger().warning("reporting to Terra. Report issues with the addon to the");
getLogger().warning("addon's maintainers!");
getLogger().warning("|-------------------------------------------------------|");
this.handle = handle;
}
@Override
public void onDisable() {
TerraChunkGenerator.saveAll();
}
@Override
public void onEnable() {
Debug.setLogger(getLogger()); // Set debug logger.
saveDefaultConfig();
Metrics metrics = new Metrics(this, 9017); // Set up bStats.
metrics.addCustomChart(new Metrics.SingleLineChart("worlds", worldMap::size)); // World number chart.
config.load(this); // Load master config.yml
LangUtil.load(config.getLanguage(), this); // Load language.
Debug.setDebug(isDebug());
registry.loadAll(this); // Load all config packs.
PluginCommand c = Objects.requireNonNull(getCommand("terra"));
TerraCommand command = new TerraCommand(this); // Set up main Terra command.
c.setExecutor(command);
c.setTabCompleter(command);
LocateCommand locate = new LocateCommand(command, false);
PluginCommand locatePl = Objects.requireNonNull(getCommand("locate"));
locatePl.setExecutor(locate); // Override locate command. Once Paper accepts StructureLocateEvent this will be unneeded on Paper implementations.
locatePl.setTabCompleter(locate);
long save = config.getDataSaveInterval();
Bukkit.getScheduler().runTaskTimerAsynchronously(this, TerraChunkGenerator::saveAll, save, save); // Schedule population data saving
Bukkit.getPluginManager().registerEvents(new EventListener(this), this); // Register master event listener
Bukkit.getPluginManager().registerEvents(new SpigotListener(this), this); // Register Spigot event listener, once Paper accepts StructureLocateEvent PR Spigot and Paper events will be separate.
PaperUtil.checkPaper(this);
}
@Override
public @Nullable ChunkGenerator getDefaultWorldGenerator(@NotNull String worldName, @Nullable String id) {
return generatorMap.computeIfAbsent(worldName, name -> {
if(!registry.contains(id)) throw new IllegalArgumentException("No such config pack \"" + id + "\"");
worlds.put(worldName, registry.get(id));
return new TerraChunkGenerator(registry.get(id), this);
});
}
@Override
public boolean isDebug() {
return config.isDebug();
}
@Override
public Class<? extends GaeaChunkGenerator> getGeneratorClass() {
return TerraChunkGenerator.class;
}
@Override
public Language getLanguage() {
return LangUtil.getLanguage();
}
public void registerAllLoaders(TypeRegistry registry) {
registry.registerLoader(ProbabilityCollection.class, new ProbabilityCollectionLoader())
.registerLoader(Range.class, new RangeLoader())
.registerLoader(CarverPalette.class, new CarverPaletteLoader())
.registerLoader(GridSpawn.class, new GridSpawnLoader())
.registerLoader(PaletteHolder.class, new PaletteHolderLoader())
.registerLoader(PaletteLayer.class, new PaletteLayerLoader())
.registerLoader(Biome.class, (t, o, l) -> Biome.valueOf((String) o))
.registerLoader(BlockData.class, (t, o, l) -> Bukkit.createBlockData((String) o))
.registerLoader(Material.class, (t, o, l) -> Material.matchMaterial((String) o))
.registerLoader(FloraLayer.class, new FloraLayerLoader())
.registerLoader(Ore.Type.class, (t, o, l) -> Ore.Type.valueOf((String) o))
.registerLoader(OreConfig.class, new OreConfigLoader())
.registerLoader(NoiseBuilder.class, new NoiseBuilderLoader())
.registerLoader(TreeLayer.class, new TreeLayerLoader(this))
.registerLoader(MaterialSet.class, new MaterialSetLoader())
.registerLoader(OreHolder.class, new OreHolderLoader())
.registerLoader(Feature.class, new StructureFeatureLoader())
.registerLoader(ImageLoader.class, new ImageLoaderLoader())
.registerLoader(EntityType.class, (t, o, l) -> EntityType.valueOf((String) o))
.registerLoader(TerraBiomeGrid.Type.class, (t, o, l) -> TerraBiomeGrid.Type.valueOf((String) o))
.registerLoader(StructureTypeEnum.class, (t, o, l) -> StructureTypeEnum.valueOf((String) o))
.registerLoader(ImageLoader.Channel.class, (t, o, l) -> ImageLoader.Channel.valueOf((String) o))
.registerLoader(ImageLoader.Align.class, (t, o, l) -> ImageLoader.Align.valueOf((String) o))
.registerLoader(TerraFlora.Search.class, (t, o, l) -> TerraFlora.Search.valueOf((String) o));
}
public ConfigRegistry getRegistry() {
return registry;
}
public TerraWorld getWorld(World w) {
if(!(w.getGenerator() instanceof TerraChunkGenerator)) throw new IllegalArgumentException("Not a Terra world!");
if(!worlds.containsKey(w.getName())) {
getLogger().warning("Unexpected world load detected: \"" + w.getName() + "\"");
return new TerraWorld(w, ((TerraChunkGenerator) w.getGenerator()).getConfigPack());
}
return worldMap.computeIfAbsent(w, world -> new TerraWorld(w, worlds.get(w.getName())));
}
@NotNull
public PluginConfig getTerraConfig() {
return config;
}
@Override
public WorldHandle getHandle() {
return handle;
}
}