diff --git a/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java b/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java index 1c8c0f0b4..21c2f05dd 100644 --- a/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java +++ b/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java @@ -16,6 +16,7 @@ import com.volmit.iris.scaffold.parallel.MultiBurst; import com.volmit.iris.util.*; import lombok.Getter; import lombok.Setter; +import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -25,6 +26,10 @@ import org.bukkit.event.world.WorldSaveEvent; import org.bukkit.generator.BlockPopulator; import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; public class IrisEngineCompound implements EngineCompound { @Getter @@ -66,36 +71,47 @@ public class IrisEngineCompound implements EngineCompound { engineMetadata.setLastVersion(Iris.instance.getDescription().getVersion()); - if(engineMetadata.getStrongholdPosition() == null) + if(engineMetadata.getStrongholdPositions() == null || engineMetadata.getStrongholdPositions().size() == 0) { - if(!(world instanceof FakeWorld && world instanceof HeightedFakeWorld)) + if(!(world instanceof FakeWorld || world instanceof HeightedFakeWorld)) { + Iris.info("Got this far (0)"); + List strongholds = new ArrayList<>(); Object nmsWorld = new V(world).invoke("getHandle"); Object chunkProvider = new V(nmsWorld).invoke("getChunkProvider"); Object chunkGenerator = new V(chunkProvider).invoke("getChunkGenerator"); try { + Iris.info("Got this far (1)"); Class clazz = Class.forName("net.minecraft.server." + INMS.getNMSTag() + ".ChunkGenerator"); Class clazzSG = Class.forName("net.minecraft.server." + INMS.getNMSTag() + ".StructureGenerator"); Class clazzBP = Class.forName("net.minecraft.server." + INMS.getNMSTag() + ".BlockPosition"); - Object bp = clazz.getDeclaredMethod("findNearestMapFeature", - nmsWorld.getClass(), - clazzSG, - clazzBP, - int.class, - boolean.class - ).invoke(chunkGenerator, - nmsWorld, - clazzSG.getDeclaredField("STRONGHOLD").get(null), - clazzBP.getDeclaredField("ZERO").get(null), - 100, - false - ); - engineMetadata.setStrongholdPosition(new IrisPosition((int)new V(bp, false).invoke("getX"), (int)new V(bp, false).invoke("getY"), (int)new V(bp, false).invoke("getZ"))); + CompletableFuture cf = new CompletableFuture<>(); + Object BP = null; + getBPSafe(clazz, clazzSG, clazzBP, nmsWorld, chunkGenerator).thenAccept(bp -> { + Iris.info("Got this far (2)"); + strongholds.add(new IrisPosition((int) new V(bp, false).invoke("getX"), (int) new V(bp, false).invoke("getY"), (int) new V(bp, false).invoke("getZ"))); + Iris.info("Got this far (3)"); + String positions = ""; + for (IrisPosition pos : strongholds){ + positions += "(" + pos.getX() + "," + pos.getY() + "," + pos.getZ() + ") "; + } + Iris.info("Strongholds (" + engineMetadata.getStrongholdPositions().size() + ") found at [" + positions + "]"); + }); + + engineMetadata.setStrongholdPositions(strongholds); } catch (Throwable ignored) { - engineMetadata.setStrongholdPosition(new IrisPosition(1337, 32, -1337)); - Iris.warn("Couldn't properly find the stronghold positon for this world. Is this headless mode?"); + strongholds.add( new IrisPosition(10337, 32, -1337) ); + engineMetadata.setStrongholdPositions(strongholds); + Iris.warn("Couldn't properly find the stronghold position for this world. Is this headless mode?"); + Iris.warn(" -> Setting default stronghold position"); + ignored.printStackTrace(); + Iris.info("Got this far (3)"); + String positions = ""; + for (IrisPosition pos : strongholds){ + positions += "(" + pos.getX() + "," + pos.getY() + "," + pos.getZ() + ") "; + } + Iris.info("Strongholds (" + engineMetadata.getStrongholdPositions().size() + ") found at [" + positions + "]"); } - Iris.info("Stronghold: " + engineMetadata.getStrongholdPosition().toString()); } } @@ -158,10 +174,39 @@ public class IrisEngineCompound implements EngineCompound { Iris.instance.registerListener(this); } - - public IrisPosition getStrongholdPosition() + + private Object getBP(Class clazz, Class clazzSG, Class clazzBP, Object nmsWorld, Object chunkGenerator) throws NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { + return clazz.getDeclaredMethod("findNearestMapFeature", + nmsWorld.getClass(), + clazzSG, + clazzBP, + int.class, + boolean.class + ).invoke(chunkGenerator, + nmsWorld, + clazzSG.getDeclaredField("STRONGHOLD").get(null), + clazzBP.getDeclaredField("ZERO").get(null), + 100, + false + ); + } + + public CompletableFuture getBPSafe(Class clazz, Class clazzSG, Class clazzBP, Object nmsWorld, Object chunkGenerator) { + CompletableFuture cf = new CompletableFuture<>(); + Bukkit.getScheduler().runTask(Iris.instance, () -> { + try { + cf.complete(getBP(clazz, clazzSG, clazzBP, nmsWorld, chunkGenerator)); + } catch (Throwable e){ + cf.complete(null); + e.printStackTrace(); + } + }); + return cf; + } + + public List getStrongholdPositions() { - return engineMetadata.getStrongholdPosition(); + return engineMetadata.getStrongholdPositions(); } @EventHandler diff --git a/src/main/java/com/volmit/iris/manager/command/CommandLocate.java b/src/main/java/com/volmit/iris/manager/command/CommandLocate.java index fcefb4e85..78f583044 100644 --- a/src/main/java/com/volmit/iris/manager/command/CommandLocate.java +++ b/src/main/java/com/volmit/iris/manager/command/CommandLocate.java @@ -16,9 +16,9 @@ public class CommandLocate extends MortarCommand implements Listener { @EventHandler public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) { - if (event.getMessage().contains("locate") && IrisWorlds.isIrisWorld(event.getPlayer().getWorld())){ + if (!event.getMessage().contains("stronghold") && event.getMessage().contains("locate") && IrisWorlds.isIrisWorld(event.getPlayer().getWorld())) { event.setCancelled(true); - event.getPlayer().sendMessage("/locate command blocked in Iris worlds. Please use '/ir goto' instead."); + event.getPlayer().sendMessage("/locate command blocked in Iris worlds. Please use '/ir goto' instead. You can /locate stronghold!"); } } diff --git a/src/main/java/com/volmit/iris/scaffold/engine/EngineCompound.java b/src/main/java/com/volmit/iris/scaffold/engine/EngineCompound.java index 8dfe50d80..6e75cf09a 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/EngineCompound.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/EngineCompound.java @@ -16,6 +16,8 @@ import org.bukkit.command.CommandSender; import org.bukkit.event.Listener; import org.bukkit.generator.BlockPopulator; +import java.util.List; + public interface EngineCompound extends Listener, Hotloadable, DataProvider { public IrisDimension getRootDimension(); @@ -24,7 +26,7 @@ public interface EngineCompound extends Listener, Hotloadable, DataProvider public World getWorld(); - public IrisPosition getStrongholdPosition(); + public List getStrongholdPositions(); public void printMetrics(CommandSender sender); diff --git a/src/main/java/com/volmit/iris/scaffold/engine/EngineData.java b/src/main/java/com/volmit/iris/scaffold/engine/EngineData.java index cdbc7aebd..0cd8e42ca 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/EngineData.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/EngineData.java @@ -7,12 +7,13 @@ import lombok.Data; import java.io.File; import java.io.IOException; +import java.util.List; @Data public class EngineData { private String dimension; private String lastVersion; - private IrisPosition strongholdPosition; + private List strongholdPositions; public void save(File f) { diff --git a/src/main/java/com/volmit/iris/scaffold/engine/EngineParallaxManager.java b/src/main/java/com/volmit/iris/scaffold/engine/EngineParallaxManager.java index 34b22cf7b..de9147745 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/EngineParallaxManager.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/EngineParallaxManager.java @@ -21,6 +21,7 @@ import org.bukkit.block.data.BlockData; import org.bukkit.util.BlockVector; import org.bukkit.util.Consumer; +import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -345,6 +346,10 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { { KList placeAfter = new KList<>(); + if (structure == null){ + return null; + } + if(structure.getFeature() != null) { if(structure.getFeature().getBlockRadius() == 32) @@ -366,13 +371,13 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { if(getEngine().getDimension().getStronghold() != null) { - IrisPosition pos = getEngine().getCompound().getStrongholdPosition(); - - if(x == pos.getX() >> 4 && z == pos.getZ() >> 4) - { - IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(getEngine().getDimension().getStronghold()); - placeAfter.addAll(placeStructure(pos, structure, rng)); - placed = true; + List poss = getEngine().getCompound().getStrongholdPositions(); + for (IrisPosition pos : poss) { + if (x == pos.getX() >> 4 && z == pos.getZ() >> 4) { + IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(getEngine().getDimension().getStronghold()); + placeAfter.addAll(placeStructure(pos, structure, rng)); + placed = true; + } } }