diff --git a/src/main/java/com/dfsek/terra/EventListener.java b/src/main/java/com/dfsek/terra/EventListener.java new file mode 100644 index 000000000..894675acf --- /dev/null +++ b/src/main/java/com/dfsek/terra/EventListener.java @@ -0,0 +1,39 @@ +package com.dfsek.terra; + +import com.dfsek.terra.async.AsyncStructureFinder; +import com.dfsek.terra.config.genconfig.StructureConfig; +import com.dfsek.terra.util.StructureTypeEnum; +import org.bukkit.entity.EnderSignal; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntitySpawnEvent; +import org.polydev.gaea.GaeaPlugin; + +public class EventListener implements Listener { + private final GaeaPlugin main; + + public EventListener(GaeaPlugin main) { + this.main = main; + } + @EventHandler(priority = EventPriority.NORMAL) + public void onEnderEye(EntitySpawnEvent e) { + Entity entity = e.getEntity(); + if(e.getEntityType().equals(EntityType.ENDER_SIGNAL)) { + Debug.info("Detected Ender Signal..."); + TerraWorld tw = TerraWorld.getWorld(e.getEntity().getWorld()); + EnderSignal signal = (EnderSignal) entity; + StructureConfig config = tw.getConfig().getLocatable().get(StructureTypeEnum.STRONGHOLD); + if(config!= null) { + Debug.info("Overriding Ender Signal..."); + AsyncStructureFinder finder = new AsyncStructureFinder(tw.getGrid(), config, e.getLocation(), 0, 500, location -> { + if(location != null) signal.setTargetLocation(location.toLocation(signal.getWorld())); + Debug.info("Location: " + location); + }); + finder.run(); // Do this synchronously so eye doesn't change direction several ticks after spawning. + } else main.getLogger().warning("No overrides are defined for Strongholds. Ender Signals will not work correctly."); + } + } +} diff --git a/src/main/java/com/dfsek/terra/Terra.java b/src/main/java/com/dfsek/terra/Terra.java index 117a859e8..8adab9176 100644 --- a/src/main/java/com/dfsek/terra/Terra.java +++ b/src/main/java/com/dfsek/terra/Terra.java @@ -51,7 +51,7 @@ public class Terra extends GaeaPlugin { saveDefaultConfig(); Bukkit.getScheduler().scheduleAsyncRepeatingTask(this, TerraChunkGenerator::saveAll, ConfigUtil.dataSave, ConfigUtil.dataSave); - + Bukkit.getPluginManager().registerEvents(new EventListener(this), this); } @Override diff --git a/src/main/java/com/dfsek/terra/async/AsyncStructureFinder.java b/src/main/java/com/dfsek/terra/async/AsyncStructureFinder.java index d8b6cc917..e7e8e1121 100644 --- a/src/main/java/com/dfsek/terra/async/AsyncStructureFinder.java +++ b/src/main/java/com/dfsek/terra/async/AsyncStructureFinder.java @@ -13,6 +13,7 @@ import org.bukkit.entity.Player; import org.bukkit.util.Vector; import java.util.Random; +import java.util.function.Consumer; /** * Runnable to locate structures asynchronously @@ -20,26 +21,24 @@ import java.util.Random; public class AsyncStructureFinder implements Runnable { private final TerraBiomeGrid grid; private final StructureConfig target; - private final Player p; private final int startRadius; private final int maxRadius; - private final boolean tp; private final int centerX; private final int centerZ; private final long seed; private final World world; + private final Consumer callback; - public AsyncStructureFinder(TerraBiomeGrid grid, StructureConfig target, Player p, int startRadius, int maxRadius, boolean tp) { + public AsyncStructureFinder(TerraBiomeGrid grid, StructureConfig target, Location origin, int startRadius, int maxRadius, Consumer callback) { this.grid = grid; this.target = target; - this.p = p; this.startRadius = startRadius; this.maxRadius = maxRadius; - this.tp = tp; - this.centerX = p.getLocation().getBlockX(); - this.centerZ = p.getLocation().getBlockZ(); - this.seed = p.getWorld().getSeed(); - this.world = p.getWorld(); + this.centerX = origin.getBlockX(); + this.centerZ = origin.getBlockZ(); + this.world = origin.getWorld(); + this.seed = world.getSeed(); + this.callback = callback; } @Override @@ -47,7 +46,7 @@ public class AsyncStructureFinder implements Runnable { int x = centerX; int z = centerZ; - int wid = target.getSpawn().getWidth() + 2*target.getSpawn().getSeparation(); + final int wid = target.getSpawn().getWidth() + 2*target.getSpawn().getSeparation(); x/=wid; z/=wid; @@ -77,17 +76,8 @@ public class AsyncStructureFinder implements Runnable { run++; toggle = !toggle; } - if(p.isOnline()) { - if(found) { - p.sendMessage("Located structure at (" + spawn.getBlockX() + ", " + spawn.getBlockZ() + ")."); - if(tp) { - int finalX = spawn.getBlockX(); - int finalZ = spawn.getBlockZ(); - Bukkit.getScheduler().runTask(Terra.getInstance(), () -> p.teleport(new Location(p.getWorld(), finalX, p.getLocation().getY(), finalZ))); - } - } - else p.sendMessage("Unable to locate structure. " + spawn); - } + final Vector finalSpawn = found ? spawn: null; + Bukkit.getScheduler().runTask(Terra.getInstance(), () -> callback.accept(finalSpawn)); } /** diff --git a/src/main/java/com/dfsek/terra/command/structure/LocateCommand.java b/src/main/java/com/dfsek/terra/command/structure/LocateCommand.java index e9a00fb06..a5ef6d2ba 100644 --- a/src/main/java/com/dfsek/terra/command/structure/LocateCommand.java +++ b/src/main/java/com/dfsek/terra/command/structure/LocateCommand.java @@ -7,6 +7,7 @@ import com.dfsek.terra.config.genconfig.StructureConfig; import com.dfsek.terra.config.lang.LangUtil; import com.dfsek.terra.generation.TerraChunkGenerator; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.World; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; @@ -42,7 +43,19 @@ public class LocateCommand extends WorldCommand { LangUtil.send("command.structure.invalid", sender, id); return true; } - Bukkit.getScheduler().runTaskAsynchronously(Terra.getInstance(), new AsyncStructureFinder(TerraWorld.getWorld(world).getGrid(), s, sender, 0, maxRadius, tp)); + Bukkit.getScheduler().runTaskAsynchronously(Terra.getInstance(), new AsyncStructureFinder(TerraWorld.getWorld(world).getGrid(), s, sender.getLocation(), 0, maxRadius, (location) -> { + if(sender.isOnline()) { + if(location != null) { + sender.sendMessage("Located structure at (" + location.getBlockX() + ", " + location.getBlockZ() + ")."); + if(tp) { + int finalX = location.getBlockX(); + int finalZ = location.getBlockZ(); + Bukkit.getScheduler().runTask(Terra.getInstance(), () -> sender.teleport(new Location(sender.getWorld(), finalX, sender.getLocation().getY(), finalZ))); + } + } + else sender.sendMessage("Unable to locate structure. "); + } + })); return true; } diff --git a/src/main/java/com/dfsek/terra/config/base/ConfigPack.java b/src/main/java/com/dfsek/terra/config/base/ConfigPack.java index f12a574c1..f01768403 100644 --- a/src/main/java/com/dfsek/terra/config/base/ConfigPack.java +++ b/src/main/java/com/dfsek/terra/config/base/ConfigPack.java @@ -4,6 +4,7 @@ import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.carving.UserDefinedCarver; import com.dfsek.terra.config.ConfigLoader; import com.dfsek.terra.config.exception.ConfigException; +import com.dfsek.terra.config.exception.NotFoundException; import com.dfsek.terra.config.genconfig.TreeConfig; import com.dfsek.terra.config.genconfig.biome.AbstractBiomeConfig; import com.dfsek.terra.config.genconfig.biome.BiomeConfig; @@ -14,6 +15,9 @@ import com.dfsek.terra.config.genconfig.OreConfig; import com.dfsek.terra.config.genconfig.PaletteConfig; import com.dfsek.terra.config.genconfig.StructureConfig; import com.dfsek.terra.config.lang.LangUtil; +import com.dfsek.terra.util.StructureTypeEnum; +import org.bukkit.StructureType; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.java.JavaPlugin; @@ -71,6 +75,8 @@ public class ConfigPack extends YamlConfiguration { public final int octaves; public final float frequency; + public final Map locatable = new HashMap<>(); + public ConfigPack(File file) throws IOException, InvalidConfigurationException { long l = System.nanoTime(); load(new File(file, "pack.yml")); @@ -130,9 +136,27 @@ public class ConfigPack extends YamlConfiguration { allStructures.addAll(b.getStructures()); } + ConfigurationSection st = getConfigurationSection("locatable"); + if(st != null) { + Map strucLocatable = st.getValues(false); + for(Map.Entry e : strucLocatable.entrySet()) { + StructureConfig c = getStructure((String) e.getValue()); + if(c == null) throw new NotFoundException("Structure", (String) e.getValue(), getID()); + try { + locatable.put(StructureTypeEnum.valueOf(e.getKey()), c); + } catch(IllegalArgumentException ex) { + throw new NotFoundException("Structure Type", e.getKey(), getID()); + } + } + } + LangUtil.log("config-pack.loaded", Level.INFO, getID(), String.valueOf((System.nanoTime() - l)/1000000D)); } + public Map getLocatable() { + return locatable; + } + public Map getAbstractBiomes() { return abstractBiomes; } diff --git a/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeFloraConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeFloraConfig.java index 15eb21417..df694eca4 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeFloraConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeFloraConfig.java @@ -32,7 +32,7 @@ public class BiomeFloraConfig extends TerraConfigSection { floraAttempts = parent.getInt("flora.attempts", 1); floraChance = parent.getInt("flora.chance", 0); float floraFreq = (float) parent.getDouble("flora.simplex.frequency", 0.1); - int floraSeed = parent.getInt("flora.simplex.seed", 0); + int floraSeed = parent.getInt("flora.simplex.seed", 2403); if(floraSimplex) { floraNoise = new FastNoiseLite(floraSeed); floraNoise.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2); diff --git a/src/main/java/com/dfsek/terra/events/OreVeinGenerateEvent.java b/src/main/java/com/dfsek/terra/events/OreVeinGenerateEvent.java new file mode 100644 index 000000000..04ba5ee44 --- /dev/null +++ b/src/main/java/com/dfsek/terra/events/OreVeinGenerateEvent.java @@ -0,0 +1,4 @@ +package com.dfsek.terra.events; + +public class OreVeinGenerateEvent { +} diff --git a/src/main/java/com/dfsek/terra/events/TerraStructureLocateEvent.java b/src/main/java/com/dfsek/terra/events/TerraStructureLocateEvent.java new file mode 100644 index 000000000..6b25e85a5 --- /dev/null +++ b/src/main/java/com/dfsek/terra/events/TerraStructureLocateEvent.java @@ -0,0 +1,4 @@ +package com.dfsek.terra.events; + +public class TerraStructureLocateEvent { +} diff --git a/src/main/java/com/dfsek/terra/events/TreeGenerateEvent.java b/src/main/java/com/dfsek/terra/events/TreeGenerateEvent.java new file mode 100644 index 000000000..d2875f5fa --- /dev/null +++ b/src/main/java/com/dfsek/terra/events/TreeGenerateEvent.java @@ -0,0 +1,4 @@ +package com.dfsek.terra.events; + +public class TreeGenerateEvent { +} diff --git a/src/main/java/com/dfsek/terra/util/StructureTypeEnum.java b/src/main/java/com/dfsek/terra/util/StructureTypeEnum.java new file mode 100644 index 000000000..e55931013 --- /dev/null +++ b/src/main/java/com/dfsek/terra/util/StructureTypeEnum.java @@ -0,0 +1,36 @@ +package com.dfsek.terra.util; + +import org.bukkit.StructureType; + +/** + * Enum to represent StructureType, which is a class for some reason. + */ +public enum StructureTypeEnum { + MINESHAFT(StructureType.MINESHAFT), + VILLAGE(StructureType.VILLAGE), + NETHER_FORTRESS(StructureType.NETHER_FORTRESS), + STRONGHOLD(StructureType.STRONGHOLD), + JUNGLE_PYRAMID(StructureType.JUNGLE_PYRAMID), + OCEAN_RUIN(StructureType.OCEAN_RUIN), + DESERT_PYRAMID(StructureType.DESERT_PYRAMID), + IGLOO(StructureType.IGLOO), + SWAMP_HUT(StructureType.SWAMP_HUT), + OCEAN_MONUMENT(StructureType.OCEAN_MONUMENT), + END_CITY(StructureType.END_CITY), + WOODLAND_MANSION(StructureType.WOODLAND_MANSION), + BURIED_TREASURE(StructureType.BURIED_TREASURE), + SHIPWRECK(StructureType.SHIPWRECK), + PILLAGER_OUTPOST(StructureType.PILLAGER_OUTPOST), + NETHER_FOSSIL(StructureType.NETHER_FOSSIL), + RUINED_PORTAL(StructureType.RUINED_PORTAL), + BASTION_REMNANT(StructureType.BASTION_REMNANT); + StructureTypeEnum(StructureType type) { + this.type = type; + } + + private final StructureType type; + + public StructureType getType() { + return type; + } +}