amidstest/src/main/java/amidst/mojangapi/world/oracle/BiomeDataOracle.java

182 lines
6.1 KiB
Java
Raw Normal View History

2015-12-08 06:47:58 -08:00
package amidst.mojangapi.world.oracle;
2015-11-22 21:39:54 -08:00
import java.util.List;
import java.util.Random;
2015-12-12 06:45:45 -08:00
import amidst.documentation.ThreadSafe;
2016-11-20 14:48:53 -08:00
import amidst.logging.AmidstLogger;
import amidst.logging.AmidstMessageBox;
import amidst.mojangapi.minecraftinterface.MinecraftInterface;
import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException;
2015-12-16 10:16:07 -08:00
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;
2015-11-22 21:39:54 -08:00
2015-12-12 06:45:45 -08:00
@ThreadSafe
public class BiomeDataOracle implements IBiomeDataOracle {
private final MinecraftInterface minecraftInterface;
2015-12-07 11:18:32 -08:00
public BiomeDataOracle(MinecraftInterface minecraftInterface) {
this.minecraftInterface = minecraftInterface;
2015-12-07 11:18:32 -08:00
}
public short populateArray(CoordinatesInWorld corner, short[][] result, boolean useQuarterResolution) {
added world icon test To prevent the need to make the minecraft jar file and libraries available on travis ci, this test uses previously generated testdata to ensure that the generated world icons are still the same as when the test data where generated. It is true, that this uses the production code to generate the test data, however, this is not an issue, because the test data are stored and not generated every time the test is executed. All in all, the test checks whether the generated world icons have changed since the test data where generated. It does not ensure, that the world icons are correct (meaning like minecraft generates them). The test: * loads the biome data from the test data * loads the world icons * creates a fake minecraft interface that provides the stored biome data * creates a world object using the fake minecraft interface * generates all world icons using the world object * compares the generated world icons to the loaded world icons The test data contains all biome data in the test area as well as all world icons. The test area is 10 fragments in all directions from [0, 0] ([-5120, -5120] to [5120, 5120]). The world icons are generated for the inner 10 - 1 = 9 fragments ([-4608, -4608] to [4608, 4608]). This prevents the world icon producers to request biome data that have not been stored. The test data are stored in a zip-file to prevent them from taking up to much space. One world requires about 6.5 MB (compressed). Thus, we should not add to much test worlds and not change them very often to prevent the repository from getting too big. An alternative would be stored the testdata somewhere else than in the repository. However, they have to be available for travis ci, so this will be the solution for now. * The End Cities are currently not included. * The current seed is "amidst-test-seed" using the default world type and minecraft version 1.8.9. * The test data are generated by running the test in the class DevToolRunner.
2016-01-24 17:05:37 -08:00
Resolution resolution = Resolution.from(useQuarterResolution);
int width = result.length;
if (width > 0) {
int height = result[0].length;
added world icon test To prevent the need to make the minecraft jar file and libraries available on travis ci, this test uses previously generated testdata to ensure that the generated world icons are still the same as when the test data where generated. It is true, that this uses the production code to generate the test data, however, this is not an issue, because the test data are stored and not generated every time the test is executed. All in all, the test checks whether the generated world icons have changed since the test data where generated. It does not ensure, that the world icons are correct (meaning like minecraft generates them). The test: * loads the biome data from the test data * loads the world icons * creates a fake minecraft interface that provides the stored biome data * creates a world object using the fake minecraft interface * generates all world icons using the world object * compares the generated world icons to the loaded world icons The test data contains all biome data in the test area as well as all world icons. The test area is 10 fragments in all directions from [0, 0] ([-5120, -5120] to [5120, 5120]). The world icons are generated for the inner 10 - 1 = 9 fragments ([-4608, -4608] to [4608, 4608]). This prevents the world icon producers to request biome data that have not been stored. The test data are stored in a zip-file to prevent them from taking up to much space. One world requires about 6.5 MB (compressed). Thus, we should not add to much test worlds and not change them very often to prevent the repository from getting too big. An alternative would be stored the testdata somewhere else than in the repository. However, they have to be available for travis ci, so this will be the solution for now. * The End Cities are currently not included. * The current seed is "amidst-test-seed" using the default world type and minecraft version 1.8.9. * The test data are generated by running the test in the class DevToolRunner.
2016-01-24 17:05:37 -08:00
int left = (int) corner.getXAs(resolution);
int top = (int) corner.getYAs(resolution);
try {
copyToResult(result, width, height, getBiomeData(left, top, width, height, useQuarterResolution));
} catch (MinecraftInterfaceException e) {
AmidstLogger.error(e);
AmidstMessageBox.displayError("Error", e);
}
}
return (short)0xffff;
}
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)];
2015-11-22 21:39:54 -08:00
}
}
}
added world icon test To prevent the need to make the minecraft jar file and libraries available on travis ci, this test uses previously generated testdata to ensure that the generated world icons are still the same as when the test data where generated. It is true, that this uses the production code to generate the test data, however, this is not an issue, because the test data are stored and not generated every time the test is executed. All in all, the test checks whether the generated world icons have changed since the test data where generated. It does not ensure, that the world icons are correct (meaning like minecraft generates them). The test: * loads the biome data from the test data * loads the world icons * creates a fake minecraft interface that provides the stored biome data * creates a world object using the fake minecraft interface * generates all world icons using the world object * compares the generated world icons to the loaded world icons The test data contains all biome data in the test area as well as all world icons. The test area is 10 fragments in all directions from [0, 0] ([-5120, -5120] to [5120, 5120]). The world icons are generated for the inner 10 - 1 = 9 fragments ([-4608, -4608] to [4608, 4608]). This prevents the world icon producers to request biome data that have not been stored. The test data are stored in a zip-file to prevent them from taking up to much space. One world requires about 6.5 MB (compressed). Thus, we should not add to much test worlds and not change them very often to prevent the repository from getting too big. An alternative would be stored the testdata somewhere else than in the repository. However, they have to be available for travis ci, so this will be the solution for now. * The End Cities are currently not included. * The current seed is "amidst-test-seed" using the default world type and minecraft version 1.8.9. * The test data are generated by running the test in the class DevToolRunner.
2016-01-24 17:05:37 -08:00
public static int getBiomeDataIndex(int x, int y, int width) {
return x + y * width;
2015-11-22 21:39:54 -08:00
}
public boolean isValidBiomeAtMiddleOfChunk(int chunkX, int chunkY, List<Biome> validBiomes) {
return isValidBiome(getMiddleOfChunk(chunkX), getMiddleOfChunk(chunkY), validBiomes);
}
private boolean isValidBiome(int x, int y, List<Biome> validBiomes) {
try {
return validBiomes.contains(getBiomeAt(x, y));
} catch (UnknownBiomeIndexException e) {
AmidstLogger.error(e);
AmidstMessageBox.displayError("Error", e);
return false;
} catch (MinecraftInterfaceException e) {
AmidstLogger.error(e);
AmidstMessageBox.displayError("Error", e);
return false;
}
}
public boolean isValidBiomeForStructureAtMiddleOfChunk(int chunkX, int chunkY, int size, List<Biome> validBiomes) {
return isValidBiomeForStructure(getMiddleOfChunk(chunkX), getMiddleOfChunk(chunkY), size, validBiomes);
}
public boolean isValidBiomeForStructure(int x, int y, int size, List<Biome> validBiomes) {
int left = x - size >> 2;
int top = y - size >> 2;
int right = x + size >> 2;
int bottom = y + size >> 2;
int width = right - left + 1;
int height = bottom - top + 1;
try {
int[] biomeData = getQuarterResolutionBiomeData(left, top, width, height);
for (int i = 0; i < width * height; i++) {
if (!validBiomes.contains(Biome.getByIndex(biomeData[i]))) {
return false;
}
}
return true;
} catch (UnknownBiomeIndexException e) {
AmidstLogger.error(e);
AmidstMessageBox.displayError("Error", e);
return false;
} catch (MinecraftInterfaceException e) {
AmidstLogger.error(e);
AmidstMessageBox.displayError("Error", e);
return false;
}
}
public CoordinatesInWorld findValidLocationAtMiddleOfChunk(
int chunkX,
int chunkY,
int size,
List<Biome> validBiomes,
Random random) {
return findValidLocation(getMiddleOfChunk(chunkX), getMiddleOfChunk(chunkY), size, validBiomes, random);
}
// TODO: Find out if we should useQuarterResolution or not
public CoordinatesInWorld findValidLocation(int x, int y, int size, List<Biome> validBiomes, Random random) {
int left = x - size >> 2;
int top = y - size >> 2;
int right = x + size >> 2;
int bottom = y + size >> 2;
int width = right - left + 1;
int height = bottom - top + 1;
try {
int[] biomeData = getQuarterResolutionBiomeData(left, top, width, height);
CoordinatesInWorld result = null;
int numberOfValidLocations = 0;
for (int i = 0; i < width * height; i++) {
if (validBiomes.contains(Biome.getByIndex(biomeData[i]))
&& (result == null || random.nextInt(numberOfValidLocations + 1) == 0)) {
result = createCoordinates(left, top, width, i);
numberOfValidLocations++;
}
}
return result;
} catch (UnknownBiomeIndexException e) {
AmidstLogger.error(e);
AmidstMessageBox.displayError("Error", e);
return null;
} catch (MinecraftInterfaceException e) {
AmidstLogger.error(e);
AmidstMessageBox.displayError("Error", e);
return null;
}
}
private CoordinatesInWorld createCoordinates(int left, int top, int width, int i) {
int x = left + i % width << 2;
int y = top + i / width << 2;
return CoordinatesInWorld.from(x, y);
}
private int getMiddleOfChunk(int coordinate) {
return coordinate * 16 + 8;
}
public Biome getBiomeAtMiddleOfChunk(int chunkX, int chunkY)
throws UnknownBiomeIndexException,
MinecraftInterfaceException {
return getBiomeAt(getMiddleOfChunk(chunkX), getMiddleOfChunk(chunkY));
}
/**
* Gets the biome located at the block-coordinates. This is not a fast
* routine, it was added for rare things like accurately testing structures.
* (uses the 1:1 scale biome-map)
*/
private Biome getBiomeAt(int x, int y) throws UnknownBiomeIndexException, MinecraftInterfaceException {
int[] biomeData = getFullResolutionBiomeData(x, y, 1, 1);
return Biome.getByIndex(biomeData[0]);
}
private int[] getQuarterResolutionBiomeData(int x, int y, int width, int height)
throws MinecraftInterfaceException {
2015-12-07 11:18:32 -08:00
return getBiomeData(x, y, width, height, true);
}
private int[] getFullResolutionBiomeData(int x, int y, int width, int height) throws MinecraftInterfaceException {
2015-12-07 11:18:32 -08:00
return getBiomeData(x, y, width, height, false);
}
private int[] getBiomeData(int x, int y, int width, int height, boolean useQuarterResolution)
throws MinecraftInterfaceException {
return minecraftInterface.getBiomeData(x, y, width, height, useQuarterResolution);
}
2015-11-22 21:39:54 -08:00
}