Add ability to set custom structures as locatable by Ender Eyes

This commit is contained in:
dfsek 2020-10-21 00:37:10 -07:00
parent 1ccd14a973
commit 862e9e82a2
10 changed files with 138 additions and 24 deletions

View File

@ -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.");
}
}
}

View File

@ -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

View File

@ -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<Vector> 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<Vector> 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));
}
/**

View File

@ -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;
}

View File

@ -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<StructureTypeEnum, StructureConfig> 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<String, Object> strucLocatable = st.getValues(false);
for(Map.Entry<String, Object> 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<StructureTypeEnum, StructureConfig> getLocatable() {
return locatable;
}
public Map<String, AbstractBiomeConfig> getAbstractBiomes() {
return abstractBiomes;
}

View File

@ -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);

View File

@ -0,0 +1,4 @@
package com.dfsek.terra.events;
public class OreVeinGenerateEvent {
}

View File

@ -0,0 +1,4 @@
package com.dfsek.terra.events;
public class TerraStructureLocateEvent {
}

View File

@ -0,0 +1,4 @@
package com.dfsek.terra.events;
public class TreeGenerateEvent {
}

View File

@ -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;
}
}