Advertisement
Guest User

MC 1.16.4 Ore Feature generation test

a guest
Jan 3rd, 2021
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.86 KB | None | 0 0
  1. public class OreTest {
  2.     private static final HashMap<Integer, OreVeinData> ORE_RATES = new HashMap<Integer, OreVeinData>(); // Map for storing values
  3.  
  4.     public static void doTest() {
  5.         System.out.println("Beginning oregen test");
  6.  
  7.         for (int i = 0; i <= 50; i++) { // Test every "Size" value between 0 and 50 inclusive
  8.             System.out.println("Testing vein generation with 'size' value: " + i);
  9.  
  10.             for (int j = 0; j <= 100000000; j++) { // Loop 100 million times for every value for more accurate averages
  11.                 Random rand = new Random(); // Generate new random every loop for true random cycles
  12.                 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
  13.  
  14.                 generate(null, null, rand, pos, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, Blocks.DIAMOND_ORE.getDefaultState(), i)); // Generate, in the exact same way vanilla does.
  15.             }
  16.         }
  17.  
  18.         // Loop through ore data map and print out results
  19.         System.out.println("Printing out ore generation data");
  20.         System.out.println("--");
  21.  
  22.         for (Map.Entry<Integer, OreVeinData> entry : ORE_RATES.entrySet()) {
  23.             OreVeinData data = entry.getValue();
  24.             int min = data.minimumOres;
  25.             int max = data.maximumOres;
  26.             float avg = data.cumulativeOres / (float)data.veinsCounted;
  27.  
  28.             System.out.println("Vein Size: " + entry.getKey() + ". Min Ores: " + min + ", Max Ores: " + max + ", Average ores: " + avg);
  29.         }
  30.     }
  31.  
  32.     // Container class for holding ore & vein data
  33.     private static class OreVeinData {
  34.         private int veinsCounted = 0;
  35.         private int cumulativeOres = 0;
  36.  
  37.         private int minimumOres;
  38.         private int maximumOres;
  39.  
  40.         private OreVeinData(int ores) {
  41.             this.minimumOres = ores;
  42.             this.maximumOres = ores;
  43.             this.cumulativeOres = ores;
  44.             veinsCounted = 1;
  45.         }
  46.  
  47.         // Add new vein to data
  48.         private void addOreVein(int oresInVein) {
  49.             if (minimumOres > oresInVein) // Replace minimum vein size if necessary
  50.                 minimumOres = oresInVein;
  51.  
  52.             if (maximumOres < oresInVein) // Replace maximum vein size if necessary
  53.                 maximumOres = oresInVein;
  54.  
  55.             cumulativeOres += oresInVein; // Add vein to total ores count
  56.             veinsCounted++; // Increment total number of veins counted
  57.         }
  58.     }
  59.  
  60.     private static void addOreCount(int sizeValue, int oresInVein) {
  61.         if (ORE_RATES.containsKey(sizeValue)) {
  62.             ORE_RATES.get(sizeValue).addOreVein(oresInVein);
  63.         }
  64.         else {
  65.             ORE_RATES.put(sizeValue, new OreVeinData(oresInVein));
  66.         }
  67.     }
  68.  
  69.     // Leaving unnecessary casts & code for easier comparison with live code in OreFeature
  70.     public static boolean generate(IWorld world, ChunkGenerator chunkGen, Random rand, BlockPos pos, OreFeatureConfig config) {
  71.         float veinSizeRandomMod = rand.nextFloat() * (float)Math.PI;
  72.         float veinSizeMod = (float)config.size / 8.0F;
  73.         int additionalBlockWidth = MathHelper.ceil(((float)config.size / 16.0F * 2.0F + 1.0F) / 2.0F);
  74.         double maxX = (double)pos.getX() + Math.sin((double)veinSizeRandomMod) * (double)veinSizeMod;
  75.         double minX = (double)pos.getX() - Math.sin((double)veinSizeRandomMod) * (double)veinSizeMod;
  76.         double maxZ = (double)pos.getZ() + Math.cos((double)veinSizeRandomMod) * (double)veinSizeMod;
  77.         double minZ = (double)pos.getZ() - Math.cos((double)veinSizeRandomMod) * (double)veinSizeMod;
  78.         //int j = 2; Useless variable lol
  79.         double yPos1 = (double)(pos.getY() + rand.nextInt(3) - 2);
  80.         double yPos2 = (double)(pos.getY() + rand.nextInt(3) - 2);
  81.         int veinRadiusX = pos.getX() - MathHelper.ceil(veinSizeMod) - additionalBlockWidth;
  82.         int minY = pos.getY() - 2 - additionalBlockWidth;
  83.         int veinRadiusZ = pos.getZ() - MathHelper.ceil(veinSizeMod) - additionalBlockWidth;
  84.         int j1 = 2 * (MathHelper.ceil(veinSizeMod) + additionalBlockWidth);
  85.         int k1 = 2 * (2 + additionalBlockWidth);
  86.  
  87.         for(int x = veinRadiusX; x <= veinRadiusX + j1; ++x) {
  88.             for(int z = veinRadiusZ; z <= veinRadiusZ + j1; ++z) {
  89.                 // if (l <= world.getHeight(Heightmap.Type.OCEAN_FLOOR_WG, x, z)) Remove check as it's not necessary for testing
  90.                     return attemptVeinGeneration(world, rand, config, maxX, minX, maxZ, minZ, yPos1, yPos2, veinRadiusX, minY, veinRadiusZ, j1, k1);
  91.             }
  92.         }
  93.  
  94.         return false;
  95.     }
  96.  
  97.     // Remapping func_207803_a
  98.     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_) {
  99.         int oresInVein = 0;
  100.         BitSet bitSet = new BitSet(p_207803_19_ * p_207803_20_ * p_207803_19_);
  101.         BlockPos.Mutable orePlacementPos = new BlockPos.Mutable();
  102.         int configSize = config.size;
  103.         double[] adouble = new double[configSize * 4];
  104.  
  105.         for(int i = 0; i < configSize; ++i) {
  106.             float veinProgress = (float)i / (float)configSize;
  107.             double lerpX = MathHelper.lerp((double)veinProgress, maxX, minX);
  108.             double lerpY = MathHelper.lerp((double)veinProgress, firstY, secondY);
  109.             double lerpZ = MathHelper.lerp((double)veinProgress, maxZ, minZ);
  110.             double blockRandOffset = rand.nextDouble() * (double)configSize / 16.0D;
  111.             double d7 = ((double)(MathHelper.sin((float)Math.PI * veinProgress) + 1.0F) * blockRandOffset + 1.0D) / 2.0D;
  112.             adouble[i * 4 + 0] = lerpX;
  113.             adouble[i * 4 + 1] = lerpY;
  114.             adouble[i * 4 + 2] = lerpZ;
  115.             adouble[i * 4 + 3] = d7;
  116.         }
  117.         // Couldn't be bothered mapping the rest of the values lol
  118.         for(int i = 0; i < configSize - 1; ++i) {
  119.             if (!(adouble[i * 4 + 3] <= 0.0D)) {
  120.                 for(int iPlus1 = i + 1; iPlus1 < configSize; ++iPlus1) {
  121.                     if (!(adouble[iPlus1 * 4 + 3] <= 0.0D)) {
  122.                         double d12 = adouble[i * 4 + 0] - adouble[iPlus1 * 4 + 0];
  123.                         double d13 = adouble[i * 4 + 1] - adouble[iPlus1 * 4 + 1];
  124.                         double d14 = adouble[i * 4 + 2] - adouble[iPlus1 * 4 + 2];
  125.                         double d15 = adouble[i * 4 + 3] - adouble[iPlus1 * 4 + 3];
  126.                         if (d15 * d15 > d12 * d12 + d13 * d13 + d14 * d14) {
  127.                             if (d15 > 0.0D) {
  128.                                 adouble[iPlus1 * 4 + 3] = -1.0D;
  129.                             } else {
  130.                                 adouble[i * 4 + 3] = -1.0D;
  131.                             }
  132.                         }
  133.                     }
  134.                 }
  135.             }
  136.         }
  137.  
  138.         for(int j3 = 0; j3 < configSize; ++j3) {
  139.             double d11 = adouble[j3 * 4 + 3];
  140.             if (!(d11 < 0.0D)) {
  141.                 double d1 = adouble[j3 * 4 + 0];
  142.                 double d3 = adouble[j3 * 4 + 1];
  143.                 double d5 = adouble[j3 * 4 + 2];
  144.                 int l = Math.max(MathHelper.floor(d1 - d11), veinRadiusX);
  145.                 int l3 = Math.max(MathHelper.floor(d3 - d11), minY);
  146.                 int i1 = Math.max(MathHelper.floor(d5 - d11), veinRadiusZ);
  147.                 int j1 = Math.max(MathHelper.floor(d1 + d11), l);
  148.                 int k1 = Math.max(MathHelper.floor(d3 + d11), l3);
  149.                 int l1 = Math.max(MathHelper.floor(d5 + d11), i1);
  150.  
  151.                 for(int x = l; x <= j1; ++x) {
  152.                     double d8 = ((double)x + 0.5D - d1) / d11;
  153.                     if (d8 * d8 < 1.0D) {
  154.                         for(int y = l3; y <= k1; ++y) {
  155.                             double d9 = ((double)y + 0.5D - d3) / d11;
  156.                             if (d8 * d8 + d9 * d9 < 1.0D) {
  157.                                 for(int z = i1; z <= l1; ++z) {
  158.                                     double d10 = ((double)z + 0.5D - d5) / d11;
  159.                                     if (d8 * d8 + d9 * d9 + d10 * d10 < 1.0D) {
  160.                                         int bitPosition = x - veinRadiusX + (y - minY) * p_207803_19_ + (z - veinRadiusZ) * p_207803_19_ * p_207803_20_;
  161.                                         if (!bitSet.get(bitPosition)) {
  162.                                             bitSet.set(bitPosition);
  163.                                             orePlacementPos.setPos(x, y, z);
  164.                                             //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
  165.                                                 // world.setBlockState(orePlacementPos, config.state, 2); Remove actual block placement as we don't need to do that for this test
  166.                                                 ++oresInVein;
  167.                                             //}
  168.                                         }
  169.                                     }
  170.                                 }
  171.                             }
  172.                         }
  173.                     }
  174.                 }
  175.             }
  176.         }
  177.  
  178.         if (oresInVein > 0) // Filter out 0-size veins as vanilla does
  179.             addOreCount(config.size, oresInVein);
  180.  
  181.         return oresInVein > 0;
  182.     }
  183. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement