Minetest support - initial commit
Rivers don't match the game, but Amidst can now draw maps made with a different engine than Minecraftmaster
parent
196a2bca7b
commit
969f26e406
5
pom.xml
5
pom.xml
|
@ -130,5 +130,10 @@
|
|||
<scope>provided</scope>
|
||||
<type>maven-plugin</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.vecmath</groupId>
|
||||
<artifactId>vecmath</artifactId>
|
||||
<version>1.5.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -26,6 +26,9 @@ public class AmidstSettings {
|
|||
public final Setting<Boolean> showOceanMonuments;
|
||||
public final Setting<Boolean> showNetherFortresses;
|
||||
public final Setting<Boolean> showEndCities;
|
||||
public final Setting<Boolean> showMinetestRivers;
|
||||
public final Setting<Boolean> showMinetestOceans;
|
||||
public final Setting<Boolean> showMinetestMountains;
|
||||
public final Setting<Boolean> enableAllLayers;
|
||||
|
||||
public final Setting<Boolean> smoothScrolling;
|
||||
|
@ -58,6 +61,9 @@ public class AmidstSettings {
|
|||
showOceanMonuments = Settings.createBoolean( preferences, "oceanMonumentIcons", true);
|
||||
showNetherFortresses = Settings.createBoolean( preferences, "netherFortressIcons", false);
|
||||
showEndCities = Settings.createBoolean( preferences, "endCityIcons", false);
|
||||
showMinetestRivers = Settings.createBoolean( preferences, "minetestRivers", true);
|
||||
showMinetestOceans = Settings.createBoolean( preferences, "minetestOceans", true);
|
||||
showMinetestMountains = Settings.createBoolean( preferences, "minetestMountains", true);
|
||||
enableAllLayers = Settings.createBoolean( preferences, "enableAllLayers", false);
|
||||
|
||||
smoothScrolling = Settings.createBoolean( preferences, "mapFlicking", true);
|
||||
|
|
|
@ -11,6 +11,9 @@ import amidst.documentation.ThreadSafe;
|
|||
@ThreadSafe
|
||||
public class CommandLineParameters {
|
||||
// @formatter:off
|
||||
@Option(name = "-mtpath", usage = "location of the minetest directory.", metaVar = "<directory>")
|
||||
public volatile String minetestDirectory;
|
||||
|
||||
@Option(name = "-mcpath", usage = "location of the '.minecraft' directory.", metaVar = "<directory>")
|
||||
public volatile String dotMinecraftDirectory;
|
||||
|
||||
|
|
|
@ -8,4 +8,5 @@ public enum FeatureToggles {
|
|||
|
||||
public static final boolean SEED_SEARCH = false;
|
||||
public static final boolean WORLD_EXPORTER = false;
|
||||
public static final boolean MINETEST_SUPPORT = true;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import amidst.gui.main.viewer.PerViewerFacadeInjector;
|
|||
import amidst.gui.main.viewer.ViewerFacade;
|
||||
import amidst.gui.main.viewer.Zoom;
|
||||
import amidst.gui.profileselect.ProfileSelectWindow;
|
||||
import amidst.minetest.file.MinetestInstallation;
|
||||
import amidst.mojangapi.LauncherProfileRunner;
|
||||
import amidst.mojangapi.RunningLauncherProfile;
|
||||
import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException;
|
||||
|
@ -41,6 +42,7 @@ public class PerApplicationInjector {
|
|||
private final PlayerInformationProvider playerInformationProvider;
|
||||
private final SeedHistoryLogger seedHistoryLogger;
|
||||
private final MinecraftInstallation minecraftInstallation;
|
||||
private final MinetestInstallation minetestInstallation;
|
||||
private final Optional<LauncherProfile> preferredLauncherProfile;
|
||||
private final WorldBuilder worldBuilder;
|
||||
private final LauncherProfileRunner launcherProfileRunner;
|
||||
|
@ -64,8 +66,12 @@ public class PerApplicationInjector {
|
|||
this.seedHistoryLogger = SeedHistoryLogger.from(parameters.seedHistoryFile);
|
||||
this.minecraftInstallation = MinecraftInstallation
|
||||
.newLocalMinecraftInstallation(parameters.dotMinecraftDirectory);
|
||||
this.preferredLauncherProfile = minecraftInstallation
|
||||
.tryReadLauncherProfile(parameters.minecraftJarFile, parameters.minecraftJsonFile);
|
||||
this.minetestInstallation = MinetestInstallation
|
||||
.newLocalMinetestInstallationOrDefault(parameters.minetestDirectory);
|
||||
//this.preferredLauncherProfile = minecraftInstallation
|
||||
// .tryReadLauncherProfile(parameters.minecraftJarFile, parameters.minecraftJsonFile);
|
||||
this.preferredLauncherProfile = minetestInstallation
|
||||
.defaultLauncherProfile();
|
||||
this.worldBuilder = new WorldBuilder(playerInformationProvider, seedHistoryLogger);
|
||||
this.launcherProfileRunner = new LauncherProfileRunner(worldBuilder);
|
||||
this.biomeProfileDirectory = BiomeProfileDirectory.create(parameters.biomeProfilesDirectory);
|
||||
|
@ -102,7 +108,7 @@ public class PerApplicationInjector {
|
|||
application,
|
||||
metadata,
|
||||
settings,
|
||||
minecraftInstallation,
|
||||
minetestInstallation,
|
||||
runningLauncherProfile,
|
||||
biomeProfileDirectory,
|
||||
this::createViewerFacade,
|
||||
|
@ -116,7 +122,7 @@ public class PerApplicationInjector {
|
|||
metadata,
|
||||
threadMaster.getWorkerExecutor(),
|
||||
versionListProvider,
|
||||
minecraftInstallation,
|
||||
minetestInstallation,
|
||||
launcherProfileRunner,
|
||||
settings);
|
||||
}
|
||||
|
|
|
@ -83,7 +83,14 @@ public class Fragment {
|
|||
private volatile CoordinatesInWorld corner;
|
||||
|
||||
private volatile float alpha;
|
||||
private volatile short[][] biomeData;
|
||||
private volatile short[][] biomeData;
|
||||
/**
|
||||
* a mask to apply to biomeData if you wish to use it like a biome index.
|
||||
* This will remove any bits from the integer that are being used
|
||||
* to indicate 1-bit overlay biome layers, such as minetest rivers
|
||||
* and oceans
|
||||
*/
|
||||
private volatile short biomeDataIndexMask; //
|
||||
private volatile List<EndIsland> endIslands;
|
||||
private final AtomicReferenceArray<BufferedImage> images;
|
||||
private final AtomicReferenceArray<List<WorldIcon>> worldIcons;
|
||||
|
@ -106,14 +113,23 @@ public class Fragment {
|
|||
}
|
||||
|
||||
@CalledOnlyBy(AmidstThread.FRAGMENT_LOADER)
|
||||
public void populateBiomeData(BiomeDataOracle biomeDataOracle) {
|
||||
biomeDataOracle.populateArray(corner, biomeData, true);
|
||||
public void populateBiomeData(IBiomeDataOracle biomeDataOracle) {
|
||||
biomeDataIndexMask = biomeDataOracle.populateArray(corner, biomeData, true);
|
||||
}
|
||||
|
||||
public short getBiomeIndexAt(int x, int y) {
|
||||
return (short)(biomeData[x][y] & biomeDataIndexMask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw data stored in the biomeData array, not to be
|
||||
* confused with getBiomeIndexAt(), as the raw data may contain
|
||||
* bitplanes so should not be treated as a short integer index.
|
||||
*/
|
||||
public short getBiomeDataAt(int x, int y) {
|
||||
return biomeData[x][y];
|
||||
}
|
||||
|
||||
|
||||
public void setEndIslands(List<EndIsland> endIslands) {
|
||||
this.endIslands = endIslands;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package amidst.fragment;
|
||||
|
||||
import amidst.mojangapi.world.coordinates.CoordinatesInWorld;
|
||||
|
||||
public interface IBiomeDataOracle {
|
||||
|
||||
// Returns the biome-index mask: a mask you should apply to the
|
||||
// returned biome data if you wish to use it like a biome index.
|
||||
// This will remove any bits from the integer that are being used
|
||||
// to indicate other things, such as 1-bit overlay biome layers
|
||||
// for minetest rivers and oceans
|
||||
public short populateArray(
|
||||
CoordinatesInWorld corner,
|
||||
short[][] result,
|
||||
boolean useQuarterResolution
|
||||
);
|
||||
}
|
|
@ -19,7 +19,7 @@ public class BiomeColorProvider implements ColorProvider {
|
|||
|
||||
@Override
|
||||
public int getColorAt(Dimension dimension, Fragment fragment, long cornerX, long cornerY, int x, int y) {
|
||||
return getColor(fragment.getBiomeDataAt(x, y));
|
||||
return getColor(fragment.getBiomeIndexAt(x, y));
|
||||
}
|
||||
|
||||
private int getColor(int biomeIndex) {
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package amidst.fragment.colorprovider;
|
||||
|
||||
import amidst.documentation.ThreadSafe;
|
||||
import amidst.fragment.Fragment;
|
||||
import amidst.mojangapi.world.Dimension;
|
||||
import amidst.minetest.world.oracle.BiomeDataOracle;
|
||||
|
||||
@ThreadSafe
|
||||
public class MinetestRiverColorProvider implements ColorProvider {
|
||||
private static final int RIVER_COLOR = 0xA0FE80FA;
|
||||
private static final int NOT_RIVER_COLOR = 0x00000000;
|
||||
|
||||
@Override
|
||||
public int getColorAt(Dimension dimension, Fragment fragment, long cornerX, long cornerY, int x, int y) {
|
||||
|
||||
if ((fragment.getBiomeDataAt(x, y) & BiomeDataOracle.BITPLANE_RIVER) > 0) {
|
||||
return RIVER_COLOR;
|
||||
} else {
|
||||
return NOT_RIVER_COLOR;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ import amidst.documentation.Immutable;
|
|||
import amidst.fragment.Fragment;
|
||||
import amidst.fragment.colorprovider.BackgroundColorProvider;
|
||||
import amidst.fragment.colorprovider.BiomeColorProvider;
|
||||
import amidst.fragment.colorprovider.MinetestRiverColorProvider;
|
||||
import amidst.fragment.colorprovider.SlimeColorProvider;
|
||||
import amidst.fragment.colorprovider.TheEndColorProvider;
|
||||
import amidst.fragment.constructor.BiomeDataConstructor;
|
||||
|
@ -54,6 +55,9 @@ public class LayerBuilder {
|
|||
new BiomeDataConstructor(Resolution.QUARTER),
|
||||
new EndIslandsConstructor(),
|
||||
new ImageConstructor(Resolution.QUARTER, LayerIds.BACKGROUND),
|
||||
new ImageConstructor(Resolution.QUARTER, LayerIds.MINETEST_RIVER),
|
||||
new ImageConstructor(Resolution.QUARTER, LayerIds.MINETEST_OCEAN),
|
||||
new ImageConstructor(Resolution.QUARTER, LayerIds.MINETEST_MOUNTAIN),
|
||||
new ImageConstructor(Resolution.CHUNK, LayerIds.SLIME)));
|
||||
}
|
||||
|
||||
|
@ -99,6 +103,11 @@ public class LayerBuilder {
|
|||
declare(settings, declarations, versionFeatures, LayerIds.OCEAN_MONUMENT, Dimension.OVERWORLD, false, settings.showOceanMonuments);
|
||||
declare(settings, declarations, versionFeatures, LayerIds.NETHER_FORTRESS, Dimension.OVERWORLD, false, settings.showNetherFortresses);
|
||||
declare(settings, declarations, versionFeatures, LayerIds.END_CITY, Dimension.END, false, settings.showEndCities);
|
||||
|
||||
declare(settings, declarations, versionFeatures, LayerIds.MINETEST_RIVER, Dimension.OVERWORLD, false, settings.showMinetestRivers);
|
||||
declare(settings, declarations, versionFeatures, LayerIds.MINETEST_OCEAN, Dimension.OVERWORLD, false, settings.showMinetestOceans);
|
||||
declare(settings, declarations, versionFeatures, LayerIds.MINETEST_MOUNTAIN, Dimension.OVERWORLD, false, settings.showMinetestMountains);
|
||||
|
||||
// @formatter:on
|
||||
return Collections.unmodifiableList(Arrays.asList(declarations));
|
||||
}
|
||||
|
@ -134,6 +143,7 @@ public class LayerBuilder {
|
|||
new BiomeDataLoader( declarations.get(LayerIds.BIOME_DATA), world.getBiomeDataOracle()),
|
||||
new EndIslandsLoader( declarations.get(LayerIds.END_ISLANDS), world.getEndIslandOracle()),
|
||||
new ImageLoader( declarations.get(LayerIds.BACKGROUND), Resolution.QUARTER, new BackgroundColorProvider(new BiomeColorProvider(biomeSelection, settings.biomeProfileSelection), new TheEndColorProvider())),
|
||||
new ImageLoader( declarations.get(LayerIds.MINETEST_RIVER), Resolution.QUARTER, new MinetestRiverColorProvider()),
|
||||
new ImageLoader( declarations.get(LayerIds.SLIME), Resolution.CHUNK, new SlimeColorProvider(world.getSlimeChunkOracle())),
|
||||
new WorldIconLoader<>(declarations.get(LayerIds.SPAWN), world.getSpawnProducer()),
|
||||
new WorldIconLoader<>(declarations.get(LayerIds.STRONGHOLD), world.getStrongholdProducer()),
|
||||
|
@ -160,6 +170,7 @@ public class LayerBuilder {
|
|||
return Collections.unmodifiableList(Arrays.asList(
|
||||
new AlphaUpdater( declarations.get(LayerIds.ALPHA)),
|
||||
new ImageDrawer( declarations.get(LayerIds.BACKGROUND), Resolution.QUARTER, accelerationCounter),
|
||||
new ImageDrawer( declarations.get(LayerIds.MINETEST_RIVER), Resolution.QUARTER, accelerationCounter),
|
||||
new ImageDrawer( declarations.get(LayerIds.SLIME), Resolution.CHUNK, accelerationCounter),
|
||||
new GridDrawer( declarations.get(LayerIds.GRID), zoom),
|
||||
new WorldIconDrawer(declarations.get(LayerIds.SPAWN), zoom, worldIconSelection),
|
||||
|
|
|
@ -24,6 +24,12 @@ public class LayerIds {
|
|||
public static final int OCEAN_MONUMENT = 12;
|
||||
public static final int NETHER_FORTRESS = 13;
|
||||
public static final int END_CITY = 14;
|
||||
public static final int NUMBER_OF_LAYERS = 15;
|
||||
|
||||
public static final int MINETEST_RIVER = 15;
|
||||
public static final int MINETEST_OCEAN = 16;
|
||||
public static final int MINETEST_MOUNTAIN = 17;
|
||||
|
||||
public static final int NUMBER_OF_LAYERS = 18;
|
||||
|
||||
// @formatter:on
|
||||
}
|
||||
|
|
|
@ -4,15 +4,15 @@ import amidst.documentation.AmidstThread;
|
|||
import amidst.documentation.CalledOnlyBy;
|
||||
import amidst.documentation.NotThreadSafe;
|
||||
import amidst.fragment.Fragment;
|
||||
import amidst.fragment.IBiomeDataOracle;
|
||||
import amidst.fragment.layer.LayerDeclaration;
|
||||
import amidst.mojangapi.world.Dimension;
|
||||
import amidst.mojangapi.world.oracle.BiomeDataOracle;
|
||||
|
||||
@NotThreadSafe
|
||||
public class BiomeDataLoader extends FragmentLoader {
|
||||
private final BiomeDataOracle biomeDataOracle;
|
||||
private final IBiomeDataOracle biomeDataOracle;
|
||||
|
||||
public BiomeDataLoader(LayerDeclaration declaration, BiomeDataOracle biomeDataOracle) {
|
||||
public BiomeDataLoader(LayerDeclaration declaration, IBiomeDataOracle biomeDataOracle) {
|
||||
super(declaration);
|
||||
this.biomeDataOracle = biomeDataOracle;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package amidst.gameengineabstraction;
|
||||
|
||||
public enum GameEngineType {
|
||||
|
||||
MINECRAFT ("Minecraft"),
|
||||
MINETESTv7 ("Minetest v7");
|
||||
|
||||
private final String name;
|
||||
|
||||
private GameEngineType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package amidst.gameengineabstraction.file;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import amidst.mojangapi.file.SaveGame;
|
||||
import amidst.parsing.FormatException;
|
||||
|
||||
/**
|
||||
* base interface for MinetestInstallation and MinecraftInstallation
|
||||
*/
|
||||
public interface IGameInstallation {
|
||||
|
||||
public List<IUnresolvedLauncherProfile> readLauncherProfiles() throws FormatException, IOException;
|
||||
|
||||
public SaveGame newSaveGame(File location) throws IOException, FormatException;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package amidst.gameengineabstraction.file;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import amidst.mojangapi.file.LauncherProfile;
|
||||
import amidst.mojangapi.file.VersionList;
|
||||
import amidst.parsing.FormatException;
|
||||
|
||||
public interface IUnresolvedLauncherProfile {
|
||||
|
||||
public String getName();
|
||||
|
||||
public LauncherProfile resolve(VersionList versionList) throws FormatException, IOException;
|
||||
|
||||
public LauncherProfile resolveToVanilla(VersionList versionList) throws FormatException, IOException;
|
||||
|
||||
}
|
|
@ -16,6 +16,7 @@ import amidst.Application;
|
|||
import amidst.documentation.AmidstThread;
|
||||
import amidst.documentation.CalledOnlyBy;
|
||||
import amidst.documentation.NotThreadSafe;
|
||||
import amidst.gameengineabstraction.GameEngineType;
|
||||
import amidst.gui.crash.CrashWindow;
|
||||
import amidst.gui.main.menu.MovePlayerPopupMenu;
|
||||
import amidst.gui.main.viewer.ViewerFacade;
|
||||
|
@ -39,6 +40,7 @@ public class Actions {
|
|||
private final SeedSearcherWindow seedSearcherWindow;
|
||||
private final Supplier<ViewerFacade> viewerFacadeSupplier;
|
||||
private final BiomeProfileSelection biomeProfileSelection;
|
||||
private final GameEngineType gameEngineType;
|
||||
|
||||
@CalledOnlyBy(AmidstThread.EDT)
|
||||
public Actions(
|
||||
|
@ -47,18 +49,20 @@ public class Actions {
|
|||
WorldSwitcher worldSwitcher,
|
||||
SeedSearcherWindow seedSearcherWindow,
|
||||
Supplier<ViewerFacade> viewerFacadeSupplier,
|
||||
BiomeProfileSelection biomeProfileSelection) {
|
||||
BiomeProfileSelection biomeProfileSelection,
|
||||
GameEngineType gameEngineType) {
|
||||
this.application = application;
|
||||
this.dialogs = dialogs;
|
||||
this.worldSwitcher = worldSwitcher;
|
||||
this.seedSearcherWindow = seedSearcherWindow;
|
||||
this.viewerFacadeSupplier = viewerFacadeSupplier;
|
||||
this.biomeProfileSelection = biomeProfileSelection;
|
||||
this.gameEngineType = gameEngineType;
|
||||
}
|
||||
|
||||
@CalledOnlyBy(AmidstThread.EDT)
|
||||
public void newFromSeed() {
|
||||
WorldSeed seed = dialogs.askForSeed();
|
||||
WorldSeed seed = dialogs.askForSeed(gameEngineType);
|
||||
if (seed != null) {
|
||||
newFromSeed(seed);
|
||||
}
|
||||
|
@ -66,7 +70,7 @@ public class Actions {
|
|||
|
||||
@CalledOnlyBy(AmidstThread.EDT)
|
||||
public void newFromRandom() {
|
||||
newFromSeed(WorldSeed.random());
|
||||
newFromSeed(WorldSeed.random(gameEngineType));
|
||||
}
|
||||
|
||||
@CalledOnlyBy(AmidstThread.EDT)
|
||||
|
|
|
@ -11,6 +11,7 @@ import amidst.AmidstSettings;
|
|||
import amidst.documentation.AmidstThread;
|
||||
import amidst.documentation.CalledOnlyBy;
|
||||
import amidst.documentation.NotThreadSafe;
|
||||
import amidst.gameengineabstraction.GameEngineType;
|
||||
import amidst.logging.AmidstMessageBox;
|
||||
import amidst.mojangapi.RunningLauncherProfile;
|
||||
import amidst.mojangapi.world.WorldSeed;
|
||||
|
@ -41,8 +42,8 @@ public class MainWindowDialogs {
|
|||
}
|
||||
|
||||
@CalledOnlyBy(AmidstThread.EDT)
|
||||
public WorldSeed askForSeed() {
|
||||
return new SeedPrompt(frame).askForSeed();
|
||||
public WorldSeed askForSeed(GameEngineType engine_type) {
|
||||
return new SeedPrompt(frame, engine_type).askForSeed();
|
||||
}
|
||||
|
||||
@CalledOnlyBy(AmidstThread.EDT)
|
||||
|
|
|
@ -13,13 +13,14 @@ import amidst.dependency.injection.Factory2;
|
|||
import amidst.documentation.AmidstThread;
|
||||
import amidst.documentation.CalledOnlyBy;
|
||||
import amidst.documentation.NotThreadSafe;
|
||||
import amidst.gameengineabstraction.GameEngineType;
|
||||
import amidst.gameengineabstraction.file.IGameInstallation;
|
||||
import amidst.gui.main.menu.AmidstMenu;
|
||||
import amidst.gui.main.menu.AmidstMenuBuilder;
|
||||
import amidst.gui.main.viewer.ViewerFacade;
|
||||
import amidst.gui.seedsearcher.SeedSearcher;
|
||||
import amidst.gui.seedsearcher.SeedSearcherWindow;
|
||||
import amidst.mojangapi.RunningLauncherProfile;
|
||||
import amidst.mojangapi.file.MinecraftInstallation;
|
||||
import amidst.mojangapi.world.World;
|
||||
import amidst.settings.biomeprofile.BiomeProfileDirectory;
|
||||
import amidst.threading.ThreadMaster;
|
||||
|
@ -52,17 +53,21 @@ public class PerMainWindowInjector {
|
|||
private final Actions actions;
|
||||
private final AmidstMenu menuBar;
|
||||
private final MainWindow mainWindow;
|
||||
private final GameEngineType gameEngine;
|
||||
|
||||
@CalledOnlyBy(AmidstThread.EDT)
|
||||
public PerMainWindowInjector(
|
||||
Application application,
|
||||
AmidstMetaData metadata,
|
||||
AmidstSettings settings,
|
||||
MinecraftInstallation minecraftInstallation,
|
||||
IGameInstallation gameInstallation,
|
||||
RunningLauncherProfile runningLauncherProfile,
|
||||
BiomeProfileDirectory biomeProfileDirectory,
|
||||
Factory2<World, Actions, ViewerFacade> viewerFacadeFactory,
|
||||
ThreadMaster threadMaster) {
|
||||
|
||||
gameEngine = runningLauncherProfile.getGameEngineType();
|
||||
|
||||
this.viewerFacadeFactory = viewerFacadeFactory;
|
||||
this.versionString = createVersionString(metadata, runningLauncherProfile);
|
||||
this.frame = new JFrame();
|
||||
|
@ -70,7 +75,7 @@ public class PerMainWindowInjector {
|
|||
this.viewerFacadeReference = new AtomicReference<>();
|
||||
this.dialogs = new MainWindowDialogs(settings, runningLauncherProfile, frame);
|
||||
this.worldSwitcher = new WorldSwitcher(
|
||||
minecraftInstallation,
|
||||
gameInstallation,
|
||||
runningLauncherProfile,
|
||||
this::createViewerFacade,
|
||||
threadMaster,
|
||||
|
@ -95,7 +100,8 @@ public class PerMainWindowInjector {
|
|||
worldSwitcher,
|
||||
seedSearcherWindow,
|
||||
viewerFacadeReference::get,
|
||||
settings.biomeProfileSelection);
|
||||
settings.biomeProfileSelection,
|
||||
gameEngine);
|
||||
this.menuBar = new AmidstMenuBuilder(settings, actions, biomeProfileDirectory).construct();
|
||||
this.mainWindow = new MainWindow(frame, worldSwitcher, seedSearcherWindow);
|
||||
this.mainWindow.initializeFrame(metadata, versionString, actions, menuBar);
|
||||
|
|
|
@ -15,6 +15,7 @@ import javax.swing.event.DocumentEvent;
|
|||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import amidst.documentation.NotThreadSafe;
|
||||
import amidst.gameengineabstraction.GameEngineType;
|
||||
import amidst.mojangapi.world.WorldSeed;
|
||||
import amidst.mojangapi.world.WorldSeed.WorldSeedType;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
@ -31,13 +32,16 @@ public class SeedPrompt {
|
|||
private final JLabel warningLabel;
|
||||
private final JPanel panel;
|
||||
private WorldSeed seed;
|
||||
private GameEngineType engineType;
|
||||
|
||||
public SeedPrompt(JFrame frame) {
|
||||
public SeedPrompt(JFrame frame, GameEngineType engine_type) {
|
||||
this.frame = frame;
|
||||
this.textField = createTextField();
|
||||
this.seedLabel = createSeedLabel();
|
||||
this.warningLabel = createWarningLabel();
|
||||
this.panel = createPanel();
|
||||
|
||||
this.engineType = engine_type;
|
||||
}
|
||||
|
||||
private JTextField createTextField() {
|
||||
|
@ -111,7 +115,8 @@ public class SeedPrompt {
|
|||
}
|
||||
|
||||
private void update() {
|
||||
seed = WorldSeed.fromUserInput(textField.getText());
|
||||
|
||||
seed = WorldSeed.fromUserInput(textField.getText(), engineType);
|
||||
if (WorldSeedType.TEXT == seed.getType() && seed.getText().startsWith(" ")) {
|
||||
warningLabel.setText(STARTS_WITH_SPACE_TEXT);
|
||||
} else if (WorldSeedType.TEXT == seed.getType() && seed.getText().endsWith(" ")) {
|
||||
|
|
|
@ -15,9 +15,9 @@ import amidst.documentation.CalledOnlyBy;
|
|||
import amidst.documentation.NotThreadSafe;
|
||||
import amidst.gui.main.menu.AmidstMenu;
|
||||
import amidst.gui.main.viewer.ViewerFacade;
|
||||
import amidst.gameengineabstraction.file.IGameInstallation;
|
||||
import amidst.logging.AmidstLogger;
|
||||
import amidst.mojangapi.RunningLauncherProfile;
|
||||
import amidst.mojangapi.file.MinecraftInstallation;
|
||||
import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException;
|
||||
import amidst.mojangapi.world.World;
|
||||
import amidst.mojangapi.world.WorldSeed;
|
||||
|
@ -29,7 +29,7 @@ import amidst.threading.ThreadMaster;
|
|||
|
||||
@NotThreadSafe
|
||||
public class WorldSwitcher {
|
||||
private final MinecraftInstallation minecraftInstallation;
|
||||
private final IGameInstallation minecraftInstallation;
|
||||
private final RunningLauncherProfile runningLauncherProfile;
|
||||
private final Factory1<World, ViewerFacade> viewerFacadeFactory;
|
||||
private final ThreadMaster threadMaster;
|
||||
|
@ -41,7 +41,7 @@ public class WorldSwitcher {
|
|||
|
||||
@CalledOnlyBy(AmidstThread.EDT)
|
||||
public WorldSwitcher(
|
||||
MinecraftInstallation minecraftInstallation,
|
||||
IGameInstallation minecraftInstallation,
|
||||
RunningLauncherProfile runningLauncherProfile,
|
||||
Factory1<World, ViewerFacade> viewerFacadeFactory,
|
||||
ThreadMaster threadMaster,
|
||||
|
@ -75,9 +75,9 @@ public class WorldSwitcher {
|
|||
@CalledOnlyBy(AmidstThread.EDT)
|
||||
public void displayWorld(File file) {
|
||||
try {
|
||||
clearViewerFacade();
|
||||
clearViewerFacade();
|
||||
setWorld(runningLauncherProfile.createWorldFromSaveGame(minecraftInstallation.newSaveGame(file)));
|
||||
} catch (IllegalStateException | MinecraftInterfaceException | IOException | FormatException e) {
|
||||
} catch (IllegalStateException | MinecraftInterfaceException | IOException | FormatException | UnsupportedOperationException e) {
|
||||
AmidstLogger.warn(e);
|
||||
dialogs.displayError(e);
|
||||
}
|
||||
|
|
|
@ -61,7 +61,13 @@ public class LayersMenu {
|
|||
|
||||
@CalledOnlyBy(AmidstThread.EDT)
|
||||
private void createDimensionLayers(Dimension dimension) {
|
||||
if (viewerFacade.hasLayer(LayerIds.END_ISLANDS)) {
|
||||
if (viewerFacade.hasLayer(LayerIds.MINETEST_OCEAN)) {
|
||||
createAllDimensions();
|
||||
menu.addSeparator();
|
||||
createMinetestLayers(dimension);
|
||||
createEnableAllLayersIfNecessary();
|
||||
|
||||
} else if (viewerFacade.hasLayer(LayerIds.END_ISLANDS)) {
|
||||
createAllDimensions();
|
||||
menu.addSeparator();
|
||||
createOverworldAndEndLayers(dimension);
|
||||
|
@ -96,6 +102,21 @@ public class LayersMenu {
|
|||
// @formatter:on
|
||||
}
|
||||
|
||||
@CalledOnlyBy(AmidstThread.EDT)
|
||||
private void createMinetestLayers(Dimension dimension) {
|
||||
// @formatter:off
|
||||
overworldLayer(settings.showMinetestRivers, "Rivers", getIcon("slime.png"), MenuShortcuts.SHOW_MINETEST_RIVERS, dimension, LayerIds.MINETEST_RIVER);
|
||||
overworldLayer(settings.showMinetestOceans, "Oceans", getIcon("slime.png"), MenuShortcuts.SHOW_MINETEST_OCEANS, dimension, LayerIds.MINETEST_OCEAN);
|
||||
overworldLayer(settings.showMinetestMountains, "Mountains", getIcon("slime.png"), MenuShortcuts.SHOW_MINETEST_MOUNTAINS, dimension, LayerIds.MINETEST_MOUNTAIN);
|
||||
|
||||
// temp for debug
|
||||
// (Remove SLIME from DefaultVersionFeatures as well when finished)
|
||||
if (viewerFacade.hasLayer(LayerIds.SLIME)) {
|
||||
overworldLayer(settings.showSlimeChunks, "Slime Chunks", getIcon("slime.png"), MenuShortcuts.SHOW_SLIME_CHUNKS, dimension, LayerIds.SLIME);
|
||||
}
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@CalledOnlyBy(AmidstThread.EDT)
|
||||
private void createOverworldLayers(Dimension dimension) {
|
||||
// @formatter:off
|
||||
|
|
|
@ -42,6 +42,11 @@ public enum MenuShortcuts implements MenuShortcut {
|
|||
SHOW_OCEAN_MONUMENTS("menu 7"),
|
||||
SHOW_NETHER_FORTRESSES("menu 8"),
|
||||
SHOW_END_CITIES("menu 9"),
|
||||
|
||||
SHOW_MINETEST_RIVERS("menu 1"),
|
||||
SHOW_MINETEST_OCEANS("menu 2"),
|
||||
SHOW_MINETEST_MOUNTAINS("menu 3"),
|
||||
|
||||
SHOW_GRID("menu G"),
|
||||
SHOW_PLAYERS("menu P"),
|
||||
ENABLE_ALL_LAYERS("menu E"),
|
||||
|
|
|
@ -71,7 +71,7 @@ public class CursorInformationWidget extends TextWidget {
|
|||
if (fragment != null && fragment.isLoaded()) {
|
||||
long x = coordinates.getXRelativeToFragmentAs(Resolution.QUARTER);
|
||||
long y = coordinates.getYRelativeToFragmentAs(Resolution.QUARTER);
|
||||
short biome = fragment.getBiomeDataAt((int) x, (int) y);
|
||||
short biome = fragment.getBiomeIndexAt((int) x, (int) y);
|
||||
try {
|
||||
return Biome.getByIndex(biome).getName();
|
||||
} catch (UnknownBiomeIndexException e) {
|
||||
|
|
|
@ -9,10 +9,10 @@ import amidst.documentation.CalledOnlyBy;
|
|||
import amidst.documentation.NotThreadSafe;
|
||||
import amidst.logging.AmidstLogger;
|
||||
import amidst.logging.AmidstMessageBox;
|
||||
import amidst.gameengineabstraction.file.IUnresolvedLauncherProfile;
|
||||
import amidst.mojangapi.LauncherProfileRunner;
|
||||
import amidst.mojangapi.RunningLauncherProfile;
|
||||
import amidst.mojangapi.file.LauncherProfile;
|
||||
import amidst.mojangapi.file.UnresolvedLauncherProfile;
|
||||
import amidst.mojangapi.file.VersionListProvider;
|
||||
import amidst.mojangapi.minecraftinterface.local.LocalMinecraftInterfaceCreationException;
|
||||
import amidst.parsing.FormatException;
|
||||
|
@ -24,7 +24,7 @@ public class LocalProfileComponent extends ProfileComponent {
|
|||
private final WorkerExecutor workerExecutor;
|
||||
private final VersionListProvider versionListProvider;
|
||||
private final LauncherProfileRunner launcherProfileRunner;
|
||||
private final UnresolvedLauncherProfile unresolvedProfile;
|
||||
private final IUnresolvedLauncherProfile unresolvedProfile;
|
||||
|
||||
private volatile boolean isResolving = false;
|
||||
private volatile boolean failedResolving = false;
|
||||
|
@ -38,7 +38,7 @@ public class LocalProfileComponent extends ProfileComponent {
|
|||
WorkerExecutor workerExecutor,
|
||||
VersionListProvider versionListProvider,
|
||||
LauncherProfileRunner launcherProfileRunner,
|
||||
UnresolvedLauncherProfile unresolvedProfile) {
|
||||
IUnresolvedLauncherProfile unresolvedProfile) {
|
||||
this.application = application;
|
||||
this.workerExecutor = workerExecutor;
|
||||
this.versionListProvider = versionListProvider;
|
||||
|
|
|
@ -20,9 +20,9 @@ import amidst.documentation.CalledOnlyBy;
|
|||
import amidst.documentation.NotThreadSafe;
|
||||
import amidst.logging.AmidstLogger;
|
||||
import amidst.logging.AmidstMessageBox;
|
||||
import amidst.gameengineabstraction.file.IGameInstallation;
|
||||
import amidst.gameengineabstraction.file.IUnresolvedLauncherProfile;
|
||||
import amidst.mojangapi.LauncherProfileRunner;
|
||||
import amidst.mojangapi.file.MinecraftInstallation;
|
||||
import amidst.mojangapi.file.UnresolvedLauncherProfile;
|
||||
import amidst.mojangapi.file.VersionListProvider;
|
||||
import amidst.parsing.FormatException;
|
||||
import amidst.threading.WorkerExecutor;
|
||||
|
@ -36,7 +36,7 @@ public class ProfileSelectWindow {
|
|||
private final AmidstMetaData metadata;
|
||||
private final WorkerExecutor workerExecutor;
|
||||
private final VersionListProvider versionListProvider;
|
||||
private final MinecraftInstallation minecraftInstallation;
|
||||
private final IGameInstallation gameInstallation;
|
||||
private final LauncherProfileRunner launcherProfileRunner;
|
||||
private final AmidstSettings settings;
|
||||
|
||||
|
@ -51,14 +51,14 @@ public class ProfileSelectWindow {
|
|||
AmidstMetaData metadata,
|
||||
WorkerExecutor workerExecutor,
|
||||
VersionListProvider versionListProvider,
|
||||
MinecraftInstallation minecraftInstallation,
|
||||
IGameInstallation gameInstallation,
|
||||
LauncherProfileRunner launcherProfileRunner,
|
||||
AmidstSettings settings) {
|
||||
this.application = application;
|
||||
this.metadata = metadata;
|
||||
this.workerExecutor = workerExecutor;
|
||||
this.versionListProvider = versionListProvider;
|
||||
this.minecraftInstallation = minecraftInstallation;
|
||||
this.gameInstallation = gameInstallation;
|
||||
this.launcherProfileRunner = launcherProfileRunner;
|
||||
this.settings = settings;
|
||||
this.profileSelectPanel = new ProfileSelectPanel(settings.lastProfile, "Scanning...");
|
||||
|
@ -122,22 +122,22 @@ public class ProfileSelectWindow {
|
|||
}
|
||||
|
||||
@CalledOnlyBy(AmidstThread.WORKER)
|
||||
private List<UnresolvedLauncherProfile> scanAndLoadProfiles() throws FormatException, IOException {
|
||||
private List<IUnresolvedLauncherProfile> scanAndLoadProfiles() throws FormatException, IOException {
|
||||
AmidstLogger.info("Scanning for profiles.");
|
||||
List<UnresolvedLauncherProfile> launcherProfiles = minecraftInstallation.readLauncherProfiles();
|
||||
List<IUnresolvedLauncherProfile> launcherProfiles = gameInstallation.readLauncherProfiles();
|
||||
AmidstLogger.info("Successfully loaded profile list.");
|
||||
return launcherProfiles;
|
||||
}
|
||||
|
||||
@CalledOnlyBy(AmidstThread.EDT)
|
||||
private void displayProfiles(List<UnresolvedLauncherProfile> launcherProfiles) {
|
||||
private void displayProfiles(List<IUnresolvedLauncherProfile> launcherProfiles) {
|
||||
createProfileComponentsIfNecessary(launcherProfiles);
|
||||
restoreSelection();
|
||||
frame.pack();
|
||||
}
|
||||
|
||||
@CalledOnlyBy(AmidstThread.EDT)
|
||||
private void createProfileComponentsIfNecessary(List<UnresolvedLauncherProfile> launcherProfiles) {
|
||||
private void createProfileComponentsIfNecessary(List<IUnresolvedLauncherProfile> launcherProfiles) {
|
||||
if (launcherProfiles.isEmpty()) {
|
||||
AmidstLogger.warn("No profiles found in launcher_profiles.json");
|
||||
profileSelectPanel.setEmptyMessage("No profiles found");
|
||||
|
@ -155,8 +155,8 @@ public class ProfileSelectWindow {
|
|||
}
|
||||
|
||||
@CalledOnlyBy(AmidstThread.EDT)
|
||||
private void createProfileComponents(List<UnresolvedLauncherProfile> launcherProfiles) {
|
||||
for (UnresolvedLauncherProfile profile : launcherProfiles) {
|
||||
private void createProfileComponents(List<IUnresolvedLauncherProfile> launcherProfiles) {
|
||||
for (IUnresolvedLauncherProfile profile : launcherProfiles) {
|
||||
profileSelectPanel.addProfile(
|
||||
new LocalProfileComponent(
|
||||
application,
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.function.Consumer;
|
|||
import amidst.documentation.AmidstThread;
|
||||
import amidst.documentation.CalledOnlyBy;
|
||||
import amidst.documentation.NotThreadSafe;
|
||||
import amidst.gameengineabstraction.GameEngineType;
|
||||
import amidst.gui.main.MainWindowDialogs;
|
||||
import amidst.logging.AmidstLogger;
|
||||
import amidst.mojangapi.RunningLauncherProfile;
|
||||
|
@ -93,7 +94,7 @@ public class SeedSearcher {
|
|||
throws IllegalStateException,
|
||||
MinecraftInterfaceException {
|
||||
while (!isStopRequested) {
|
||||
World world = runningLauncherProfile.createWorldFromSeed(WorldSeed.random(), configuration.getWorldType());
|
||||
World world = runningLauncherProfile.createWorldFromSeed(WorldSeed.random(GameEngineType.MINECRAFT), configuration.getWorldType());
|
||||
if (configuration.getWorldFilter().isValid(world)) {
|
||||
reporter.report(world.getWorldSeed());
|
||||
world.dispose();
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package amidst.minetest;
|
||||
|
||||
import amidst.minetest.file.directory.MinetestDirectory;
|
||||
import amidst.minetest.world.mapgen.MapgenV7Params;
|
||||
import amidst.mojangapi.file.LauncherProfile;
|
||||
import amidst.mojangapi.file.json.version.VersionJson;
|
||||
|
||||
public class MinetestLauncherProfile extends LauncherProfile {
|
||||
|
||||
// Can be null! (minetest might not be installed, and we might be using
|
||||
// defaults)
|
||||
private final MinetestDirectory minetestDirectory;
|
||||
|
||||
public static MinetestLauncherProfile InternalDefault = new MinetestLauncherProfile(
|
||||
null, "Minetest mapgen v7 default");
|
||||
|
||||
public MinetestLauncherProfile(MinetestDirectory minetestDirectory,
|
||||
String profileName) {
|
||||
|
||||
super(null, // dotMinecraftDirectory,
|
||||
null, // profileDirectory,
|
||||
null, // versionDirectory,
|
||||
new VersionJson("v7", null), // versionJson,
|
||||
true, // isVersionListedInProfile,
|
||||
profileName);
|
||||
|
||||
this.minetestDirectory = minetestDirectory;
|
||||
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public MapgenV7Params getMapGenParams() {
|
||||
|
||||
// TODO: fetch the MapgenV7Params from MinetestDirectory
|
||||
return new MapgenV7Params();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package amidst.minetest;
|
||||
|
||||
import amidst.gameengineabstraction.GameEngineType;
|
||||
import amidst.minetest.world.mapgen.MapgenV7Params;
|
||||
import amidst.mojangapi.minecraftinterface.MinecraftInterface;
|
||||
import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException;
|
||||
import amidst.mojangapi.minecraftinterface.RecognisedVersion;
|
||||
import amidst.mojangapi.world.WorldType;
|
||||
|
||||
public class MinetestMapgenV7Interface implements MinecraftInterface {
|
||||
|
||||
public final MapgenV7Params params;
|
||||
|
||||
public MinetestMapgenV7Interface(MapgenV7Params params) {
|
||||
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getBiomeData(int x, int y, int width, int height,
|
||||
boolean useQuarterResolution) throws MinecraftInterfaceException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWorld(long seed, WorldType worldType,
|
||||
String generatorOptions) throws MinecraftInterfaceException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecognisedVersion getRecognisedVersion() {
|
||||
return RecognisedVersion.Minetest_v7;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameEngineType getGameEngineType() {
|
||||
return GameEngineType.MINETESTv7;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
package amidst.minetest.file;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import amidst.documentation.Immutable;
|
||||
import amidst.logging.AmidstLogger;
|
||||
import amidst.gameengineabstraction.file.IUnresolvedLauncherProfile;
|
||||
import amidst.gameengineabstraction.file.IGameInstallation;
|
||||
import amidst.minetest.MinetestLauncherProfile;
|
||||
import amidst.minetest.file.directory.MinetestDirectory;
|
||||
import amidst.minetest.file.service.MinetestDirectoryService;
|
||||
import amidst.minetest.file.UnresolvedLauncherProfile;
|
||||
import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException;
|
||||
import amidst.mojangapi.file.LauncherProfile;
|
||||
import amidst.mojangapi.file.SaveGame;
|
||||
import amidst.mojangapi.file.directory.DotMinecraftDirectory;
|
||||
import amidst.mojangapi.file.directory.SaveDirectory;
|
||||
import amidst.mojangapi.file.directory.VersionDirectory;
|
||||
import amidst.mojangapi.file.json.version.VersionJson;
|
||||
import amidst.mojangapi.file.service.DotMinecraftDirectoryService;
|
||||
import amidst.mojangapi.file.service.SaveDirectoryService;
|
||||
import amidst.parsing.FormatException;
|
||||
import amidst.parsing.json.JsonReader;
|
||||
|
||||
@Immutable
|
||||
public class MinetestInstallation implements IGameInstallation {
|
||||
|
||||
public static MinetestInstallation newLocalMinetestInstallation() throws DotMinecraftDirectoryNotFoundException {
|
||||
return newLocalMinetestInstallationOrDefault(null);
|
||||
}
|
||||
|
||||
public static MinetestInstallation newLocalMinetestInstallationOrDefault(String preferredMinetestDirectory) {
|
||||
|
||||
MinetestDirectory minetestDirectory = null;
|
||||
try {
|
||||
minetestDirectory = new MinetestDirectoryService()
|
||||
.createMinetestDirectory(preferredMinetestDirectory);
|
||||
AmidstLogger.info("using minetest directory at: '" + minetestDirectory.getRoot() + "'");
|
||||
} catch (DotMinecraftDirectoryNotFoundException e) {
|
||||
|
||||
AmidstLogger.info("Minetest directory not found, using default mapgen v7 profile");
|
||||
}
|
||||
return new MinetestInstallation(minetestDirectory);
|
||||
}
|
||||
|
||||
private final MinetestDirectoryService minetestDirectoryService = new MinetestDirectoryService();
|
||||
private final MinetestDirectory minetestDirectory;
|
||||
|
||||
public MinetestInstallation(MinetestDirectory minetestDirectory) {
|
||||
this.minetestDirectory = minetestDirectory;
|
||||
}
|
||||
|
||||
|
||||
public Optional<LauncherProfile> defaultLauncherProfile() {
|
||||
|
||||
return Optional.of(MinetestLauncherProfile.InternalDefault);
|
||||
}
|
||||
|
||||
public SaveGame newSaveGame(File location) throws IOException, FormatException {
|
||||
//SaveDirectory saveDirectory = saveDirectoryService.newSaveDirectory(location);
|
||||
//return new SaveGame(saveDirectory, saveDirectoryService.readLevelDat(saveDirectory));
|
||||
throw new UnsupportedOperationException("need to add support for world saves");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IUnresolvedLauncherProfile> readLauncherProfiles()
|
||||
throws FormatException, IOException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
ArrayList<IUnresolvedLauncherProfile> result = new ArrayList<IUnresolvedLauncherProfile>();
|
||||
result.add(new UnresolvedLauncherProfile());
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
public List<LauncherProfile> readInstalledVersionsAsLauncherProfiles() throws FormatException, IOException {
|
||||
List<LauncherProfile> result = new LinkedList<>();
|
||||
for (VersionDirectory versionDirectory : minetestDirectoryService
|
||||
.findInstalledValidVersionDirectories(minetestDirectory)) {
|
||||
result.add(newLauncherProfile(versionDirectory));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<UnresolvedLauncherProfile> readLauncherProfiles() throws FormatException, IOException {
|
||||
return minetestDirectoryService
|
||||
.readLauncherProfilesFrom(minetestDirectory)
|
||||
.getProfiles()
|
||||
.values()
|
||||
.stream()
|
||||
.map(p -> new UnresolvedLauncherProfile(minetestDirectory, p))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public LauncherProfile newLauncherProfile(String versionId) throws FormatException, IOException {
|
||||
return newLauncherProfile(
|
||||
minetestDirectoryService.createValidVersionDirectory(minetestDirectory, versionId));
|
||||
}
|
||||
|
||||
public LauncherProfile newLauncherProfile(File jar, File json) throws FormatException, IOException {
|
||||
return newLauncherProfile(minetestDirectoryService.createValidVersionDirectory(jar, json));
|
||||
}
|
||||
|
||||
private LauncherProfile newLauncherProfile(VersionDirectory versionDirectory) throws FormatException, IOException {
|
||||
VersionJson versionJson = JsonReader.readLocation(versionDirectory.getJson(), VersionJson.class);
|
||||
return new LauncherProfile(
|
||||
minetestDirectory,
|
||||
minetestDirectory.asProfileDirectory(),
|
||||
versionDirectory,
|
||||
versionJson,
|
||||
false,
|
||||
versionJson.getId());
|
||||
}
|
||||
|
||||
public SaveGame newSaveGame(File location) throws IOException, FormatException {
|
||||
SaveDirectory saveDirectory = saveDirectoryService.newSaveDirectory(location);
|
||||
return new SaveGame(saveDirectory, saveDirectoryService.readLevelDat(saveDirectory));
|
||||
}
|
||||
|
||||
public Optional<LauncherProfile> tryReadLauncherProfile(
|
||||
String preferredMinecraftJarFile,
|
||||
String preferredMinecraftJsonFile) {
|
||||
if (preferredMinecraftJarFile != null && preferredMinecraftJsonFile != null) {
|
||||
try {
|
||||
return Optional.of(
|
||||
newLauncherProfile(new File(preferredMinecraftJarFile), new File(preferredMinecraftJsonFile)));
|
||||
} catch (FormatException | IOException e) {
|
||||
AmidstLogger.error(
|
||||
e,
|
||||
"cannot read launcher profile. preferredMinecraftJarFile: '" + preferredMinecraftJarFile
|
||||
+ "', preferredMinecraftJsonFile: '" + "'");
|
||||
return Optional.empty();
|
||||
}
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package amidst.minetest.file;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import amidst.documentation.Immutable;
|
||||
import amidst.gameengineabstraction.file.IUnresolvedLauncherProfile;
|
||||
import amidst.minetest.MinetestLauncherProfile;
|
||||
import amidst.minetest.file.directory.MinetestDirectory;
|
||||
import amidst.mojangapi.file.LauncherProfile;
|
||||
import amidst.mojangapi.file.VersionList;
|
||||
import amidst.parsing.FormatException;
|
||||
|
||||
@Immutable
|
||||
public class UnresolvedLauncherProfile implements IUnresolvedLauncherProfile {
|
||||
private final MinetestDirectory minetestDirectory;
|
||||
private final String name;
|
||||
|
||||
public UnresolvedLauncherProfile(
|
||||
MinetestDirectory minetestDirectory,
|
||||
String name) {
|
||||
this.minetestDirectory = minetestDirectory;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public UnresolvedLauncherProfile() {
|
||||
this.minetestDirectory = null;
|
||||
this.name = MinetestLauncherProfile.InternalDefault.getProfileName();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LauncherProfile resolve(VersionList versionList) throws FormatException, IOException {
|
||||
return new MinetestLauncherProfile(minetestDirectory, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LauncherProfile resolveToVanilla(VersionList versionList) throws FormatException, IOException {
|
||||
// Vanilla is a concept for modded Minecraft, Minetest doesn't need it.
|
||||
return resolve(versionList);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package amidst.minetest.file.directory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Objects;
|
||||
|
||||
import amidst.documentation.Immutable;
|
||||
|
||||
@Immutable
|
||||
public class MinetestDirectory {
|
||||
/**
|
||||
* Allows to customize all parts of the minetest directory, mainly for
|
||||
* testing and the dev tools. Pass null to use default values.
|
||||
*/
|
||||
public static MinetestDirectory newCustom(
|
||||
File root,
|
||||
File games,
|
||||
File worlds,
|
||||
File mods,
|
||||
File launcherProfilesJson) {
|
||||
Objects.requireNonNull(root);
|
||||
return new MinetestDirectory(
|
||||
root,
|
||||
games != null ? games : new File(root, "games"),
|
||||
worlds != null ? worlds : new File(root, "worlds"),
|
||||
mods != null ? mods : new File(root, "mods"),
|
||||
launcherProfilesJson != null ? launcherProfilesJson : new File(root, "launcher_profiles.json"));
|
||||
}
|
||||
|
||||
private final File root;
|
||||
private final File mods;
|
||||
private final File worlds;
|
||||
private final File games;
|
||||
private final File launcherProfilesJson;
|
||||
|
||||
public MinetestDirectory(File root) {
|
||||
this.root = root;
|
||||
this.mods = new File(root, "mods");
|
||||
this.worlds = new File(root, "worlds");
|
||||
this.games = new File(root, "games");
|
||||
this.launcherProfilesJson = new File(root, "launcher_profiles.json");
|
||||
}
|
||||
|
||||
private MinetestDirectory(File root, File games, File worlds, File mods, File launcherProfilesJson) {
|
||||
this.root = root;
|
||||
this.games = games;
|
||||
this.worlds = worlds;
|
||||
this.mods = mods;
|
||||
this.launcherProfilesJson = launcherProfilesJson;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return root.isDirectory() && mods.isDirectory() && games.isDirectory() && launcherProfilesJson.isFile();
|
||||
}
|
||||
|
||||
public File getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
public File getMods() {
|
||||
return mods;
|
||||
}
|
||||
|
||||
public File getWorlds() {
|
||||
return worlds;
|
||||
}
|
||||
|
||||
public File getGames() {
|
||||
return games;
|
||||
}
|
||||
|
||||
public File getLauncherProfilesJson() {
|
||||
return launcherProfilesJson;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package amidst.minetest.file.service;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import amidst.documentation.Immutable;
|
||||
import amidst.documentation.NotNull;
|
||||
import amidst.logging.AmidstLogger;
|
||||
import amidst.minetest.file.directory.MinetestDirectory;
|
||||
import amidst.mojangapi.file.DotMinecraftDirectoryNotFoundException;
|
||||
import amidst.util.OperatingSystemDetector;
|
||||
|
||||
@Immutable
|
||||
public class MinetestDirectoryService {
|
||||
|
||||
@NotNull
|
||||
public MinetestDirectory createMinetestDirectory(String preferredMinetestDirectory)
|
||||
throws DotMinecraftDirectoryNotFoundException {
|
||||
return validate(new MinetestDirectory(findMinetestDirectory(preferredMinetestDirectory)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private MinetestDirectory validate(MinetestDirectory minecraftDirectory)
|
||||
throws DotMinecraftDirectoryNotFoundException {
|
||||
if (minecraftDirectory.isValid()) {
|
||||
return minecraftDirectory;
|
||||
} else {
|
||||
throw new DotMinecraftDirectoryNotFoundException(
|
||||
"invalid mintest directory at: '" + minecraftDirectory.getRoot() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private File findMinetestDirectory(String preferredMinetestDirectory) throws DotMinecraftDirectoryNotFoundException {
|
||||
|
||||
File result = null;
|
||||
|
||||
if (preferredMinetestDirectory != null) {
|
||||
result = new File(preferredMinetestDirectory);
|
||||
if (!result.isDirectory()) {
|
||||
AmidstLogger.warn(
|
||||
"Unable to set Minetest directory to: " + result
|
||||
+ " as that location does not exist or is not a folder.");
|
||||
result = getMinetestDirectory();
|
||||
}
|
||||
} else {
|
||||
result = getMinetestDirectory();
|
||||
}
|
||||
|
||||
if (result == null) throw new DotMinecraftDirectoryNotFoundException("unable to locate minetest directory");
|
||||
return result;
|
||||
}
|
||||
|
||||
private File getMinetestDirectory() {
|
||||
|
||||
File result = null;
|
||||
|
||||
File home = new File(System.getProperty("user.home", "."));
|
||||
if (OperatingSystemDetector.isWindows()) {
|
||||
result = new File("C:\\minetest");
|
||||
if (!result.isDirectory()) result = new File("C:\\games\\minetest");
|
||||
if (!result.isDirectory()) result = null;
|
||||
|
||||
} else if (OperatingSystemDetector.isMac()) {
|
||||
// /home/username/.minetest/
|
||||
}
|
||||
|
||||
if (result == null) result = new File(home, ".minetest");
|
||||
if (!result.isDirectory()) result = new File(home, "minetest");
|
||||
|
||||
if (!result.isDirectory()) result = null;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package amidst.minetest.world.mapgen;
|
||||
|
||||
public class Constants {
|
||||
|
||||
// Dimension of a MapBlock
|
||||
// WARNING: A MineTest MapBlock is similar to a Minecraft Chunk, while
|
||||
// a Minetest Chunk is 5 x 5 x 5 MapBlocks!
|
||||
public static final int MAP_BLOCKSIZE = 16;
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package amidst.minetest.world.mapgen;
|
||||
|
||||
import amidst.documentation.Immutable;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@Immutable
|
||||
public class InvalidNoiseParamsException extends Exception {
|
||||
|
||||
public InvalidNoiseParamsException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public InvalidNoiseParamsException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package amidst.minetest.world.mapgen;
|
||||
|
||||
import javax.vecmath.Vector3f;
|
||||
|
||||
public class MapgenV7Params {
|
||||
|
||||
public static final int FLAG_V7_MOUNTAINS = 0x01;
|
||||
public static final int FLAG_V7_RIDGES = 0x02;
|
||||
public static final int FLAG_V7_FLOATLANDS = 0x04;
|
||||
public static final int FLAG_V7_CAVERNS = 0x08;
|
||||
public static final int FLAG_V7_BIOMEREPEAT = 0x10; // Now unused
|
||||
|
||||
/*
|
||||
private short mount_zero_level;
|
||||
private short large_cave_depth;
|
||||
private float float_mount_density;
|
||||
private float float_mount_height;
|
||||
private float float_mount_exponent;
|
||||
private short floatland_level;
|
||||
private short shadow_limit;
|
||||
private short dungeon_ymin;
|
||||
private short dungeon_ymax;
|
||||
|
||||
private Noise noise_terrain_alt;
|
||||
private Noise noise_terrain_persist;
|
||||
private Noise noise_height_select;
|
||||
private Noise noise_mount_height;
|
||||
private Noise noise_ridge_uwater;
|
||||
private Noise noise_floatland_base;
|
||||
private Noise noise_float_base_height;
|
||||
private Noise noise_mountain;
|
||||
private Noise noise_ridge;
|
||||
*/
|
||||
|
||||
|
||||
|
||||
public int spflags = FLAG_V7_MOUNTAINS | FLAG_V7_RIDGES | FLAG_V7_CAVERNS;
|
||||
short mount_zero_level = 0;
|
||||
float cave_width = 0.09f;
|
||||
short large_cave_depth = -33;
|
||||
short lava_depth = -256;
|
||||
float float_mount_density = 0.6f;
|
||||
float float_mount_height = 128.0f;
|
||||
float float_mount_exponent = 0.75f;
|
||||
short floatland_level = 1280;
|
||||
short shadow_limit = 1024;
|
||||
short cavern_limit = -256;
|
||||
short cavern_taper = 256;
|
||||
float cavern_threshold = 0.7f;
|
||||
short dungeon_ymin = -31000;
|
||||
short dungeon_ymax = 31000;
|
||||
|
||||
int chunksize_in_mapblocks = 5;
|
||||
public int chunk_length_x = chunksize_in_mapblocks * Constants.MAP_BLOCKSIZE;
|
||||
public int chunk_length_y = chunk_length_x;
|
||||
public int chunk_length_z = chunk_length_x;
|
||||
|
||||
// params that aren't public aren't being used by Amidst
|
||||
NoiseParams np_terrain_base = new NoiseParams(4, 70, new Vector3f(600, 600, 600), 82341, (short)5, 0.6f, 2.0f);
|
||||
NoiseParams np_terrain_alt = new NoiseParams(4, 25, new Vector3f(600, 600, 600), 5934, (short)5, 0.6f, 2.0f);
|
||||
NoiseParams np_terrain_persist = new NoiseParams(0.6f, 0.1f, new Vector3f(2000, 2000, 2000), 539, (short)3, 0.6f, 2.0f);
|
||||
NoiseParams np_height_select = new NoiseParams(-8, 16, new Vector3f(500, 500, 500), 4213, (short)6, 0.7f, 2.0f);
|
||||
NoiseParams np_filler_depth = new NoiseParams(0, 1.2f, new Vector3f(150, 150, 150), 261, (short)3, 0.7f, 2.0f);
|
||||
NoiseParams np_mount_height = new NoiseParams(256f, 112f, new Vector3f(1000, 1000, 1000), 72449, (short)3, 0.6f, 2.0f);
|
||||
public NoiseParams np_ridge_uwater = new NoiseParams(0, 1, new Vector3f(1000, 1000, 1000), 85039, (short)5, 0.6f, 2.0f);
|
||||
NoiseParams np_floatland_base = new NoiseParams(-0.6f, 1.5f, new Vector3f(600, 600, 600), 114, (short)5, 0.6f, 2.0f);
|
||||
NoiseParams np_float_base_height = new NoiseParams(48, 24, new Vector3f(300, 300, 300), 907, (short)4, 0.7f, 2.0f);
|
||||
public NoiseParams np_mountain = new NoiseParams(-0.6f, 1, new Vector3f(250, 350, 250), 5333, (short)5, 0.63f, 2.0f);
|
||||
public NoiseParams np_ridge = new NoiseParams(0, 1, new Vector3f(100, 100, 100), 6467, (short)4, 0.75f, 2.0f);
|
||||
NoiseParams np_cavern = new NoiseParams(0, 1, new Vector3f(384, 128, 384), 723, (short)5, 0.63f, 2.0f);
|
||||
NoiseParams np_cave1 = new NoiseParams(0, 12, new Vector3f(61, 61, 61), 52534, (short)3, 0.5f, 2.0f);
|
||||
NoiseParams np_cave2 = new NoiseParams(0, 12, new Vector3f(67, 67, 67), 10325, (short)3, 0.5f, 2.0f);
|
||||
}
|
|
@ -0,0 +1,186 @@
|
|||
package amidst.minetest.world.mapgen;
|
||||
|
||||
public class Noise {
|
||||
|
||||
public static final int FLAG_DEFAULTS = 0x01;
|
||||
public static final int FLAG_EASED = 0x02;
|
||||
public static final int FLAG_ABSVALUE = 0x04;
|
||||
public static final int FLAG_POINTBUFFER = 0x08;
|
||||
public static final int FLAG_SIMPLEX = 0x10;
|
||||
|
||||
public static final int MAGIC_X = 1619;
|
||||
public static final int MAGIC_Y = 31337;
|
||||
public static final int MAGIC_Z = 52591;
|
||||
public static final int MAGIC_SEED = 1013;
|
||||
|
||||
public NoiseParams np;
|
||||
private int seed;
|
||||
private int sx;
|
||||
private int sy;
|
||||
private int sz;
|
||||
private float[] noise_buf = null;
|
||||
private float[] gradient_buf = null;
|
||||
private float[] persist_buf = null;
|
||||
private float[] result = null;
|
||||
|
||||
public Noise(NoiseParams np_, int seed, int sx, int sy) throws InvalidNoiseParamsException {
|
||||
|
||||
this(np_, seed, sx, sy, 1);
|
||||
}
|
||||
|
||||
public Noise(NoiseParams np_, int seed, int sx, int sy, int sz) throws InvalidNoiseParamsException {
|
||||
this.np = np_;
|
||||
this.seed = seed;
|
||||
this.sx = sx;
|
||||
this.sy = sy;
|
||||
this.sz = sz;
|
||||
|
||||
allocBuffers();
|
||||
}
|
||||
|
||||
private void allocBuffers() throws InvalidNoiseParamsException
|
||||
{
|
||||
if (sx < 1) sx = 1;
|
||||
if (sy < 1) sy = 1;
|
||||
if (sz < 1) sz = 1;
|
||||
|
||||
this.noise_buf = null;
|
||||
resizeNoiseBuf(sz > 1);
|
||||
|
||||
gradient_buf = null;
|
||||
persist_buf = null;
|
||||
result = null;
|
||||
|
||||
try {
|
||||
int bufsize = sx * sy * sz;
|
||||
persist_buf = null;
|
||||
gradient_buf = new float[bufsize];
|
||||
result = new float[bufsize];
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw new InvalidNoiseParamsException("out of memory");
|
||||
}
|
||||
}
|
||||
|
||||
private void resizeNoiseBuf(boolean is3d) throws InvalidNoiseParamsException
|
||||
{
|
||||
//if (is3d) throw new UnsupportedOperationException("need to port 3d noise functions");
|
||||
|
||||
//maximum possible spread value factor
|
||||
float ofactor = (np.lacunarity > 1.0) ?
|
||||
(float)Math.pow(np.lacunarity, np.octaves - 1) :
|
||||
np.lacunarity;
|
||||
|
||||
// noise lattice point count
|
||||
// (int)(sz * spread * ofactor) is # of lattice points crossed due to length
|
||||
float num_noise_points_x = sx * ofactor / np.spread.x;
|
||||
float num_noise_points_y = sy * ofactor / np.spread.y;
|
||||
float num_noise_points_z = sz * ofactor / np.spread.z;
|
||||
|
||||
// protect against obviously invalid parameters
|
||||
if (num_noise_points_x > 1000000000.f ||
|
||||
num_noise_points_y > 1000000000.f ||
|
||||
num_noise_points_z > 1000000000.f)
|
||||
throw new InvalidNoiseParamsException();
|
||||
|
||||
// + 2 for the two initial endpoints
|
||||
// + 1 for potentially crossing a boundary due to offset
|
||||
int nlx = (int)Math.ceil(num_noise_points_x) + 3;
|
||||
int nly = (int)Math.ceil(num_noise_points_y) + 3;
|
||||
int nlz = is3d ? (int)Math.ceil(num_noise_points_z) + 3 : 1;
|
||||
|
||||
try {
|
||||
noise_buf = new float[nlx * nly * nlz];
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw new InvalidNoiseParamsException("out of memory");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static float NoisePerlin2D(NoiseParams np, float x, float y, int seed)
|
||||
{
|
||||
float a = 0;
|
||||
float f = 1.0f;
|
||||
float g = 1.0f;
|
||||
|
||||
x /= np.spread.x;
|
||||
y /= np.spread.y;
|
||||
seed += np.seed;
|
||||
|
||||
for (int i = 0; i < np.octaves; i++) {
|
||||
float noiseval = noise2d_gradient(x * f, y * f, seed + i,
|
||||
(np.flags & (FLAG_DEFAULTS | FLAG_EASED)) > 0);
|
||||
|
||||
if ((np.flags & FLAG_ABSVALUE) > 0)
|
||||
noiseval = Math.abs(noiseval);
|
||||
|
||||
a += g * noiseval;
|
||||
f *= np.lacunarity;
|
||||
g *= np.persist;
|
||||
}
|
||||
|
||||
return np.offset + a * np.scale;
|
||||
}
|
||||
|
||||
static float noise2d(int x, int y, int seed)
|
||||
{
|
||||
// n is an unsigned int, which Java does not possess, so
|
||||
// divide and shift operations on it must be performed unsigned
|
||||
//
|
||||
// Note that in two's complement arithmetic, the arithmetic operations of
|
||||
// add, subtract, and multiply are bit-wise identical if the two operands
|
||||
// are regarded as both being signed or both being unsigned.
|
||||
//
|
||||
// unsigned int n = (MAGIC_X * x + MAGIC_Y * y + MAGIC_SEED * seed) & 0x7fffffff;
|
||||
// n = (n >> 13) ^ n;
|
||||
// n = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
|
||||
// return 1.f - (float)(int)n / 0x40000000;
|
||||
int n = (MAGIC_X * x + MAGIC_Y * y + MAGIC_SEED * seed) & 0x7fffffff;
|
||||
n = (n >>> 13) ^ n;
|
||||
n = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
|
||||
return 1.f - (float)(int)n / 0x40000000; // ?? check this
|
||||
}
|
||||
|
||||
static float noise2d_gradient(float x, float y, int seed, boolean eased)
|
||||
{
|
||||
// Calculate the integer coordinates
|
||||
int x0 = ((x) < 0.0 ? (int)(x) - 1 : (int)(x)); // x0 = myfloor(x)
|
||||
int y0 = ((y) < 0.0 ? (int)(y) - 1 : (int)(y)); // y0 = myfloor(y)
|
||||
// Calculate the remaining part of the coordinates
|
||||
float xl = x - (float)x0;
|
||||
float yl = y - (float)y0;
|
||||
// Get values for corners of square
|
||||
float v00 = noise2d(x0, y0, seed);
|
||||
float v10 = noise2d(x0+1, y0, seed);
|
||||
float v01 = noise2d(x0, y0+1, seed);
|
||||
float v11 = noise2d(x0+1, y0+1, seed);
|
||||
// Interpolate
|
||||
if (eased) {
|
||||
return biLinearInterpolation(v00, v10, v01, v11, xl, yl);
|
||||
}
|
||||
|
||||
return biLinearInterpolationNoEase(v00, v10, v01, v11, xl, yl);
|
||||
}
|
||||
|
||||
static float biLinearInterpolation(
|
||||
float v00, float v10,
|
||||
float v01, float v11,
|
||||
float x, float y)
|
||||
{
|
||||
float tx = x * x * x * (x * (6.f * x - 15.f) + 10.f); // easeCurve(x);
|
||||
float ty = y * y * y * (y * (6.f * y - 15.f) + 10.f); // easeCurve(y);
|
||||
float u = v00 + (v10 - v00) * x; // linearInterpolation(v00, v10, x);
|
||||
float v = v01 + (v11 - v01) * x; // linearInterpolation(v01, v11, x);
|
||||
return u + (v - u) * y; // linearInterpolation(u, v, y);
|
||||
}
|
||||
|
||||
|
||||
static float biLinearInterpolationNoEase(
|
||||
float v00, float v10,
|
||||
float v01, float v11,
|
||||
float x, float y)
|
||||
{
|
||||
float u = v00 + (v10 - v00) * x; // linearInterpolation(v00, v10, x);
|
||||
float v = v01 + (v11 - v01) * x; // linearInterpolation(v01, v11, x);
|
||||
return u + (v - u) * y; // linearInterpolation(u, v, y);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package amidst.minetest.world.mapgen;
|
||||
|
||||
import javax.vecmath.Vector3f;
|
||||
|
||||
public class NoiseParams {
|
||||
|
||||
float offset = 0.0f;
|
||||
float scale = 1.0f;
|
||||
Vector3f spread = new Vector3f(250, 250, 250);
|
||||
int seed = 12345;
|
||||
short octaves = 3;
|
||||
float persist = 0.6f;
|
||||
float lacunarity = 2.0f;
|
||||
int flags = Noise.FLAG_DEFAULTS; // Static methods like compareUnsigned, divideUnsigned etc have been added to the Integer class to support the arithmetic operations for unsigned integers
|
||||
|
||||
|
||||
public NoiseParams() { }
|
||||
|
||||
public NoiseParams(float offset_, float scale_, Vector3f spread_, int seed_,
|
||||
short octaves_, float persist_, float lacunarity_)
|
||||
{
|
||||
this(offset_, scale_, spread_, seed_, octaves_, persist_, lacunarity_, Noise.FLAG_DEFAULTS);
|
||||
}
|
||||
|
||||
public NoiseParams(float offset_, float scale_, Vector3f spread_, int seed_,
|
||||
short octaves_, float persist_, float lacunarity_,
|
||||
int flags_)
|
||||
{
|
||||
offset = offset_;
|
||||
scale = scale_;
|
||||
spread = spread_;
|
||||
seed = seed_;
|
||||
octaves = octaves_;
|
||||
persist = persist_;
|
||||
lacunarity = lacunarity_;
|
||||
flags = flags_;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package amidst.minetest.world.mapgen;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
|
||||
import amidst.mojangapi.world.WorldSeed;
|
||||
|
||||
public class Numeric {
|
||||
|
||||
/**
|
||||
* @return A pair of values: the seed as a long, and whether it was
|
||||
* parsed as a numeric or text string
|
||||
*/
|
||||
public static SimpleEntry<Long, Boolean> stringToSeed(String input)
|
||||
{
|
||||
long seed;
|
||||
boolean fromText = false;
|
||||
|
||||
try {
|
||||
if (input.startsWith("0x")) {
|
||||
seed = Long.decode(input);
|
||||
} else {
|
||||
seed = Long.parseLong(input);
|
||||
}
|
||||
} catch (NumberFormatException err) {
|
||||
byte[] stringAsBytes = input.getBytes(Charset.forName("UTF-8"));
|
||||
seed = murmurhash2_hash64(stringAsBytes, stringAsBytes.length, 0x1337);
|
||||
fromText = true;
|
||||
}
|
||||
return new SimpleEntry<Long, Boolean>(seed, fromText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates 64 bit hash from byte array of the given length and seed.
|
||||
*
|
||||
* @param data byte array to hash
|
||||
* @param length length of the array to hash
|
||||
* @param seed initial seed value
|
||||
* @return 64 bit hash of the given array
|
||||
*/
|
||||
public static long murmurhash2_hash64(final byte[] data, int length, int seed) {
|
||||
final long m = 0xc6a4a7935bd1e995L;
|
||||
final int r = 47;
|
||||
|
||||
long h = (seed&0xffffffffl)^(length*m);
|
||||
|
||||
int length8 = length/8;
|
||||
|
||||
for (int i=0; i<length8; i++) {
|
||||
final int i8 = i*8;
|
||||
long k = ((long)data[i8+0]&0xff) +(((long)data[i8+1]&0xff)<<8)
|
||||
+(((long)data[i8+2]&0xff)<<16) +(((long)data[i8+3]&0xff)<<24)
|
||||
+(((long)data[i8+4]&0xff)<<32) +(((long)data[i8+5]&0xff)<<40)
|
||||
+(((long)data[i8+6]&0xff)<<48) +(((long)data[i8+7]&0xff)<<56);
|
||||
|
||||
k *= m;
|
||||
k ^= k >>> r;
|
||||
k *= m;
|
||||
|
||||
h ^= k;
|
||||
h *= m;
|
||||
}
|
||||
|
||||
switch (length%8) {
|
||||
case 7: h ^= (long)(data[(length&~7)+6]&0xff) << 48;
|
||||
case 6: h ^= (long)(data[(length&~7)+5]&0xff) << 40;
|
||||
case 5: h ^= (long)(data[(length&~7)+4]&0xff) << 32;
|
||||
case 4: h ^= (long)(data[(length&~7)+3]&0xff) << 24;
|
||||
case 3: h ^= (long)(data[(length&~7)+2]&0xff) << 16;
|
||||
case 2: h ^= (long)(data[(length&~7)+1]&0xff) << 8;
|
||||
case 1: h ^= (long)(data[length&~7]&0xff);
|
||||
h *= m;
|
||||
};
|
||||
|
||||
h ^= h >>> r;
|
||||
h *= m;
|
||||
h ^= h >>> r;
|
||||
|
||||
return h;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
package amidst.minetest.world.oracle;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import amidst.documentation.Immutable;
|
||||
import amidst.fragment.Fragment;
|
||||
import amidst.fragment.IBiomeDataOracle;
|
||||
import amidst.logging.AmidstLogger;
|
||||
import amidst.logging.AmidstMessageBox;
|
||||
import amidst.minetest.world.mapgen.InvalidNoiseParamsException;
|
||||
import amidst.minetest.world.mapgen.MapgenV7Params;
|
||||
import amidst.minetest.world.mapgen.Noise;
|
||||
import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException;
|
||||
import amidst.mojangapi.world.coordinates.CoordinatesInWorld;
|
||||
import amidst.mojangapi.world.coordinates.Resolution;
|
||||
|
||||
@Immutable
|
||||
public class BiomeDataOracle implements IBiomeDataOracle {
|
||||
private final int seed;
|
||||
private final MapgenV7Params params;
|
||||
|
||||
private Noise noise_terrain_alt;
|
||||
private Noise noise_ridge_uwater;
|
||||
private Noise noise_mountain;
|
||||
private Noise noise_ridge;
|
||||
|
||||
|
||||
public static final int BITPLANE_RIVER = 0x4000;
|
||||
public static final int BITPLANE_OCEAN = 0x2000;
|
||||
public static final int BITPLANE_MOUNTAIN = 0x1000;
|
||||
public static final int MASK_BITPLANES = ~(BITPLANE_RIVER | BITPLANE_OCEAN | BITPLANE_MOUNTAIN);
|
||||
|
||||
|
||||
public BiomeDataOracle(MapgenV7Params params, long seed) throws InvalidNoiseParamsException {
|
||||
//this.seed = (int)(seed & 0xFFFFFFFFL);
|
||||
this.seed = (int)seed;
|
||||
this.params = params;
|
||||
|
||||
if ((params.spflags & MapgenV7Params.FLAG_V7_RIDGES) > 0) {
|
||||
noise_ridge_uwater = new Noise(params.np_ridge_uwater, this.seed, params.chunk_length_x, params.chunk_length_z);
|
||||
|
||||
// 3D noise, 1-up 1-down overgeneration
|
||||
noise_ridge = new Noise(params.np_ridge, this.seed, params.chunk_length_x, params.chunk_length_y + 2, params.chunk_length_z);
|
||||
}
|
||||
|
||||
// 3D noise, 1 up, 1 down overgeneration
|
||||
if ((params.spflags & (MapgenV7Params.FLAG_V7_MOUNTAINS | MapgenV7Params.FLAG_V7_FLOATLANDS)) > 0) {
|
||||
noise_mountain = new Noise(params.np_mountain, this.seed, params.chunk_length_x, params.chunk_length_y + 2, params.chunk_length_z);
|
||||
}
|
||||
}
|
||||
|
||||
public short populateArray(CoordinatesInWorld corner, short[][] result, boolean useQuarterResolution) {
|
||||
Resolution resolution = Resolution.from(useQuarterResolution);
|
||||
int width = result.length;
|
||||
if (width > 0) {
|
||||
int height = result[0].length;
|
||||
int left = (int) corner.getX();
|
||||
int top = (int) corner.getY();
|
||||
int shift = resolution.getShift();
|
||||
int step = resolution.getStep();
|
||||
float river_width = 0.2f;
|
||||
int world_y;
|
||||
int world_x;
|
||||
short biomeValue;
|
||||
|
||||
try {
|
||||
for (int y = 0; y < height; y++) {
|
||||
|
||||
world_y = top + (y << shift);
|
||||
world_x = left;
|
||||
|
||||
for (int x = 0; x < width; x++) {
|
||||
|
||||
biomeValue = 0;
|
||||
|
||||
// add the river bitplane
|
||||
float uwatern = Noise.NoisePerlin2D(noise_ridge_uwater.np, world_x, world_y, seed) * 2;
|
||||
if (Math.abs(uwatern) <= river_width) biomeValue |= BITPLANE_RIVER;
|
||||
|
||||
|
||||
result[x][y] = biomeValue;
|
||||
world_x += step;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//copyToResult(result, width, height, getBiomeData(left, top, width, height, useQuarterResolution));
|
||||
} catch (Exception e) {
|
||||
AmidstLogger.error(e);
|
||||
AmidstMessageBox.displayError("Error", e);
|
||||
}
|
||||
}
|
||||
return MASK_BITPLANES;
|
||||
}
|
||||
|
||||
/*
|
||||
public static void copyToResult(short[][] result, int width, int height, int[] biomeData) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
result[x][y] = (short) biomeData[getBiomeDataIndex(x, y, width)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int[] getBiomeData(int x, int y, int width, int height, boolean useQuarterResolution)
|
||||
throws UnsupportedOperationException {
|
||||
|
||||
// return minecraftInterface.getBiomeData(x, y, width, height, useQuarterResolution);
|
||||
throw new UnsupportedOperationException("getBiomeData (minetest)");
|
||||
}*/
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package amidst.minetest.world.oracle;
|
||||
|
||||
import amidst.documentation.ThreadSafe;
|
||||
import amidst.minetest.world.mapgen.MapgenV7Params;
|
||||
import amidst.mojangapi.world.coordinates.CoordinatesInWorld;
|
||||
import amidst.mojangapi.world.oracle.WorldSpawnOracle;
|
||||
|
||||
@ThreadSafe
|
||||
public class HeuristicWorldSpawnOracle implements WorldSpawnOracle {
|
||||
private final int seed;
|
||||
private final MapgenV7Params params;
|
||||
|
||||
public HeuristicWorldSpawnOracle(MapgenV7Params params, long seed) {
|
||||
this.seed = (int)(seed & 0xFFFFFFFFL);
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CoordinatesInWorld get() {
|
||||
// Not implemented
|
||||
return CoordinatesInWorld.origin();
|
||||
}
|
||||
}
|
|
@ -3,6 +3,9 @@ package amidst.mojangapi;
|
|||
import java.io.IOException;
|
||||
|
||||
import amidst.documentation.ThreadSafe;
|
||||
import amidst.gameengineabstraction.GameEngineType;
|
||||
import amidst.minetest.MinetestLauncherProfile;
|
||||
import amidst.minetest.MinetestMapgenV7Interface;
|
||||
import amidst.mojangapi.file.LauncherProfile;
|
||||
import amidst.mojangapi.file.SaveGame;
|
||||
import amidst.mojangapi.minecraftinterface.MinecraftInterface;
|
||||
|
@ -20,10 +23,18 @@ import amidst.mojangapi.world.WorldType;
|
|||
public class RunningLauncherProfile {
|
||||
public static RunningLauncherProfile from(WorldBuilder worldBuilder, LauncherProfile launcherProfile)
|
||||
throws LocalMinecraftInterfaceCreationException {
|
||||
|
||||
MinecraftInterface mapgenInterface;
|
||||
|
||||
if (launcherProfile instanceof MinetestLauncherProfile) {
|
||||
mapgenInterface = new MinetestMapgenV7Interface(((MinetestLauncherProfile)launcherProfile).getMapGenParams());
|
||||
} else {
|
||||
mapgenInterface = LocalMinecraftInterface.create(DefaultClassTranslator.INSTANCE.get(), launcherProfile);
|
||||
}
|
||||
return new RunningLauncherProfile(
|
||||
worldBuilder,
|
||||
launcherProfile,
|
||||
LocalMinecraftInterface.create(DefaultClassTranslator.INSTANCE.get(), launcherProfile));
|
||||
mapgenInterface);
|
||||
}
|
||||
|
||||
private final WorldBuilder worldBuilder;
|
||||
|
@ -48,6 +59,10 @@ public class RunningLauncherProfile {
|
|||
return minecraftInterface.getRecognisedVersion();
|
||||
}
|
||||
|
||||
public GameEngineType getGameEngineType() {
|
||||
return minecraftInterface.getGameEngineType();
|
||||
}
|
||||
|
||||
public RunningLauncherProfile createSilentPlayerlessCopy() {
|
||||
try {
|
||||
return RunningLauncherProfile.from(WorldBuilder.createSilentPlayerless(), launcherProfile);
|
||||
|
|
|
@ -8,6 +8,8 @@ import java.util.Optional;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import amidst.documentation.Immutable;
|
||||
import amidst.gameengineabstraction.file.IGameInstallation;
|
||||
import amidst.gameengineabstraction.file.IUnresolvedLauncherProfile;
|
||||
import amidst.logging.AmidstLogger;
|
||||
import amidst.mojangapi.file.directory.DotMinecraftDirectory;
|
||||
import amidst.mojangapi.file.directory.SaveDirectory;
|
||||
|
@ -19,7 +21,7 @@ import amidst.parsing.FormatException;
|
|||
import amidst.parsing.json.JsonReader;
|
||||
|
||||
@Immutable
|
||||
public class MinecraftInstallation {
|
||||
public class MinecraftInstallation implements IGameInstallation {
|
||||
public static MinecraftInstallation newCustomMinecraftInstallation(
|
||||
File libraries,
|
||||
File saves,
|
||||
|
@ -60,13 +62,13 @@ public class MinecraftInstallation {
|
|||
return result;
|
||||
}
|
||||
|
||||
public List<UnresolvedLauncherProfile> readLauncherProfiles() throws FormatException, IOException {
|
||||
public List<IUnresolvedLauncherProfile> readLauncherProfiles() throws FormatException, IOException {
|
||||
return dotMinecraftDirectoryService
|
||||
.readLauncherProfilesFrom(dotMinecraftDirectory)
|
||||
.getProfiles()
|
||||
.values()
|
||||
.stream()
|
||||
.map(p -> new UnresolvedLauncherProfile(dotMinecraftDirectory, p))
|
||||
.map(p -> (IUnresolvedLauncherProfile)new UnresolvedLauncherProfile(dotMinecraftDirectory, p))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package amidst.mojangapi.file;
|
|||
import java.io.IOException;
|
||||
|
||||
import amidst.documentation.Immutable;
|
||||
import amidst.gameengineabstraction.file.IUnresolvedLauncherProfile;
|
||||
import amidst.mojangapi.file.directory.DotMinecraftDirectory;
|
||||
import amidst.mojangapi.file.directory.ProfileDirectory;
|
||||
import amidst.mojangapi.file.directory.VersionDirectory;
|
||||
|
@ -13,7 +14,7 @@ import amidst.parsing.FormatException;
|
|||
import amidst.parsing.json.JsonReader;
|
||||
|
||||
@Immutable
|
||||
public class UnresolvedLauncherProfile {
|
||||
public class UnresolvedLauncherProfile implements IUnresolvedLauncherProfile {
|
||||
private final DotMinecraftDirectoryService dotMinecraftDirectoryService = new DotMinecraftDirectoryService();
|
||||
private final DotMinecraftDirectory dotMinecraftDirectory;
|
||||
private final LauncherProfileJson launcherProfileJson;
|
||||
|
|
|
@ -16,6 +16,11 @@ public class VersionJson {
|
|||
public VersionJson() {
|
||||
}
|
||||
|
||||
public VersionJson(String id, String inheritsFrom) {
|
||||
this.id = id;
|
||||
this.inheritsFrom = inheritsFrom;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package amidst.mojangapi.minecraftinterface;
|
||||
|
||||
import amidst.documentation.ThreadSafe;
|
||||
import amidst.gameengineabstraction.GameEngineType;
|
||||
import amidst.mojangapi.world.WorldType;
|
||||
|
||||
/**
|
||||
|
@ -37,4 +38,6 @@ public interface MinecraftInterface {
|
|||
public void createWorld(long seed, WorldType worldType, String generatorOptions) throws MinecraftInterfaceException;
|
||||
|
||||
public RecognisedVersion getRecognisedVersion();
|
||||
|
||||
public GameEngineType getGameEngineType();
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ public enum RecognisedVersion {
|
|||
// TODO: Remove these versions before V1_0?
|
||||
// TODO: stronghold reset on V1_9pre4?
|
||||
UNKNOWN,
|
||||
Minetest_v7 ("Minetest mapgen v7", ""),
|
||||
|
||||
_1_12_pre7 ("1.12-pre7", "ujrjoxmsrw[Lom;pj[J[[Jpf"), // matches the launcher version id: 1.12-pre7 1.12-pre6 1.12-pre5 1.12-pre4 1.12-pre3
|
||||
_1_12_pre2 ("1.12-pre2", "uhrhovmqru[Lok;ph[J[[Jpd"), // matches the launcher version id: 1.12-pre2
|
||||
_1_12_pre1 ("1.12-pre1", "ugrgoumprt[Loj;pg[J[[Jpc"), // matches the launcher version id: 1.12-pre1
|
||||
|
@ -132,6 +134,7 @@ public enum RecognisedVersion {
|
|||
_a1_0_15 ("a1.0.15", "hfazigcjebebmdferjsbdgiifbbljcnlufinqmc[Jmaap"), // matches the launcher version id: a1.0.15
|
||||
_a1_0_14 ("a1.0.14", "hcazidcjebebmdfeqjpbdghicbblfcnlpfhnmly[Jlwap"), // matches the launcher version id: a1.0.14
|
||||
_a1_0_11 ("a1.0.11", "haaziacjebebmddenjlbdgfhzbbkzcnljfenels[Jlqap"); // matches the launcher version id: a1.0.11
|
||||
|
||||
// @formatter:on
|
||||
|
||||
@NotNull
|
||||
|
|
|
@ -6,6 +6,7 @@ import amidst.clazz.symbolic.SymbolicClass;
|
|||
import amidst.clazz.symbolic.SymbolicObject;
|
||||
import amidst.clazz.translator.ClassTranslator;
|
||||
import amidst.documentation.ThreadSafe;
|
||||
import amidst.gameengineabstraction.GameEngineType;
|
||||
import amidst.logging.AmidstLogger;
|
||||
import amidst.mojangapi.file.LauncherProfile;
|
||||
import amidst.mojangapi.minecraftinterface.MinecraftInterface;
|
||||
|
@ -147,4 +148,9 @@ public class LocalMinecraftInterface implements MinecraftInterface {
|
|||
public RecognisedVersion getRecognisedVersion() {
|
||||
return recognisedVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameEngineType getGameEngineType() {
|
||||
return GameEngineType.MINECRAFT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.List;
|
|||
import java.util.function.Consumer;
|
||||
|
||||
import amidst.documentation.ThreadSafe;
|
||||
import amidst.fragment.IBiomeDataOracle;
|
||||
import amidst.mojangapi.minecraftinterface.RecognisedVersion;
|
||||
import amidst.mojangapi.world.icon.WorldIcon;
|
||||
import amidst.mojangapi.world.icon.producer.CachedWorldIconProducer;
|
||||
|
@ -26,7 +27,7 @@ public class World {
|
|||
private final RecognisedVersion recognisedVersion;
|
||||
private final VersionFeatures versionFeatures;
|
||||
|
||||
private final BiomeDataOracle biomeDataOracle;
|
||||
private final IBiomeDataOracle biomeDataOracle;
|
||||
private final EndIslandOracle endIslandOracle;
|
||||
private final SlimeChunkOracle slimeChunkOracle;
|
||||
private final CachedWorldIconProducer spawnProducer;
|
||||
|
@ -47,7 +48,7 @@ public class World {
|
|||
MovablePlayerList movablePlayerList,
|
||||
RecognisedVersion recognisedVersion,
|
||||
VersionFeatures versionFeatures,
|
||||
BiomeDataOracle biomeDataOracle,
|
||||
IBiomeDataOracle biomeDataOracle,
|
||||
EndIslandOracle endIslandOracle,
|
||||
SlimeChunkOracle slimeChunkOracle,
|
||||
CachedWorldIconProducer spawnProducer,
|
||||
|
@ -104,7 +105,7 @@ public class World {
|
|||
return versionFeatures;
|
||||
}
|
||||
|
||||
public BiomeDataOracle getBiomeDataOracle() {
|
||||
public IBiomeDataOracle getBiomeDataOracle() {
|
||||
return biomeDataOracle;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,10 @@ import java.io.IOException;
|
|||
import java.util.function.Consumer;
|
||||
|
||||
import amidst.documentation.Immutable;
|
||||
import amidst.fragment.IBiomeDataOracle;
|
||||
import amidst.logging.AmidstLogger;
|
||||
import amidst.minetest.MinetestMapgenV7Interface;
|
||||
import amidst.minetest.world.mapgen.InvalidNoiseParamsException;
|
||||
import amidst.mojangapi.file.ImmutablePlayerInformationProvider;
|
||||
import amidst.mojangapi.file.PlayerInformationProvider;
|
||||
import amidst.mojangapi.file.SaveGame;
|
||||
|
@ -55,14 +59,36 @@ public class WorldBuilder {
|
|||
}
|
||||
|
||||
public World fromSeed(
|
||||
MinecraftInterface minecraftInterface,
|
||||
MinecraftInterface gameCodeInterface,
|
||||
Consumer<World> onDisposeWorld,
|
||||
WorldSeed worldSeed,
|
||||
WorldType worldType) throws MinecraftInterfaceException {
|
||||
BiomeDataOracle biomeDataOracle = new BiomeDataOracle(minecraftInterface);
|
||||
VersionFeatures versionFeatures = DefaultVersionFeatures.create(minecraftInterface.getRecognisedVersion());
|
||||
|
||||
VersionFeatures versionFeatures = DefaultVersionFeatures.create(gameCodeInterface.getRecognisedVersion());
|
||||
|
||||
IBiomeDataOracle biomeDataOracle;
|
||||
WorldSpawnOracle spawnOracle;
|
||||
|
||||
if (gameCodeInterface instanceof MinetestMapgenV7Interface) {
|
||||
MinetestMapgenV7Interface mapgen = (MinetestMapgenV7Interface)gameCodeInterface;
|
||||
try {
|
||||
biomeDataOracle = new amidst.minetest.world.oracle.BiomeDataOracle(mapgen.params, worldSeed.getLong());
|
||||
} catch (InvalidNoiseParamsException e) {
|
||||
AmidstLogger.error("Invalid param from Minetest game.");
|
||||
e.printStackTrace();
|
||||
biomeDataOracle = null;
|
||||
}
|
||||
spawnOracle = new amidst.minetest.world.oracle.HeuristicWorldSpawnOracle(mapgen.params, worldSeed.getLong());
|
||||
} else{
|
||||
biomeDataOracle = new BiomeDataOracle(gameCodeInterface);
|
||||
spawnOracle = new HeuristicWorldSpawnOracle(
|
||||
worldSeed.getLong(),
|
||||
(BiomeDataOracle)biomeDataOracle,
|
||||
versionFeatures.getValidBiomesForStructure_Spawn()
|
||||
);
|
||||
}
|
||||
return create(
|
||||
minecraftInterface,
|
||||
gameCodeInterface,
|
||||
onDisposeWorld,
|
||||
worldSeed,
|
||||
worldType,
|
||||
|
@ -70,10 +96,7 @@ public class WorldBuilder {
|
|||
MovablePlayerList.dummy(),
|
||||
versionFeatures,
|
||||
biomeDataOracle,
|
||||
new HeuristicWorldSpawnOracle(
|
||||
worldSeed.getLong(),
|
||||
biomeDataOracle,
|
||||
versionFeatures.getValidBiomesForStructure_Spawn()));
|
||||
spawnOracle);
|
||||
}
|
||||
|
||||
public World fromSaveGame(MinecraftInterface minecraftInterface, Consumer<World> onDisposeWorld, SaveGame saveGame)
|
||||
|
@ -88,7 +111,7 @@ public class WorldBuilder {
|
|||
return create(
|
||||
minecraftInterface,
|
||||
onDisposeWorld,
|
||||
WorldSeed.fromSaveGame(saveGame.getSeed()),
|
||||
WorldSeed.fromSaveGame(saveGame.getSeed(), minecraftInterface.getGameEngineType()),
|
||||
saveGame.getWorldType(),
|
||||
saveGame.getGeneratorOptions(),
|
||||
movablePlayerList,
|
||||
|
@ -105,12 +128,16 @@ public class WorldBuilder {
|
|||
String generatorOptions,
|
||||
MovablePlayerList movablePlayerList,
|
||||
VersionFeatures versionFeatures,
|
||||
BiomeDataOracle biomeDataOracle,
|
||||
IBiomeDataOracle biomeDataOracle,
|
||||
WorldSpawnOracle worldSpawnOracle) throws MinecraftInterfaceException {
|
||||
RecognisedVersion recognisedVersion = minecraftInterface.getRecognisedVersion();
|
||||
seedHistoryLogger.log(recognisedVersion, worldSeed);
|
||||
long seed = worldSeed.getLong();
|
||||
minecraftInterface.createWorld(seed, worldType, generatorOptions);
|
||||
|
||||
amidst.mojangapi.world.oracle.BiomeDataOracle minecraftBiomeOrNull =
|
||||
(biomeDataOracle instanceof amidst.mojangapi.world.oracle.BiomeDataOracle) ? (amidst.mojangapi.world.oracle.BiomeDataOracle)biomeDataOracle : null;
|
||||
|
||||
return new World(
|
||||
onDisposeWorld,
|
||||
worldSeed,
|
||||
|
@ -125,7 +152,7 @@ public class WorldBuilder {
|
|||
new SpawnProducer(worldSpawnOracle),
|
||||
versionFeatures.getStrongholdProducerFactory().apply(
|
||||
seed,
|
||||
biomeDataOracle,
|
||||
minecraftBiomeOrNull,
|
||||
versionFeatures.getValidBiomesAtMiddleOfChunk_Stronghold()),
|
||||
new PlayerProducer(movablePlayerList),
|
||||
new StructureProducer<>(
|
||||
|
@ -133,7 +160,7 @@ public class WorldBuilder {
|
|||
4,
|
||||
new VillageLocationChecker(
|
||||
seed,
|
||||
biomeDataOracle,
|
||||
minecraftBiomeOrNull,
|
||||
versionFeatures.getValidBiomesForStructure_Village()),
|
||||
new ImmutableWorldIconTypeProvider(DefaultWorldIconTypes.VILLAGE),
|
||||
Dimension.OVERWORLD,
|
||||
|
@ -143,9 +170,9 @@ public class WorldBuilder {
|
|||
8,
|
||||
new TempleLocationChecker(
|
||||
seed,
|
||||
biomeDataOracle,
|
||||
minecraftBiomeOrNull,
|
||||
versionFeatures.getValidBiomesAtMiddleOfChunk_Temple()),
|
||||
new TempleWorldIconTypeProvider(biomeDataOracle),
|
||||
new TempleWorldIconTypeProvider(minecraftBiomeOrNull),
|
||||
Dimension.OVERWORLD,
|
||||
false),
|
||||
new StructureProducer<>(
|
||||
|
@ -160,7 +187,7 @@ public class WorldBuilder {
|
|||
8,
|
||||
versionFeatures.getOceanMonumentLocationCheckerFactory().apply(
|
||||
seed,
|
||||
biomeDataOracle,
|
||||
minecraftBiomeOrNull,
|
||||
versionFeatures.getValidBiomesAtMiddleOfChunk_OceanMonument(),
|
||||
versionFeatures.getValidBiomesForStructure_OceanMonument()),
|
||||
new ImmutableWorldIconTypeProvider(DefaultWorldIconTypes.OCEAN_MONUMENT),
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package amidst.mojangapi.world;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
|
||||
import amidst.documentation.Immutable;
|
||||
import amidst.gameengineabstraction.GameEngineType;
|
||||
import amidst.minetest.world.mapgen.Numeric;
|
||||
|
||||
@Immutable
|
||||
public class WorldSeed {
|
||||
|
@ -20,52 +23,69 @@ public class WorldSeed {
|
|||
this.labelPrefix = labelPrefix;
|
||||
}
|
||||
|
||||
private String getLabel(long seed, String text) {
|
||||
private String getLabel(long seed, String text, GameEngineType gameEngine) {
|
||||
|
||||
String seedValue = Long.toString(seed);
|
||||
if (gameEngine != GameEngineType.MINECRAFT) {
|
||||
seedValue = Long.toUnsignedString(seed);
|
||||
}
|
||||
|
||||
if (this == TEXT) {
|
||||
return labelPrefix + ": '" + text + "' (" + seed + ")";
|
||||
return labelPrefix + ": '" + text + "' (" + seedValue + ")";
|
||||
} else {
|
||||
return labelPrefix + ": " + seed;
|
||||
return labelPrefix + ": " + seedValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static WorldSeed random() {
|
||||
return new WorldSeed(new Random().nextLong(), null, WorldSeedType.RANDOM);
|
||||
public static WorldSeed random(GameEngineType game_engine_type) {
|
||||
return new WorldSeed(new Random().nextLong(), null, WorldSeedType.RANDOM, game_engine_type);
|
||||
}
|
||||
|
||||
public static WorldSeed fromUserInput(String input) {
|
||||
public static WorldSeed fromUserInput(String input, GameEngineType engine_type) {
|
||||
if (input.isEmpty()) {
|
||||
return random();
|
||||
return random(engine_type);
|
||||
}
|
||||
try {
|
||||
long seed = Long.parseLong(input);
|
||||
return new WorldSeed(seed, null, WorldSeedType.NUMERIC);
|
||||
} catch (NumberFormatException err) {
|
||||
int seed = input.hashCode();
|
||||
return new WorldSeed(seed, input, WorldSeedType.TEXT);
|
||||
if (engine_type == GameEngineType.MINETESTv7) {
|
||||
SimpleEntry<Long, Boolean> covertedSeed = Numeric.stringToSeed(input);
|
||||
return new WorldSeed(
|
||||
covertedSeed.getKey(),
|
||||
input,
|
||||
covertedSeed.getValue() ? WorldSeedType.TEXT : WorldSeedType.NUMERIC,
|
||||
engine_type);
|
||||
} else {
|
||||
try {
|
||||
long seed = Long.parseLong(input);
|
||||
return new WorldSeed(seed, null, WorldSeedType.NUMERIC, engine_type);
|
||||
} catch (NumberFormatException err) {
|
||||
int seed = input.hashCode();
|
||||
return new WorldSeed(seed, input, WorldSeedType.TEXT, engine_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static WorldSeed fromSaveGame(long seed) {
|
||||
return new WorldSeed(seed, null, WorldSeedType.SAVE_GAME);
|
||||
public static WorldSeed fromSaveGame(long seed, GameEngineType game_engine_type) {
|
||||
return new WorldSeed(seed, null, WorldSeedType.SAVE_GAME, game_engine_type);
|
||||
}
|
||||
|
||||
private final long seed;
|
||||
private final String text;
|
||||
private final WorldSeedType type;
|
||||
private final String label;
|
||||
private final GameEngineType gameEngineType;
|
||||
|
||||
private WorldSeed(long seed, String text, WorldSeedType type) {
|
||||
private WorldSeed(long seed, String text, WorldSeedType type, GameEngineType game_engine_type) {
|
||||
this.seed = seed;
|
||||
this.text = text;
|
||||
this.type = type;
|
||||
this.label = type.getLabel(seed, text);
|
||||
this.gameEngineType = game_engine_type;
|
||||
this.label = type.getLabel(seed, text, game_engine_type);
|
||||
}
|
||||
|
||||
public long getLong() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,10 @@ public enum Resolution {
|
|||
return 1 << shift;
|
||||
}
|
||||
|
||||
public int getShift() {
|
||||
return shift;
|
||||
}
|
||||
|
||||
public int getStepsPerFragment() {
|
||||
return 1 << (FRAGMENT.shift - shift);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package amidst.mojangapi.world.icon.locationchecker;
|
|||
import java.util.List;
|
||||
|
||||
import amidst.documentation.ThreadSafe;
|
||||
import amidst.logging.AmidstLogger;
|
||||
import amidst.mojangapi.world.biome.Biome;
|
||||
import amidst.mojangapi.world.oracle.BiomeDataOracle;
|
||||
|
||||
|
@ -20,6 +21,10 @@ public class StructureBiomeLocationChecker implements LocationChecker {
|
|||
|
||||
@Override
|
||||
public boolean isValidLocation(int x, int y) {
|
||||
if (biomeDataOracle == null) {
|
||||
AmidstLogger.warn("isValidLocation asked with null biome - LocationCheckers not suitable for the current biome may be in use!");
|
||||
return false;
|
||||
}
|
||||
return biomeDataOracle.isValidBiomeForStructureAtMiddleOfChunk(x, y, size, validBiomes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,16 +12,17 @@ import amidst.mojangapi.world.biome.Biome;
|
|||
import amidst.mojangapi.world.biome.UnknownBiomeIndexException;
|
||||
import amidst.mojangapi.world.coordinates.CoordinatesInWorld;
|
||||
import amidst.mojangapi.world.coordinates.Resolution;
|
||||
import amidst.fragment.IBiomeDataOracle;
|
||||
|
||||
@ThreadSafe
|
||||
public class BiomeDataOracle {
|
||||
public class BiomeDataOracle implements IBiomeDataOracle {
|
||||
private final MinecraftInterface minecraftInterface;
|
||||
|
||||
public BiomeDataOracle(MinecraftInterface minecraftInterface) {
|
||||
this.minecraftInterface = minecraftInterface;
|
||||
}
|
||||
|
||||
public void populateArray(CoordinatesInWorld corner, short[][] result, boolean useQuarterResolution) {
|
||||
public short populateArray(CoordinatesInWorld corner, short[][] result, boolean useQuarterResolution) {
|
||||
Resolution resolution = Resolution.from(useQuarterResolution);
|
||||
int width = result.length;
|
||||
if (width > 0) {
|
||||
|
@ -35,6 +36,7 @@ public class BiomeDataOracle {
|
|||
AmidstMessageBox.displayError("Error", e);
|
||||
}
|
||||
}
|
||||
return (short)0xffff;
|
||||
}
|
||||
|
||||
public static void copyToResult(short[][] result, int width, int height, int[] biomeData) {
|
||||
|
|
|
@ -25,20 +25,38 @@ public enum DefaultVersionFeatures {
|
|||
INSTANCE;
|
||||
|
||||
public static VersionFeatures create(RecognisedVersion version) {
|
||||
return new VersionFeatures(
|
||||
INSTANCE.enabledLayers.getValue(version),
|
||||
INSTANCE.validBiomesForStructure_Spawn.getValue(version),
|
||||
INSTANCE.validBiomesAtMiddleOfChunk_Stronghold.getValue(version),
|
||||
INSTANCE.strongholdProducerFactory.getValue(version),
|
||||
INSTANCE.validBiomesForStructure_Village.getValue(version),
|
||||
INSTANCE.validBiomesAtMiddleOfChunk_Temple.getValue(version),
|
||||
INSTANCE.mineshaftAlgorithmFactory.getValue(version),
|
||||
INSTANCE.oceanMonumentLocationCheckerFactory.getValue(version),
|
||||
INSTANCE.validBiomesAtMiddleOfChunk_OceanMonument.getValue(version),
|
||||
INSTANCE.validBiomesForStructure_OceanMonument.getValue(version));
|
||||
|
||||
if (version == RecognisedVersion.Minetest_v7) {
|
||||
// Minetest
|
||||
return new VersionFeatures(
|
||||
INSTANCE.enabledLayers_Minetest.getValue(version),
|
||||
null,
|
||||
null,
|
||||
(seed, biomeOracle, validBiomes) -> null,
|
||||
null,
|
||||
null,
|
||||
seed -> null,
|
||||
(seed, biomeOracle, validCenterBiomes, validBiomes) -> null,
|
||||
null,
|
||||
null);
|
||||
} else {
|
||||
// Minecraft
|
||||
return new VersionFeatures(
|
||||
((version == RecognisedVersion.Minetest_v7) ? INSTANCE.enabledLayers_Minetest : INSTANCE.enabledLayers_Minecraft).getValue(version),
|
||||
INSTANCE.validBiomesForStructure_Spawn.getValue(version),
|
||||
INSTANCE.validBiomesAtMiddleOfChunk_Stronghold.getValue(version),
|
||||
INSTANCE.strongholdProducerFactory.getValue(version),
|
||||
INSTANCE.validBiomesForStructure_Village.getValue(version),
|
||||
INSTANCE.validBiomesAtMiddleOfChunk_Temple.getValue(version),
|
||||
INSTANCE.mineshaftAlgorithmFactory.getValue(version),
|
||||
INSTANCE.oceanMonumentLocationCheckerFactory.getValue(version),
|
||||
INSTANCE.validBiomesAtMiddleOfChunk_OceanMonument.getValue(version),
|
||||
INSTANCE.validBiomesForStructure_OceanMonument.getValue(version));
|
||||
}
|
||||
}
|
||||
|
||||
private final VersionFeature<List<Integer>> enabledLayers;
|
||||
private final VersionFeature<List<Integer>> enabledLayers_Minecraft;
|
||||
private final VersionFeature<List<Integer>> enabledLayers_Minetest;
|
||||
private final VersionFeature<List<Biome>> validBiomesForStructure_Spawn;
|
||||
private final VersionFeature<List<Biome>> validBiomesAtMiddleOfChunk_Stronghold;
|
||||
private final VersionFeature<TriFunction<Long, BiomeDataOracle, List<Biome>, StrongholdProducer_Base>> strongholdProducerFactory;
|
||||
|
@ -51,13 +69,27 @@ public enum DefaultVersionFeatures {
|
|||
|
||||
private DefaultVersionFeatures() {
|
||||
// @formatter:off
|
||||
this.enabledLayers = VersionFeature.<Integer> listBuilder()
|
||||
|
||||
this.enabledLayers_Minetest = VersionFeature.<Integer> listBuilder()
|
||||
.init(
|
||||
LayerIds.ALPHA,
|
||||
LayerIds.BIOME_DATA,
|
||||
LayerIds.BACKGROUND,
|
||||
LayerIds.SLIME,
|
||||
LayerIds.GRID,
|
||||
LayerIds.MINETEST_OCEAN,
|
||||
LayerIds.MINETEST_RIVER,
|
||||
LayerIds.MINETEST_MOUNTAIN,
|
||||
LayerIds.SLIME
|
||||
).construct();
|
||||
|
||||
|
||||
this.enabledLayers_Minecraft = VersionFeature.<Integer> listBuilder()
|
||||
.init(
|
||||
LayerIds.ALPHA,
|
||||
LayerIds.BIOME_DATA,
|
||||
LayerIds.BACKGROUND,
|
||||
LayerIds.GRID,
|
||||
LayerIds.SLIME,
|
||||
LayerIds.SPAWN,
|
||||
LayerIds.STRONGHOLD,
|
||||
LayerIds.PLAYER,
|
||||
|
|
|
@ -40,8 +40,8 @@ public class ListVersionFeatureBuilder<V> {
|
|||
}
|
||||
|
||||
@SafeVarargs
|
||||
public final ListVersionFeatureBuilder<V> exact(RecognisedVersion since, V... values) {
|
||||
return since(since, Arrays.asList(values));
|
||||
public final ListVersionFeatureBuilder<V> exact(RecognisedVersion version, V... values) {
|
||||
return exact(version, Arrays.asList(values));
|
||||
}
|
||||
|
||||
public ListVersionFeatureBuilder<V> exact(RecognisedVersion version, List<V> value) {
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import amidst.documentation.AmidstThread;
|
||||
import amidst.documentation.CalledOnlyBy;
|
||||
import amidst.documentation.ThreadSafe;
|
||||
import amidst.logging.AmidstLogger;
|
||||
|
||||
@ThreadSafe
|
||||
public class ThreadMaster {
|
||||
|
@ -91,7 +92,11 @@ public class ThreadMaster {
|
|||
@CalledOnlyBy(AmidstThread.FRAGMENT_LOADER)
|
||||
@Override
|
||||
public void run() {
|
||||
onFragmentLoadTick.run();
|
||||
try {
|
||||
onFragmentLoadTick.run();
|
||||
} catch (Exception e) {
|
||||
AmidstLogger.error("Error in fragemnt loader thread: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}, 0, 20, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package amidst.mojangapi.mocking;
|
||||
|
||||
import amidst.documentation.ThreadSafe;
|
||||
import amidst.gameengineabstraction.GameEngineType;
|
||||
import amidst.mojangapi.minecraftinterface.MinecraftInterface;
|
||||
import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException;
|
||||
import amidst.mojangapi.minecraftinterface.RecognisedVersion;
|
||||
|
@ -58,4 +59,9 @@ public class FakeMinecraftInterface implements MinecraftInterface {
|
|||
public RecognisedVersion getRecognisedVersion() {
|
||||
return worldMetadataJson.getRecognisedVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameEngineType getGameEngineType() {
|
||||
return GameEngineType.MINECRAFT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,10 +59,13 @@ public class FakeWorldBuilder {
|
|||
WorldMetadataJson worldMetadata,
|
||||
BiomeDataJson quarterBiomeData,
|
||||
BiomeDataJson fullBiomeData) throws MinecraftInterfaceException {
|
||||
|
||||
FakeMinecraftInterface fakeMinecraftInterface = createFakeMinecraftInterface(worldMetadata, quarterBiomeData, fullBiomeData);
|
||||
|
||||
return builder.fromSeed(
|
||||
createFakeMinecraftInterface(worldMetadata, quarterBiomeData, fullBiomeData),
|
||||
fakeMinecraftInterface,
|
||||
NOOP,
|
||||
WorldSeed.fromUserInput(worldMetadata.getSeed() + ""),
|
||||
WorldSeed.fromUserInput(worldMetadata.getSeed() + "", fakeMinecraftInterface.getGameEngineType()),
|
||||
worldMetadata.getWorldType());
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package amidst.mojangapi.mocking;
|
||||
|
||||
import amidst.documentation.ThreadSafe;
|
||||
import amidst.gameengineabstraction.GameEngineType;
|
||||
import amidst.mojangapi.minecraftinterface.MinecraftInterface;
|
||||
import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException;
|
||||
import amidst.mojangapi.minecraftinterface.RecognisedVersion;
|
||||
|
@ -38,4 +39,9 @@ public class RequestStoringMinecraftInterface implements MinecraftInterface {
|
|||
public synchronized RecognisedVersion getRecognisedVersion() {
|
||||
return realMinecraftInterface.getRecognisedVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameEngineType getGameEngineType() {
|
||||
return realMinecraftInterface.getGameEngineType();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
import amidst.documentation.Immutable;
|
||||
import amidst.gameengineabstraction.GameEngineType;
|
||||
import amidst.mojangapi.minecraftinterface.RecognisedVersion;
|
||||
import amidst.mojangapi.world.WorldSeed;
|
||||
import amidst.mojangapi.world.WorldType;
|
||||
|
@ -79,7 +80,7 @@ public enum TestWorldDeclaration {
|
|||
WorldType worldType,
|
||||
String... supported) {
|
||||
this.recognisedVersion = recognisedVersion;
|
||||
this.worldSeed = WorldSeed.fromUserInput(seed);
|
||||
this.worldSeed = WorldSeed.fromUserInput(seed, GameEngineType.MINECRAFT);
|
||||
this.worldType = worldType;
|
||||
this.supportedEntryNames = Collections.unmodifiableList(Arrays.asList(supported));
|
||||
this.directory = Paths.get(
|
||||
|
|
Loading…
Reference in New Issue