Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class OreTest {
- private static final HashMap<Integer, OreVeinData> ORE_RATES = new HashMap<Integer, OreVeinData>(); // Map for storing values
- public static void doTest() {
- System.out.println("Beginning oregen test");
- for (int i = 0; i <= 50; i++) { // Test every "Size" value between 0 and 50 inclusive
- System.out.println("Testing vein generation with 'size' value: " + i);
- for (int j = 0; j <= 100000000; j++) { // Loop 100 million times for every value for more accurate averages
- Random rand = new Random(); // Generate new random every loop for true random cycles
- BlockPos pos = new BlockPos(rand.nextInt(15), 5 + rand.nextInt(55), rand.nextInt(15)); // Generate random position each loop. Entirely unnecessary, but just in case
- generate(null, null, rand, pos, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, Blocks.DIAMOND_ORE.getDefaultState(), i)); // Generate, in the exact same way vanilla does.
- }
- }
- // Loop through ore data map and print out results
- System.out.println("Printing out ore generation data");
- System.out.println("--");
- for (Map.Entry<Integer, OreVeinData> entry : ORE_RATES.entrySet()) {
- OreVeinData data = entry.getValue();
- int min = data.minimumOres;
- int max = data.maximumOres;
- float avg = data.cumulativeOres / (float)data.veinsCounted;
- System.out.println("Vein Size: " + entry.getKey() + ". Min Ores: " + min + ", Max Ores: " + max + ", Average ores: " + avg);
- }
- }
- // Container class for holding ore & vein data
- private static class OreVeinData {
- private int veinsCounted = 0;
- private int cumulativeOres = 0;
- private int minimumOres;
- private int maximumOres;
- private OreVeinData(int ores) {
- this.minimumOres = ores;
- this.maximumOres = ores;
- this.cumulativeOres = ores;
- veinsCounted = 1;
- }
- // Add new vein to data
- private void addOreVein(int oresInVein) {
- if (minimumOres > oresInVein) // Replace minimum vein size if necessary
- minimumOres = oresInVein;
- if (maximumOres < oresInVein) // Replace maximum vein size if necessary
- maximumOres = oresInVein;
- cumulativeOres += oresInVein; // Add vein to total ores count
- veinsCounted++; // Increment total number of veins counted
- }
- }
- private static void addOreCount(int sizeValue, int oresInVein) {
- if (ORE_RATES.containsKey(sizeValue)) {
- ORE_RATES.get(sizeValue).addOreVein(oresInVein);
- }
- else {
- ORE_RATES.put(sizeValue, new OreVeinData(oresInVein));
- }
- }
- // Leaving unnecessary casts & code for easier comparison with live code in OreFeature
- public static boolean generate(IWorld world, ChunkGenerator chunkGen, Random rand, BlockPos pos, OreFeatureConfig config) {
- float veinSizeRandomMod = rand.nextFloat() * (float)Math.PI;
- float veinSizeMod = (float)config.size / 8.0F;
- int additionalBlockWidth = MathHelper.ceil(((float)config.size / 16.0F * 2.0F + 1.0F) / 2.0F);
- double maxX = (double)pos.getX() + Math.sin((double)veinSizeRandomMod) * (double)veinSizeMod;
- double minX = (double)pos.getX() - Math.sin((double)veinSizeRandomMod) * (double)veinSizeMod;
- double maxZ = (double)pos.getZ() + Math.cos((double)veinSizeRandomMod) * (double)veinSizeMod;
- double minZ = (double)pos.getZ() - Math.cos((double)veinSizeRandomMod) * (double)veinSizeMod;
- //int j = 2; Useless variable lol
- double yPos1 = (double)(pos.getY() + rand.nextInt(3) - 2);
- double yPos2 = (double)(pos.getY() + rand.nextInt(3) - 2);
- int veinRadiusX = pos.getX() - MathHelper.ceil(veinSizeMod) - additionalBlockWidth;
- int minY = pos.getY() - 2 - additionalBlockWidth;
- int veinRadiusZ = pos.getZ() - MathHelper.ceil(veinSizeMod) - additionalBlockWidth;
- int j1 = 2 * (MathHelper.ceil(veinSizeMod) + additionalBlockWidth);
- int k1 = 2 * (2 + additionalBlockWidth);
- for(int x = veinRadiusX; x <= veinRadiusX + j1; ++x) {
- for(int z = veinRadiusZ; z <= veinRadiusZ + j1; ++z) {
- // if (l <= world.getHeight(Heightmap.Type.OCEAN_FLOOR_WG, x, z)) Remove check as it's not necessary for testing
- return attemptVeinGeneration(world, rand, config, maxX, minX, maxZ, minZ, yPos1, yPos2, veinRadiusX, minY, veinRadiusZ, j1, k1);
- }
- }
- return false;
- }
- // Remapping func_207803_a
- protected static boolean attemptVeinGeneration(IWorld world, Random rand, OreFeatureConfig config, double maxX, double minX, double maxZ, double minZ, double firstY, double secondY, int veinRadiusX, int minY, int veinRadiusZ, int p_207803_19_, int p_207803_20_) {
- int oresInVein = 0;
- BitSet bitSet = new BitSet(p_207803_19_ * p_207803_20_ * p_207803_19_);
- BlockPos.Mutable orePlacementPos = new BlockPos.Mutable();
- int configSize = config.size;
- double[] adouble = new double[configSize * 4];
- for(int i = 0; i < configSize; ++i) {
- float veinProgress = (float)i / (float)configSize;
- double lerpX = MathHelper.lerp((double)veinProgress, maxX, minX);
- double lerpY = MathHelper.lerp((double)veinProgress, firstY, secondY);
- double lerpZ = MathHelper.lerp((double)veinProgress, maxZ, minZ);
- double blockRandOffset = rand.nextDouble() * (double)configSize / 16.0D;
- double d7 = ((double)(MathHelper.sin((float)Math.PI * veinProgress) + 1.0F) * blockRandOffset + 1.0D) / 2.0D;
- adouble[i * 4 + 0] = lerpX;
- adouble[i * 4 + 1] = lerpY;
- adouble[i * 4 + 2] = lerpZ;
- adouble[i * 4 + 3] = d7;
- }
- // Couldn't be bothered mapping the rest of the values lol
- for(int i = 0; i < configSize - 1; ++i) {
- if (!(adouble[i * 4 + 3] <= 0.0D)) {
- for(int iPlus1 = i + 1; iPlus1 < configSize; ++iPlus1) {
- if (!(adouble[iPlus1 * 4 + 3] <= 0.0D)) {
- double d12 = adouble[i * 4 + 0] - adouble[iPlus1 * 4 + 0];
- double d13 = adouble[i * 4 + 1] - adouble[iPlus1 * 4 + 1];
- double d14 = adouble[i * 4 + 2] - adouble[iPlus1 * 4 + 2];
- double d15 = adouble[i * 4 + 3] - adouble[iPlus1 * 4 + 3];
- if (d15 * d15 > d12 * d12 + d13 * d13 + d14 * d14) {
- if (d15 > 0.0D) {
- adouble[iPlus1 * 4 + 3] = -1.0D;
- } else {
- adouble[i * 4 + 3] = -1.0D;
- }
- }
- }
- }
- }
- }
- for(int j3 = 0; j3 < configSize; ++j3) {
- double d11 = adouble[j3 * 4 + 3];
- if (!(d11 < 0.0D)) {
- double d1 = adouble[j3 * 4 + 0];
- double d3 = adouble[j3 * 4 + 1];
- double d5 = adouble[j3 * 4 + 2];
- int l = Math.max(MathHelper.floor(d1 - d11), veinRadiusX);
- int l3 = Math.max(MathHelper.floor(d3 - d11), minY);
- int i1 = Math.max(MathHelper.floor(d5 - d11), veinRadiusZ);
- int j1 = Math.max(MathHelper.floor(d1 + d11), l);
- int k1 = Math.max(MathHelper.floor(d3 + d11), l3);
- int l1 = Math.max(MathHelper.floor(d5 + d11), i1);
- for(int x = l; x <= j1; ++x) {
- double d8 = ((double)x + 0.5D - d1) / d11;
- if (d8 * d8 < 1.0D) {
- for(int y = l3; y <= k1; ++y) {
- double d9 = ((double)y + 0.5D - d3) / d11;
- if (d8 * d8 + d9 * d9 < 1.0D) {
- for(int z = i1; z <= l1; ++z) {
- double d10 = ((double)z + 0.5D - d5) / d11;
- if (d8 * d8 + d9 * d9 + d10 * d10 < 1.0D) {
- int bitPosition = x - veinRadiusX + (y - minY) * p_207803_19_ + (z - veinRadiusZ) * p_207803_19_ * p_207803_20_;
- if (!bitSet.get(bitPosition)) {
- bitSet.set(bitPosition);
- orePlacementPos.setPos(x, y, z);
- //if (config.target.test(world.getBlockState(blockpos$mutable), rand)) { Remove test if block at position is stone or not (ores don't place in midair). For this test we assume all blocks are stone
- // world.setBlockState(orePlacementPos, config.state, 2); Remove actual block placement as we don't need to do that for this test
- ++oresInVein;
- //}
- }
- }
- }
- }
- }
- }
- }
- }
- }
- if (oresInVein > 0) // Filter out 0-size veins as vanilla does
- addOreCount(config.size, oresInVein);
- return oresInVein > 0;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement