mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 10:12:53 +00:00
Fixed Strongholds not generating in 1.17
- Fixed Strongholds not generating in 1.17 - Made 9 strongholds now generate by default Dev note: Tile entities are not placing correctly in jigsaws when generating (manual placement is fine)
This commit is contained in:
parent
54c7f896ad
commit
48e4fd8088
@ -27,9 +27,13 @@ import org.bukkit.event.world.WorldSaveEvent;
|
|||||||
import org.bukkit.generator.BlockPopulator;
|
import org.bukkit.generator.BlockPopulator;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class IrisEngineCompound implements EngineCompound {
|
public class IrisEngineCompound implements EngineCompound {
|
||||||
@ -71,47 +75,6 @@ public class IrisEngineCompound implements EngineCompound {
|
|||||||
engineMetadata.setDimension(rootDimension.getLoadKey());
|
engineMetadata.setDimension(rootDimension.getLoadKey());
|
||||||
engineMetadata.setLastVersion(Iris.instance.getDescription().getVersion());
|
engineMetadata.setLastVersion(Iris.instance.getDescription().getVersion());
|
||||||
|
|
||||||
// TODO: In nms class, not here. Also it doesnt work
|
|
||||||
if(engineMetadata.getStrongholdPositions() == null || engineMetadata.getStrongholdPositions().size() == 0)
|
|
||||||
{
|
|
||||||
if(!(world instanceof FakeWorld || world instanceof HeightedFakeWorld))
|
|
||||||
{
|
|
||||||
List<IrisPosition> 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 {
|
|
||||||
Class<?> clazz = Class.forName("net.minecraft.world.level.chunk.ChunkGenerator");
|
|
||||||
Class<?> clazzSG = Class.forName("net.minecraft.world.level.levelgen.feature.StructureGenerator");
|
|
||||||
Class<?> clazzBP = Class.forName("net.minecraft.core.BlockPosition");
|
|
||||||
getBPSafe(clazz, clazzSG, clazzBP, nmsWorld, chunkGenerator).thenAccept(bp -> {
|
|
||||||
if (bp == null){
|
|
||||||
throw new NullPointerException();
|
|
||||||
}
|
|
||||||
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")));
|
|
||||||
StringBuilder positions = new StringBuilder();
|
|
||||||
for (IrisPosition pos : strongholds){
|
|
||||||
positions.append("(").append(pos.getX()).append(",").append(pos.getY()).append(",").append(pos.getZ()).append(") ");
|
|
||||||
}
|
|
||||||
Iris.info("Strongholds (" + engineMetadata.getStrongholdPositions().size() + ") found at [" + positions + "]");
|
|
||||||
});
|
|
||||||
|
|
||||||
engineMetadata.setStrongholdPositions(strongholds);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
strongholds.add( new IrisPosition(1337, 32, -1337) );
|
|
||||||
engineMetadata.setStrongholdPositions(strongholds);
|
|
||||||
Iris.warn("Couldn't properly find the stronghold position for this world. Is this headless mode? Are you not using 1.16 or higher?");
|
|
||||||
Iris.warn(" -> Setting default stronghold position");
|
|
||||||
e.printStackTrace();
|
|
||||||
StringBuilder positions = new StringBuilder();
|
|
||||||
for (IrisPosition pos : strongholds){
|
|
||||||
positions.append("(").append(pos.getX()).append(",").append(pos.getY()).append(",").append(pos.getZ()).append(") ");
|
|
||||||
}
|
|
||||||
Iris.info("Strongholds (" + engineMetadata.getStrongholdPositions().size() + ") found at [" + positions + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
saveEngineMetadata();
|
saveEngineMetadata();
|
||||||
populators = new KList<>();
|
populators = new KList<>();
|
||||||
|
|
||||||
@ -174,34 +137,6 @@ public class IrisEngineCompound implements EngineCompound {
|
|||||||
Iris.instance.registerListener(this);
|
Iris.instance.registerListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
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("k").get(null),
|
|
||||||
clazzBP.getDeclaredField("b").get(null),
|
|
||||||
100,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CompletableFuture<Object> getBPSafe(Class<?> clazz, Class<?> clazzSG, Class<?> clazzBP, Object nmsWorld, Object chunkGenerator) {
|
|
||||||
CompletableFuture<Object> cf = new CompletableFuture<>();
|
|
||||||
Bukkit.getScheduler().runTask(Iris.instance, () -> {
|
|
||||||
try {
|
|
||||||
cf.complete(getBP(clazz, clazzSG, clazzBP, nmsWorld, chunkGenerator));
|
|
||||||
} catch (Throwable e){
|
|
||||||
cf.complete(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return cf;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<IrisPosition> getStrongholdPositions()
|
public List<IrisPosition> getStrongholdPositions()
|
||||||
{
|
{
|
||||||
return engineMetadata.getStrongholdPositions();
|
return engineMetadata.getStrongholdPositions();
|
||||||
|
@ -57,4 +57,9 @@ public class IrisPosition
|
|||||||
public IrisPosition copy() {
|
public IrisPosition copy() {
|
||||||
return new IrisPosition(x,y,z);
|
return new IrisPosition(x,y,z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[" + getX() + "," + getY() + "," + getZ() + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import com.volmit.iris.generator.IrisEngineCompound;
|
|||||||
import com.volmit.iris.manager.IrisDataManager;
|
import com.volmit.iris.manager.IrisDataManager;
|
||||||
import com.volmit.iris.object.IrisBiome;
|
import com.volmit.iris.object.IrisBiome;
|
||||||
import com.volmit.iris.object.IrisDimension;
|
import com.volmit.iris.object.IrisDimension;
|
||||||
|
import com.volmit.iris.object.IrisPosition;
|
||||||
import com.volmit.iris.pregen.DirectWorldWriter;
|
import com.volmit.iris.pregen.DirectWorldWriter;
|
||||||
import com.volmit.iris.scaffold.IrisWorlds;
|
import com.volmit.iris.scaffold.IrisWorlds;
|
||||||
import com.volmit.iris.scaffold.cache.Cache;
|
import com.volmit.iris.scaffold.cache.Cache;
|
||||||
@ -13,6 +14,7 @@ import com.volmit.iris.scaffold.hunk.Hunk;
|
|||||||
import com.volmit.iris.scaffold.parallel.BurstExecutor;
|
import com.volmit.iris.scaffold.parallel.BurstExecutor;
|
||||||
import com.volmit.iris.scaffold.parallel.MultiBurst;
|
import com.volmit.iris.scaffold.parallel.MultiBurst;
|
||||||
import com.volmit.iris.util.*;
|
import com.volmit.iris.util.*;
|
||||||
|
import io.netty.util.internal.ConcurrentSet;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
@ -27,12 +29,22 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class EngineCompositeGenerator extends ChunkGenerator implements IrisAccess {
|
public class EngineCompositeGenerator extends ChunkGenerator implements IrisAccess {
|
||||||
private EngineCompound compound = null;
|
private EngineCompound compound = null;
|
||||||
@ -292,6 +304,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
|
|||||||
fake.set(false);
|
fake.set(false);
|
||||||
this.compound.updateWorld(world);
|
this.compound.updateWorld(world);
|
||||||
getTarget().updateWorld(world);
|
getTarget().updateWorld(world);
|
||||||
|
placeStrongholds(world);
|
||||||
|
|
||||||
for(int i = 0; i < getComposite().getSize(); i++)
|
for(int i = 0; i < getComposite().getSize(); i++)
|
||||||
{
|
{
|
||||||
@ -324,6 +337,122 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Place strongholds in the world
|
||||||
|
* @param world
|
||||||
|
*/
|
||||||
|
public void placeStrongholds(World world) {
|
||||||
|
EngineData metadata = getComposite().getEngineMetadata();
|
||||||
|
// TODO: In nms class, not here. Also it doesnt work
|
||||||
|
if(metadata.getStrongholdPositions() == null || metadata.getStrongholdPositions().size() == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
List<IrisPosition> 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 {
|
||||||
|
Class<?> clazz = Class.forName("net.minecraft.world.level.chunk.ChunkGenerator");
|
||||||
|
Class<?> clazzSG = Class.forName("net.minecraft.world.level.levelgen.feature.StructureGenerator");
|
||||||
|
Class<?> clazzBP = Class.forName("net.minecraft.core.BlockPosition");
|
||||||
|
Constructor bpCon = clazzBP.getConstructor(int.class, int.class, int.class);
|
||||||
|
|
||||||
|
//By default, we place 9 strongholds. One near 0,0 and 8 all around it at about 10_000 blocks out
|
||||||
|
int coords[][] = {{0, 0}, {7000, -7000}, {10000, 0}, {7000, 7000}, {0, 10000}, {-7000, 7000}, {-10000, 0}, {-7000, -7000}, {0, -10000}};
|
||||||
|
|
||||||
|
//Set of stronghold locations so we don't place 2 strongholds at the same location
|
||||||
|
Set<Long> existing = new ConcurrentSet<>();
|
||||||
|
Set<CompletableFuture<Object>> futures = new HashSet<>();
|
||||||
|
for (int[] currCoords : coords) {
|
||||||
|
//Create a NMS BlockPosition
|
||||||
|
Object blockPosToTest = bpCon.newInstance(currCoords[0], 0, currCoords[1]);
|
||||||
|
//Create a CompletableFuture so we can track once the sync code is complete
|
||||||
|
|
||||||
|
CompletableFuture<Object> future = new CompletableFuture<>();
|
||||||
|
futures.add(future);
|
||||||
|
|
||||||
|
//We have to run this code synchronously because it uses NMS
|
||||||
|
J.s(() -> {
|
||||||
|
try {
|
||||||
|
Object o = getBP(clazz, clazzSG, clazzBP, nmsWorld, blockPosToTest, chunkGenerator);
|
||||||
|
future.complete(o);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
future.complete(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
CompletableFuture<Void> all = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
|
||||||
|
all.thenAccept((_void) -> { //Once all futures for all 9 strongholds have completed
|
||||||
|
for (CompletableFuture<Object> future : futures) {
|
||||||
|
try {
|
||||||
|
Object pos = future.getNow(null);
|
||||||
|
if (pos != null) {
|
||||||
|
IrisPosition ipos = new IrisPosition((int) new V(pos, false).invoke("getX"), (int) new V(pos,
|
||||||
|
false).invoke("getY"), (int) new V(pos, false).invoke("getZ"));
|
||||||
|
long xz = (((long)ipos.getX()) << 32) | (ipos.getZ() & 0xffffffffL);
|
||||||
|
if (existing.contains(xz)) return; //Make sure we don't double up on stronghold locs
|
||||||
|
existing.add(xz);
|
||||||
|
strongholds.add(ipos);
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder positions = new StringBuilder();
|
||||||
|
for (IrisPosition pos : strongholds){
|
||||||
|
positions.append("(").append(pos.getX()).append(",").append(pos.getY()).append(",").append(pos.getZ()).append(") ");
|
||||||
|
}
|
||||||
|
Iris.info("Strongholds (" + strongholds.size() + ") found at [" + positions + "]");
|
||||||
|
|
||||||
|
metadata.setStrongholdPositions(strongholds);
|
||||||
|
getComposite().saveEngineMetadata();
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
strongholds.add( new IrisPosition(1337, 32, -1337) );
|
||||||
|
metadata.setStrongholdPositions(strongholds);
|
||||||
|
Iris.warn("Couldn't properly find the stronghold position for this world. Is this headless mode? Are you not using 1.16 or higher?");
|
||||||
|
Iris.warn(" -> Setting default stronghold position");
|
||||||
|
e.printStackTrace();
|
||||||
|
StringBuilder positions = new StringBuilder();
|
||||||
|
for (IrisPosition pos : strongholds){
|
||||||
|
positions.append("(").append(pos.getX()).append(",").append(pos.getY()).append(",").append(pos.getZ()).append(") ");
|
||||||
|
}
|
||||||
|
Iris.info("Strongholds (" + metadata.getStrongholdPositions().size() + ") found at [" + positions + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get BlockPosition for nearest stronghold from the provided position
|
||||||
|
*/
|
||||||
|
private Object getBP(Class<?> clazz, Class<?> clazzSG, Class<?> clazzBP, Object nmsWorld, Object pos, Object chunkGenerator) throws NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, ClassNotFoundException {
|
||||||
|
final String stronghold = "k"; //1.17_01 mapping
|
||||||
|
|
||||||
|
Object structureGeneratorStronghold = clazzSG.getDeclaredField(stronghold).get(null);
|
||||||
|
Method getNearestGeneratedFeature = clazz.getDeclaredMethod("findNearestMapFeature",
|
||||||
|
nmsWorld.getClass(),
|
||||||
|
clazzSG,
|
||||||
|
clazzBP,
|
||||||
|
int.class,
|
||||||
|
boolean.class
|
||||||
|
);
|
||||||
|
Object nearestPOS = getNearestGeneratedFeature.invoke(chunkGenerator,
|
||||||
|
nmsWorld,
|
||||||
|
structureGeneratorStronghold,
|
||||||
|
pos,
|
||||||
|
100,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
return nearestPOS;
|
||||||
|
}
|
||||||
|
|
||||||
private File getDataFolder(World world) {
|
private File getDataFolder(World world) {
|
||||||
return new File(world.getWorldFolder(), "iris/pack");
|
return new File(world.getWorldFolder(), "iris/pack");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user