diff --git a/src/main/java/com/seibel/lod/config/LodConfig.java b/src/main/java/com/seibel/lod/config/LodConfig.java index 55512c7ea..e16096a0b 100644 --- a/src/main/java/com/seibel/lod/config/LodConfig.java +++ b/src/main/java/com/seibel/lod/config/LodConfig.java @@ -174,6 +174,7 @@ public class LodConfig public ForgeConfigSpec.EnumValue lodQualityMode; public ForgeConfigSpec.EnumValue generationResolution; public ForgeConfigSpec.EnumValue distanceGenerationMode; + public ForgeConfigSpec.EnumValue generationPriority; public ForgeConfigSpec.BooleanValue allowUnstableFeatureGeneration; public ForgeConfigSpec.EnumValue lodDistanceCalculatorType; @@ -211,6 +212,18 @@ public class LodConfig + " quadratically to the distance of the player \n") .defineEnum("lodDistanceComputation", DistanceQualityDropOff.LINEAR); + generationPriority = builder + .comment("\n\n" + + " " + GenerationPriority.FAR + " \n" + + " the fake chunk are generated from smallest to biggest\n" + + " with a small priority for far regions \n" + + + "\n" + + " " + GenerationPriority.NORMAL + " \n" + + " the fake chunk are generated around the player \n" + + " in spiral similar to vanilla minecraft \n") + .defineEnum("Generation priority", GenerationPriority.NORMAL); + distanceGenerationMode = builder .comment("\n\n" + " Note: The times listed here are the amount of time it took \n" diff --git a/src/main/java/com/seibel/lod/enums/GenerationPriority.java b/src/main/java/com/seibel/lod/enums/GenerationPriority.java new file mode 100644 index 000000000..8301f2687 --- /dev/null +++ b/src/main/java/com/seibel/lod/enums/GenerationPriority.java @@ -0,0 +1,29 @@ +/* + * This file is part of the LOD Mod, licensed under the GNU GPL v3 License. + * + * Copyright (C) 2020 James Seibel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.seibel.lod.enums; + +/** + * @author James Seibel + * @author Leonardo Amato + */ +public enum GenerationPriority +{ + NORMAL, + + FAR; +} diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java index 1e12068d3..dde3bcbd2 100644 --- a/src/main/java/com/seibel/lod/objects/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/LodDimension.java @@ -24,6 +24,7 @@ import java.util.concurrent.Executors; import com.seibel.lod.config.LodConfig; import com.seibel.lod.enums.DistanceGenerationMode; +import com.seibel.lod.enums.GenerationPriority; import com.seibel.lod.enums.VerticalQuality; import com.seibel.lod.handlers.LodDimensionFileHandler; import com.seibel.lod.util.DataPointUtil; @@ -523,16 +524,15 @@ public class LodDimension long data; x = z = dx =0; dz = -1; - int width = numbChunksWide; - int t = width; + int t = numbChunksWide; int maxI = t*t; for(int i =0; i < maxI; i++){ if(maxDataToGenerate < 0){ break; } - if ((-width/2 <= x) && (x <= width/2) && (-width/2 <= z) && (z <= width/2)){ - xChunkToCheck = x * LodUtil.CHUNK_WIDTH + playerChunkPosX; - zChunkToCheck = z * LodUtil.CHUNK_WIDTH + playerChunkPosZ; + if ((-numbChunksWide/2 <= x) && (x <= numbChunksWide/2) && (-numbChunksWide/2 <= z) && (z <= numbChunksWide/2)){ + xChunkToCheck = x + playerChunkPosX; + zChunkToCheck = z + playerChunkPosZ; distance = LevelPosUtil.maxDistance(LodUtil.CHUNK_DETAIL_LEVEL,x,z,0,0); detailLevel = DetailDistanceUtil.getGenerationDetailFromDistance(distance); posX = LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL,xChunkToCheck, detailLevel); @@ -584,7 +584,7 @@ public class LodDimension { LodRegion region = getRegion(regionPos.x, regionPos.z); if (region != null) - region.getDataToRender(posToRender, playerPosX, playerPosZ); + region.getDataToRender(posToRender, playerPosX, playerPosZ, LodConfig.CLIENT.worldGenerator.generationPriority.get() == GenerationPriority.NORMAL); } public int getMaxVerticalData(byte detailLevel, int posX, int posZ) diff --git a/src/main/java/com/seibel/lod/objects/LodRegion.java b/src/main/java/com/seibel/lod/objects/LodRegion.java index 657ee9a12..3c930415e 100644 --- a/src/main/java/com/seibel/lod/objects/LodRegion.java +++ b/src/main/java/com/seibel/lod/objects/LodRegion.java @@ -215,15 +215,15 @@ public class LodRegion /** * @return */ - public void getDataToRender(PosToRenderContainer posToRender, int playerPosX, int playerPosZ) + public void getDataToRender(PosToRenderContainer posToRender, int playerPosX, int playerPosZ, boolean requireCorrectDetailLevel) { - getDataToRender(posToRender, LodUtil.REGION_DETAIL_LEVEL, 0, 0, playerPosX, playerPosZ); + getDataToRender(posToRender, LodUtil.REGION_DETAIL_LEVEL, 0, 0, playerPosX, playerPosZ, requireCorrectDetailLevel); } /** * @return */ - private void getDataToRender(PosToRenderContainer posToRender, byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ) + private void getDataToRender(PosToRenderContainer posToRender, byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ, boolean requireCorrectDetailLevel) { int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel); @@ -249,25 +249,38 @@ public class LodRegion { for (int z = 0; z <= 1; z++) { - if (doesDataExist(childDetailLevel, childPosX + x, childPosZ + z)) childrenCount++; + if (doesDataExist(childDetailLevel, childPosX + x, childPosZ + z)) + { + if (!requireCorrectDetailLevel) + { + childrenCount++; + } else + { + getDataToRender(posToRender, childDetailLevel, childPosX + x, childPosZ + z, playerPosX, playerPosZ, requireCorrectDetailLevel); + } + } } } //If all the four children exist we go deeper - if (childrenCount == 4) + + if(!requireCorrectDetailLevel) { - for (int x = 0; x <= 1; x++) + if (childrenCount == 4) { - for (int z = 0; z <= 1; z++) + for (int x = 0; x <= 1; x++) { - getDataToRender(posToRender, childDetailLevel, childPosX + x, childPosZ + z, playerPosX, playerPosZ); + for (int z = 0; z <= 1; z++) + { + getDataToRender(posToRender, childDetailLevel, childPosX + x, childPosZ + z, playerPosX, playerPosZ, requireCorrectDetailLevel); + } } + } else + { + posToRender.addPosToRender(detailLevel, + posX + regionPosX * size, + posZ + regionPosZ * size); } - } else - { - posToRender.addPosToRender(detailLevel, - posX + regionPosX * size, - posZ + regionPosZ * size); } } } diff --git a/src/main/java/com/seibel/lod/objects/PosToRenderContainer.java b/src/main/java/com/seibel/lod/objects/PosToRenderContainer.java index cd4912f6e..66fb9cc29 100644 --- a/src/main/java/com/seibel/lod/objects/PosToRenderContainer.java +++ b/src/main/java/com/seibel/lod/objects/PosToRenderContainer.java @@ -20,7 +20,7 @@ public class PosToRenderContainer private int numberOfPosToRender; private int[] posToRender; /*TODO this population matrix could be converted to boolean to improve memory use*/ - private byte[] population; + private byte[][] population; public PosToRenderContainer(byte minDetail, int regionPosX, int regionPosZ) { @@ -30,7 +30,7 @@ public class PosToRenderContainer this.regionPosZ = regionPosZ; this.size = 1 << (LodUtil.REGION_DETAIL_LEVEL - minDetail); posToRender = new int[size*size*3]; - population = new byte[size*size]; + population = new byte[size][size]; } public void addPosToRender(byte detailLevel, int posX, int posZ) @@ -53,16 +53,16 @@ public class PosToRenderContainer posToRender[numberOfPosToRender*3 + 1] = posX; posToRender[numberOfPosToRender*3 + 2] = posZ; numberOfPosToRender++; - population[LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posX,minDetail))*size + - LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posZ,minDetail))] = (byte) (detailLevel + 1); + population[LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posX,minDetail))] + [LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posZ,minDetail))] = (byte) (detailLevel + 1); } public boolean contains(byte detailLevel, int posX, int posZ) { if(LevelPosUtil.getRegion(detailLevel, posX) == regionPosX && LevelPosUtil.getRegion(detailLevel, posZ) == regionPosZ) { - return (population[LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posX,minDetail)) * size + - LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posZ,minDetail))] == (detailLevel + 1)); + return (population[LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posX,minDetail))] + [LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posZ,minDetail))] == (detailLevel + 1)); }else { return false; @@ -75,12 +75,13 @@ public class PosToRenderContainer if(this.minDetail == minDetail) { Arrays.fill(posToRender, 0); - Arrays.fill(population, (byte) 0); + for(int i = 0; i< population.length; i++) + Arrays.fill(population[i], (byte) 0); }else{ this.minDetail = minDetail; int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - minDetail); posToRender = new int[size*size*3]; - population = new byte[size*size]; + population = new byte[size][size]; } }