the world spawn is now read from the level.dat file
parent
c6a0c2661e
commit
885ecbe1ac
|
@ -5,10 +5,12 @@ import org.jnbt.CompoundTag;
|
|||
import amidst.documentation.Immutable;
|
||||
import amidst.mojangapi.file.MojangApiParsingException;
|
||||
import amidst.mojangapi.world.WorldType;
|
||||
import amidst.mojangapi.world.coordinates.CoordinatesInWorld;
|
||||
|
||||
@Immutable
|
||||
public class LevelDatNbt {
|
||||
private final long seed;
|
||||
private final CoordinatesInWorld worldSpawn;
|
||||
private final WorldType worldType;
|
||||
private final String generatorOptions;
|
||||
private final boolean hasPlayer;
|
||||
|
@ -17,6 +19,8 @@ public class LevelDatNbt {
|
|||
try {
|
||||
CompoundTag dataTag = readDataTag(root);
|
||||
this.seed = readRandomSeed(dataTag);
|
||||
this.worldSpawn = CoordinatesInWorld.from(readSpawnX(dataTag),
|
||||
readSpawnZ(dataTag));
|
||||
if (hasGeneratorName(dataTag)) {
|
||||
this.worldType = WorldType.from(readGeneratorName(dataTag));
|
||||
if (worldType == WorldType.CUSTOMIZED) {
|
||||
|
@ -39,8 +43,18 @@ public class LevelDatNbt {
|
|||
}
|
||||
|
||||
private long readRandomSeed(CompoundTag dataTag) {
|
||||
return (Long) dataTag.getValue().get(NBTTagKeys.TAG_KEY_RANDOM_SEED)
|
||||
.getValue();
|
||||
return NBTUtils.getLongValue(dataTag.getValue().get(
|
||||
NBTTagKeys.TAG_KEY_RANDOM_SEED));
|
||||
}
|
||||
|
||||
private long readSpawnX(CompoundTag dataTag) {
|
||||
return NBTUtils.getLongValue(dataTag.getValue().get(
|
||||
NBTTagKeys.TAG_KEY_SPAWN_X));
|
||||
}
|
||||
|
||||
private long readSpawnZ(CompoundTag dataTag) {
|
||||
return NBTUtils.getLongValue(dataTag.getValue().get(
|
||||
NBTTagKeys.TAG_KEY_SPAWN_Z));
|
||||
}
|
||||
|
||||
private boolean hasGeneratorName(CompoundTag dataTag) {
|
||||
|
@ -65,6 +79,10 @@ public class LevelDatNbt {
|
|||
return seed;
|
||||
}
|
||||
|
||||
public CoordinatesInWorld getWorldSpawn() {
|
||||
return worldSpawn;
|
||||
}
|
||||
|
||||
public WorldType getWorldType() {
|
||||
return worldType;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ public class NBTTagKeys {
|
|||
public static final String TAG_KEY_DATA = "Data";
|
||||
public static final String TAG_KEY_POS = "Pos";
|
||||
public static final String TAG_KEY_PLAYER = "Player";
|
||||
public static final String TAG_KEY_SPAWN_X = "SpawnX";
|
||||
public static final String TAG_KEY_SPAWN_Z = "SpawnZ";
|
||||
public static final String TAG_KEY_DIMENSION = "Dimension";
|
||||
public static final String TAG_KEY_RANDOM_SEED = "RandomSeed";
|
||||
public static final String TAG_KEY_GENERATOR_NAME = "generatorName";
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.io.IOException;
|
|||
import org.jnbt.CompoundTag;
|
||||
import org.jnbt.NBTInputStream;
|
||||
import org.jnbt.NBTOutputStream;
|
||||
import org.jnbt.Tag;
|
||||
|
||||
import amidst.documentation.Immutable;
|
||||
|
||||
|
@ -41,4 +42,15 @@ public enum NBTUtils {
|
|||
return new NBTOutputStream(new BufferedOutputStream(
|
||||
new FileOutputStream(file)));
|
||||
}
|
||||
|
||||
public static long getLongValue(Tag tag) {
|
||||
Object value = tag.getValue();
|
||||
if (value instanceof Number) {
|
||||
return ((Number) value).longValue();
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"cannot read long value from the class '"
|
||||
+ tag.getClass().getName() + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,10 @@ import amidst.mojangapi.world.icon.type.TempleWorldIconTypeProvider;
|
|||
import amidst.mojangapi.world.oracle.BiomeDataOracle;
|
||||
import amidst.mojangapi.world.oracle.EndIsland;
|
||||
import amidst.mojangapi.world.oracle.EndIslandOracle;
|
||||
import amidst.mojangapi.world.oracle.HeuristicWorldSpawnOracle;
|
||||
import amidst.mojangapi.world.oracle.ImmutableWorldSpawnOracle;
|
||||
import amidst.mojangapi.world.oracle.SlimeChunkOracle;
|
||||
import amidst.mojangapi.world.oracle.WorldSpawnOracle;
|
||||
import amidst.mojangapi.world.player.MovablePlayerList;
|
||||
import amidst.mojangapi.world.player.PlayerInformationCache;
|
||||
import amidst.mojangapi.world.player.WorldPlayerType;
|
||||
|
@ -47,10 +50,21 @@ public class WorldBuilder {
|
|||
public World fromSeed(MinecraftInterface minecraftInterface,
|
||||
WorldSeed worldSeed, WorldType worldType)
|
||||
throws MinecraftInterfaceException {
|
||||
return create(minecraftInterface, worldSeed, worldType, "",
|
||||
BiomeDataOracle biomeDataOracle = new BiomeDataOracle(
|
||||
minecraftInterface);
|
||||
VersionFeatures versionFeatures = DefaultVersionFeatures
|
||||
.create(minecraftInterface.getRecognisedVersion());
|
||||
return create(
|
||||
minecraftInterface,
|
||||
worldSeed,
|
||||
worldType,
|
||||
"",
|
||||
MovablePlayerList.dummy(),
|
||||
DefaultVersionFeatures.create(minecraftInterface
|
||||
.getRecognisedVersion()));
|
||||
versionFeatures,
|
||||
biomeDataOracle,
|
||||
new HeuristicWorldSpawnOracle(worldSeed.getLong(),
|
||||
biomeDataOracle, versionFeatures
|
||||
.getValidBiomesForStructure_Spawn()));
|
||||
}
|
||||
|
||||
public World fromFile(MinecraftInterface minecraftInterface,
|
||||
|
@ -66,18 +80,21 @@ public class WorldBuilder {
|
|||
return create(minecraftInterface,
|
||||
WorldSeed.fromFile(levelDat.getSeed()),
|
||||
levelDat.getWorldType(), levelDat.getGeneratorOptions(),
|
||||
movablePlayerList, versionFeatures);
|
||||
movablePlayerList, versionFeatures, new BiomeDataOracle(
|
||||
minecraftInterface), new ImmutableWorldSpawnOracle(
|
||||
levelDat.getWorldSpawn()));
|
||||
}
|
||||
|
||||
private World create(MinecraftInterface minecraftInterface,
|
||||
WorldSeed worldSeed, WorldType worldType, String generatorOptions,
|
||||
MovablePlayerList movablePlayerList, VersionFeatures versionFeatures)
|
||||
MovablePlayerList movablePlayerList,
|
||||
VersionFeatures versionFeatures, BiomeDataOracle biomeDataOracle,
|
||||
WorldSpawnOracle worldSpawnOracle)
|
||||
throws MinecraftInterfaceException {
|
||||
seedHistoryLogger.log(worldSeed);
|
||||
long seed = worldSeed.getLong();
|
||||
// @formatter:off
|
||||
minecraftInterface.createWorld(seed, worldType, generatorOptions);
|
||||
BiomeDataOracle biomeDataOracle = new BiomeDataOracle(minecraftInterface);
|
||||
return new World(
|
||||
worldSeed,
|
||||
worldType,
|
||||
|
@ -87,7 +104,7 @@ public class WorldBuilder {
|
|||
biomeDataOracle,
|
||||
EndIslandOracle.from( seed),
|
||||
new SlimeChunkOracle( seed),
|
||||
new SpawnProducer( seed, biomeDataOracle, versionFeatures.getValidBiomesForStructure_Spawn()),
|
||||
new SpawnProducer(worldSpawnOracle),
|
||||
new StrongholdProducer(seed, biomeDataOracle, versionFeatures.getValidBiomesAtMiddleOfChunk_Stronghold(), versionFeatures.getNumberOfStrongholds()),
|
||||
new PlayerProducer(movablePlayerList),
|
||||
new StructureProducer<Void>(
|
||||
|
|
|
@ -2,28 +2,21 @@ package amidst.mojangapi.world.icon.producer;
|
|||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import amidst.documentation.ThreadSafe;
|
||||
import amidst.logging.Log;
|
||||
import amidst.mojangapi.world.Dimension;
|
||||
import amidst.mojangapi.world.biome.Biome;
|
||||
import amidst.mojangapi.world.coordinates.CoordinatesInWorld;
|
||||
import amidst.mojangapi.world.icon.WorldIcon;
|
||||
import amidst.mojangapi.world.icon.type.DefaultWorldIconTypes;
|
||||
import amidst.mojangapi.world.oracle.BiomeDataOracle;
|
||||
import amidst.mojangapi.world.oracle.WorldSpawnOracle;
|
||||
|
||||
@ThreadSafe
|
||||
public class SpawnProducer extends CachedWorldIconProducer {
|
||||
private final long seed;
|
||||
private final BiomeDataOracle biomeDataOracle;
|
||||
private final List<Biome> validBiomes;
|
||||
private final WorldSpawnOracle oracle;
|
||||
|
||||
public SpawnProducer(long seed, BiomeDataOracle biomeDataOracle,
|
||||
List<Biome> validBiomes) {
|
||||
this.seed = seed;
|
||||
this.biomeDataOracle = biomeDataOracle;
|
||||
this.validBiomes = validBiomes;
|
||||
public SpawnProducer(WorldSpawnOracle oracle) {
|
||||
this.oracle = oracle;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,7 +25,7 @@ public class SpawnProducer extends CachedWorldIconProducer {
|
|||
}
|
||||
|
||||
private WorldIcon createSpawnWorldIcon() {
|
||||
CoordinatesInWorld spawnLocation = getSpawnCenterInWorldCoordinates();
|
||||
CoordinatesInWorld spawnLocation = oracle.get();
|
||||
if (spawnLocation != null) {
|
||||
return createWorldIcon(spawnLocation);
|
||||
} else {
|
||||
|
@ -49,9 +42,4 @@ public class SpawnProducer extends CachedWorldIconProducer {
|
|||
DefaultWorldIconTypes.SPAWN.getImage(), Dimension.OVERWORLD,
|
||||
false);
|
||||
}
|
||||
|
||||
private CoordinatesInWorld getSpawnCenterInWorldCoordinates() {
|
||||
return biomeDataOracle.findValidLocation(0, 0, 256, validBiomes,
|
||||
new Random(seed));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ public enum DefaultWorldIconTypes {
|
|||
JUNGLE("Jungle Temple"),
|
||||
DESERT("Desert Temple"),
|
||||
VILLAGE("Village"),
|
||||
SPAWN("Default World Spawn"),
|
||||
SPAWN("World Spawn"),
|
||||
WITCH("Witch Hut"),
|
||||
OCEAN_MONUMENT("Ocean Monument"),
|
||||
IGLOO("Igloo"),
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package amidst.mojangapi.world.oracle;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import amidst.documentation.ThreadSafe;
|
||||
import amidst.mojangapi.world.biome.Biome;
|
||||
import amidst.mojangapi.world.coordinates.CoordinatesInWorld;
|
||||
|
||||
@ThreadSafe
|
||||
public class HeuristicWorldSpawnOracle implements WorldSpawnOracle {
|
||||
private final long seed;
|
||||
private final BiomeDataOracle biomeDataOracle;
|
||||
private final List<Biome> validBiomes;
|
||||
|
||||
public HeuristicWorldSpawnOracle(long seed,
|
||||
BiomeDataOracle biomeDataOracle, List<Biome> validBiomes) {
|
||||
this.seed = seed;
|
||||
this.biomeDataOracle = biomeDataOracle;
|
||||
this.validBiomes = validBiomes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CoordinatesInWorld get() {
|
||||
return biomeDataOracle.findValidLocation(0, 0, 256, validBiomes,
|
||||
new Random(seed));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package amidst.mojangapi.world.oracle;
|
||||
|
||||
import amidst.documentation.Immutable;
|
||||
import amidst.mojangapi.world.coordinates.CoordinatesInWorld;
|
||||
|
||||
@Immutable
|
||||
public class ImmutableWorldSpawnOracle implements WorldSpawnOracle {
|
||||
private final CoordinatesInWorld worldSpawn;
|
||||
|
||||
public ImmutableWorldSpawnOracle(CoordinatesInWorld worldSpawn) {
|
||||
this.worldSpawn = worldSpawn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CoordinatesInWorld get() {
|
||||
return worldSpawn;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package amidst.mojangapi.world.oracle;
|
||||
|
||||
import amidst.documentation.ThreadSafe;
|
||||
import amidst.mojangapi.world.coordinates.CoordinatesInWorld;
|
||||
|
||||
@ThreadSafe
|
||||
public interface WorldSpawnOracle {
|
||||
CoordinatesInWorld get();
|
||||
}
|
Loading…
Reference in New Issue