From b70fc86516f06010c2d3dc4eeacf4b6c1d5ad143 Mon Sep 17 00:00:00 2001 From: coolGi2007 Date: Wed, 30 Mar 2022 17:35:09 +1030 Subject: [PATCH] Downgraded 1.18 to 1.17 (that took a long time) tough still needs some fixing --- .gitignore | 3 + .gitmodules | 1 + 1.17.1.properties | 36 ++ Readme.md | 46 +- build.gradle | 61 ++- .../java/com/seibel/lod/common/Config.java | 227 ++++++++-- .../common/wrappers/McObjectConverter.java | 3 +- .../lod/common/wrappers/VersionConstants.java | 28 -- .../lod/common/wrappers/WrapperFactory.java | 7 - .../wrappers/block/BlockDetailWrapper.java | 50 ++- .../block/TintGetterOverrideFast.java | 192 +++++++++ .../block/TintGetterOverrideSmooth.java | 215 ++++++++++ .../common/wrappers/chunk/ChunkWrapper.java | 74 ++-- .../lod/common/wrappers/config/ConfigGui.java | 1 + .../config/LodConfigWrapperSingleton.java | 393 +++++++++++++++++- .../minecraft/MinecraftClientWrapper.java | 18 +- .../minecraft/MinecraftRenderWrapper.java | 109 +++-- .../common/wrappers/world/BiomeWrapper.java | 10 +- .../common/wrappers/world/WorldWrapper.java | 8 + .../BatchGenerationEnvironment.java | 142 +++---- .../worldGeneration/ThreadedParameters.java | 10 +- .../WorldGeneratorWrapper.java | 152 ------- .../mimicObject/ChunkLoader.java | 7 +- .../mimicObject/LightedWorldGenRegion.java | 11 + .../WorldGenStructFeatManager.java | 17 +- .../worldGeneration/step/StepFeatures.java | 4 +- .../worldGeneration/step/StepLight.java | 4 +- common/src/main/resources/lod.accesswidener | 5 +- core | 2 +- .../com/seibel/lod/fabric/ClientProxy.java | 4 + .../mixins/MixinUtilBackgroudThread.java | 5 +- .../lod/fabric/mixins/MixinWorldRenderer.java | 9 +- fabric/src/main/resources/fabric.mod.json | 4 +- .../java/com/seibel/lod/forge/ForgeMain.java | 22 +- .../lod/forge/mixins/MixinWorldRenderer.java | 8 +- gradle.properties | 44 +- plugins/DHJarMerger-1.0.jar | Bin 337924 -> 337990 bytes 37 files changed, 1439 insertions(+), 493 deletions(-) create mode 100644 1.17.1.properties create mode 100644 common/src/main/java/com/seibel/lod/common/wrappers/block/TintGetterOverrideFast.java create mode 100644 common/src/main/java/com/seibel/lod/common/wrappers/block/TintGetterOverrideSmooth.java delete mode 100644 common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/WorldGeneratorWrapper.java diff --git a/.gitignore b/.gitignore index 764894d0e..a07e0864a 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,6 @@ Merged/ # file from notepad++ *.bak + +# file genearated via MC version switching using preprocessor +build.properties \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 17c60bca6..c9d192eec 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,4 @@ [submodule "core"] path = core url = https://gitlab.com/jeseibel/distant-horizons-core.git + branch = main \ No newline at end of file diff --git a/1.17.1.properties b/1.17.1.properties new file mode 100644 index 000000000..cf7c79dca --- /dev/null +++ b/1.17.1.properties @@ -0,0 +1,36 @@ +org.gradle.jvmargs=-Xmx2048M + +minecraft_version=1.17.1 +java_version=16 + +# Fabric loader +fabric_loader_version=0.13.2 +fabric_api_version=0.46.1+1.17 + # Fabric mod versions + modmenu_version=2.0.14 + starlight_version_fabric=3442770 + lithium_version=mc1.17.1-0.7.5 + sodium_version=3605275 + iris_version=1.17.x-v1.1.4 + immersive_portals_version = 0.14-1.17 + + # Fabric mod run + # 0 = Dont enable and dont run + # 1 = Can be refranced in code but dosnt run + # 2 = Can be refranced in code and runs in client + enable_starlight=0 + enable_lithium=0 + enable_sodium=1 + enable_iris=0 + + +# Forge loader +forge_version=37.1.1 + # Forge mod versions + starlight_version_forge=3457784 + + # Forge mod run + # 0 = Dont enable and dont run + # 1 = Can be refranced in code but dosnt run + # 2 = Can be refranced in code and runs in client + enable_starlight_forge=0 diff --git a/Readme.md b/Readme.md index 349144413..c62e96f43 100644 --- a/Readme.md +++ b/Readme.md @@ -14,38 +14,48 @@ If you want to see a quick demo, check out a video covering the mod here: ![Minecraft Level Of Detail (LOD) mod - Alpha 1.5](https://i.ytimg.com/vi_webp/H2tnvEVbO1c/mqdefault.webp) +### Versions + Architectury version: 3.4-SNAPSHOT\ -Forge version: 37.1.0\ +Java Compiler plugin: Manifold Preprocessor + +#### 1.17.1 mods +Forge version: 37.1.1\ Fabric version: 0.13.2\ -Fabric API version: 0.46.1+1.17.1 - +Fabric API version: 0.46.1+1.17\ Modmenu version: 2.0.14 -Notes:\ -This version has been confirmed to work in Eclipse and Retail Minecraft.\ -(Retail running forge version 1.17.1-37.1.0 and fabric version 1.17.1-0.12.6) - ## Source Code Installation -See the Forge Documentation online for more detailed instructions:\ -http://mcforge.readthedocs.io/en/latest/gettingstarted/ +See the Fabric Documentation online for more detailed instructions:\ +https://fabricmc.net/wiki/tutorial:setup ### Prerequisites -* A Java Development Kit (JDK) for Java 16 (recommended) or newer. Visit https://www.oracle.com/java/technologies/downloads/ for installers. +* A Java Development Kit (JDK) for Java 17 (recommended) or newer. Visit https://www.oracle.com/java/technologies/downloads/ for installers. * Git or someway to clone git projects. Visit https://git-scm.com/ for installers. -* (Not required) Any Java IDE, for example Intellij IDEA and Eclipse. You may also use any other code editors, such as Visual Studio Code. (Optional) - It's better to use IntelliJ IDEA since Eclipse is not supported by Architectury, but it still works. +* (Not required) Any Java IDE with plugins that support Manifold, for example Intellij IDEA. **If using IntelliJ:** +0. Install Manifold plugin 1. open IDEA and import the build.gradle 2. refresh the Gradle project in IDEA if required -**If using Ecplise:** -Not supported... +**If using Ecplise: (Note that Eclispe currently doesn't support Manifold's preprocessor!)** +1. run the command: `./gradlew geneclipseruns` +2. run the command: `./gradlew eclipse` +3. Make sure eclipse has the JDK 17 installed. (This is needed so that eclipse can run minecraft) +4. Import the project into eclipse -Side note: invalidate caches and restart if required +## Switching Versions +This branch support 1 built versions: +- 1.17.1 (which also runs on 1.17) + +To switch between active versions, change `mcVer=1.17.?` in `gradle.properties` file. + +If running on IDE, to ensure IDE pickup the changed versions, you will need to run a gradle command again to allow gradle to update all the libs. (In IntellJ you will also need to do a gradle sync again if it didn't start it automatically.) +>Note: There may be a `java.nio.file.FileSystemException` thrown on running the command after switching versions. To fix it, either restart your IDE (as your IDE is locking up a file) or use tools like LockHunter to unlock the linked file. (Often a lib file under `common\build\lib` or `forge\build\lib` or `fabric\build\lib`). If anyone knows how to solve this issue please comment to this issue: https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/233 ## Compiling @@ -57,13 +67,13 @@ Side note: invalidate caches and restart if required 5. Then run command: `./gradlew mergeJars` 6. The compiled jar file will be in the folder `Merged` - **If in terminal:** -1. `git clone -b 1.17.X --recurse-submodules https://gitlab.com/jeseibel/minecraft-lod-mod.git` +1. `git clone -b preprocessor_test --recurse-submodules https://gitlab.com/jeseibel/minecraft-lod-mod.git` 2. `cd minecraft-lod-mod` 3. `./gradlew assemble` 4. `./gradlew mergeJars` -6. The compiled jar file will be in the folder `Merged` +5. The compiled jar file will be in the folder `Merged` +>Note: You can add the arg: `-PmcVer=1.17.?` to tell gradle to build a selected MC version instead of having to manually modify the `gradle.properties` file. ## Other commands diff --git a/build.gradle b/build.gradle index c88e79a67..e4e5543d8 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ import io.github.ran.jarmerger.JarMergerPlugin + buildscript { dependencies{ classpath files('plugins/DHJarMerger-1.0.jar') @@ -11,6 +12,31 @@ plugins { id "dev.architectury.loom" version "0.10.0.195" apply false } +def writeBuildGradlePredefine() { + def excapedMCVersion = rootProject.minecraft_version.replace(".", "_") + new File(projectDir, "build.properties").text = "MC_VERSION_${excapedMCVersion}=\n" +} + +def loadProperties() { + def defaultMcVersion = '1.17.1' + if (!project.hasProperty("mcVer")) { + println "No mcVer set! Defaulting to ${defaultMcVersion}." + println "Tip: Use -PmcVer='${defaultMcVersion}' in cmd arg to set mcVer." + } + def mcVersion = project.hasProperty("mcVer") ? mcVer : defaultMcVersion + + println "Loading properties file at " + mcVersion + ".properties" + def props = new Properties() + props.load(new FileInputStream("$rootProject.rootDir/"+"$mcVersion"+".properties")) + + props.each { prop -> + rootProject.ext.set(prop.key, prop.value) + // println "Added prop [key:" + prop.key + ", value:" + prop.value + "]" + } + writeBuildGradlePredefine() +} +loadProperties() + apply plugin: JarMergerPlugin architectury { @@ -35,6 +61,9 @@ subprojects { p -> // The following line declares the mojmap mappings mappings loom.officialMojangMappings() + //Manifold + annotationProcessor "systems.manifold:manifold-preprocessor:${rootProject.manifold_version}" + // Toml implementation("com.electronwill.night-config:toml:${rootProject.toml_version}") @@ -74,6 +103,9 @@ allprojects { // used to download and compile dependencies from git repos maven { url 'https://jitpack.io' } + // For Manifold Preprocessor + maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } + // Required for importing Modrinth mods maven { name = "Modrinth" @@ -117,8 +149,11 @@ allprojects { description: mod_description, homepage: mod_homepage, source: mod_source, - issues: mod_issues + issues: mod_issues, + minecraft_version: minecraft_version, + java_version: java_version ] // The left side is what gets replaced in the mod info and the right side is where to get it from in the gradle.properties + //TODO: Make Forge loader version also be relaced with non hardcoded value instead of "[36,41)" inputs.properties replaceProperties replaceProperties.put 'project', project @@ -140,6 +175,23 @@ allprojects { } tasks.withType(JavaCompile) { +// // Add Manifold Preprocessor +//// def excapedMCVersion = rootProject.minecraft_version.replace(".", "_") +//// options.compilerArgs += ['-Xplugin:Manifold', "-AMC_VERSION_${excapedMCVersion}"] +//// +// //options.compilerArgs += ['-deprecation'] +// //options.compilerArgs += ['-verbose'] +// //options.compilerArgs += ['-Xlint:unchecked'] +// //options.compilerArgs += ['-Xdiags:verbose'] +// //options.compilerArgs += ['-Xprint'] +// //options.compilerArgs += ['-XprintProcessorInfo'] +// //options.compilerArgs += ['-XprintRounds'] +// +// // println options.compilerArgs +// if (p != project(":core")) { +// options.compilerArgs += ['-Xplugin:Manifold'] +// options.release = rootProject.java_version as Integer +// } options.encoding = "UTF-8" options.release = 16 } @@ -148,3 +200,10 @@ allprojects { withSourcesJar() } } + + +// this deletes the merged folder so we don't carry over +// the previous merges to each new build job in the CI/CD pipeline +task deleteMerged(type: Delete) { + delete files("./Merged") +} \ No newline at end of file diff --git a/common/src/main/java/com/seibel/lod/common/Config.java b/common/src/main/java/com/seibel/lod/common/Config.java index b363a5407..5122638e1 100644 --- a/common/src/main/java/com/seibel/lod/common/Config.java +++ b/common/src/main/java/com/seibel/lod/common/Config.java @@ -26,8 +26,12 @@ import com.seibel.lod.core.enums.rendering.*; import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IAdvanced.*; import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IGraphics.*; +import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IGraphics.IFogQuality.IAdvancedFog; +import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IGraphics.IFogQuality.IAdvancedFog.IHeightFog; import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IMultiplayer; import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IWorldGenerator; +import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IAdvanced; +import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IAdvanced.IDebugging.*; /** * This handles any configuration the user has access to. @@ -65,8 +69,7 @@ public class Config extends ConfigGui @ConfigAnnotations.Entry public static boolean optionsButton = true; - public static class Client - { + public static class Client { @ConfigAnnotations.ScreenEntry public static Graphics graphics; @@ -80,8 +83,7 @@ public class Config extends ConfigGui public static Advanced advanced; - public static class Graphics - { + public static class Graphics { @ConfigAnnotations.ScreenEntry public static Quality quality; @@ -92,8 +94,7 @@ public class Config extends ConfigGui public static AdvancedGraphics advancedGraphics; - public static class Quality - { + public static class Quality { @ConfigAnnotations.FileComment public static String _drawResolution = IQuality.DRAW_RESOLUTION_DESC; @ConfigAnnotations.Entry @@ -123,11 +124,15 @@ public class Config extends ConfigGui public static String _dropoffQuality = IQuality.DROPOFF_QUALITY_DESC; @ConfigAnnotations.Entry public static DropoffQuality dropoffQuality = IQuality.DROPOFF_QUALITY_DEFAULT; + + @ConfigAnnotations.FileComment + public static String _lodBiomeBlending = IQuality.LOD_BIOME_BLENDING_DESC; + @ConfigAnnotations.Entry(minValue = 0, maxValue = 7) + public static int lodBiomeBlending = IQuality.LOD_BIOME_BLENDING_MIN_DEFAULT_MAX.defaultValue; } - public static class FogQuality - { + public static class FogQuality { @ConfigAnnotations.FileComment public static String _fogDistance = IFogQuality.FOG_DISTANCE_DESC; @ConfigAnnotations.Entry @@ -147,11 +152,97 @@ public class Config extends ConfigGui public static String _disableVanillaFog = IFogQuality.DISABLE_VANILLA_FOG_DESC; @ConfigAnnotations.Entry public static boolean disableVanillaFog = IFogQuality.DISABLE_VANILLA_FOG_DEFAULT; + + @ConfigAnnotations.ScreenEntry + public static AdvancedFog advancedFog; + + public static class AdvancedFog { + static final double SQRT2 = 1.4142135623730951; + + @ConfigAnnotations.FileComment + public static String _farFogStart = IAdvancedFog.FAR_FOG_START_DESC; + @ConfigAnnotations.Entry(minValue = 0.0, maxValue = SQRT2) + public static double farFogStart = IAdvancedFog.FAR_FOG_START_MIN_DEFAULT_MAX.defaultValue; + + @ConfigAnnotations.FileComment + public static String _farFogEnd = IAdvancedFog.FAR_FOG_END_DESC; + @ConfigAnnotations.Entry(minValue = 0.0, maxValue = SQRT2) + public static double farFogEnd = IAdvancedFog.FAR_FOG_END_MIN_DEFAULT_MAX.defaultValue; + + @ConfigAnnotations.FileComment + public static String _farFogMin = IAdvancedFog.FAR_FOG_MIN_DESC; + @ConfigAnnotations.Entry(minValue = -5.0, maxValue = SQRT2) + public static double farFogMin = IAdvancedFog.FAR_FOG_MIN_MIN_DEFAULT_MAX.defaultValue; + + @ConfigAnnotations.FileComment + public static String _farFogMax = IAdvancedFog.FAR_FOG_MAX_DESC; + @ConfigAnnotations.Entry(minValue = 0.0, maxValue = 5.0) + public static double farFogMax = IAdvancedFog.FAR_FOG_MAX_MIN_DEFAULT_MAX.defaultValue; + + @ConfigAnnotations.FileComment + public static String _farFogType = IAdvancedFog.FAR_FOG_TYPE_DESC; + @ConfigAnnotations.Entry + public static FogSetting.FogType farFogType = IAdvancedFog.FAR_FOG_TYPE_DEFAULT; + + @ConfigAnnotations.FileComment + public static String _farFogDensity = IAdvancedFog.FAR_FOG_DENSITY_DESC; + @ConfigAnnotations.Entry(minValue = 0.01, maxValue = 50.0) + public static double farFogDensity = IAdvancedFog.FAR_FOG_DENSITY_MIN_DEFAULT_MAX.defaultValue; + + @ConfigAnnotations.ScreenEntry + public static HeightFog heightFog; + + public static class HeightFog { + + @ConfigAnnotations.FileComment + public static String _heightFogMixMode = IHeightFog.HEIGHT_FOG_MIX_MODE_DESC; + @ConfigAnnotations.Entry + public static HeightFogMixMode heightFogMixMode = IHeightFog.HEIGHT_FOG_MIX_MODE_DEFAULT; + @ConfigAnnotations.FileComment + public static String _heightFogMode = IHeightFog.HEIGHT_FOG_MODE_DESC; + @ConfigAnnotations.Entry + public static HeightFogMode heightFogMode = IHeightFog.HEIGHT_FOG_MODE_DEFAULT; + + @ConfigAnnotations.FileComment + public static String _heightFogHeight = IHeightFog.HEIGHT_FOG_HEIGHT_DESC; + @ConfigAnnotations.Entry(minValue = -4096.0, maxValue = 4096.0) + public static double heightFogHeight = IHeightFog.HEIGHT_FOG_HEIGHT_MIN_DEFAULT_MAX.defaultValue; + + @ConfigAnnotations.FileComment + public static String _heightFogStart = IHeightFog.HEIGHT_FOG_START_DESC; + @ConfigAnnotations.Entry(minValue = 0.0, maxValue = SQRT2) + public static double heightFogStart = IHeightFog.HEIGHT_FOG_START_MIN_DEFAULT_MAX.defaultValue; + + @ConfigAnnotations.FileComment + public static String _heightFogEnd = IHeightFog.HEIGHT_FOG_END_DESC; + @ConfigAnnotations.Entry(minValue = 0.0, maxValue = SQRT2) + public static double heightFogEnd = IHeightFog.HEIGHT_FOG_END_MIN_DEFAULT_MAX.defaultValue; + + @ConfigAnnotations.FileComment + public static String _heightFogMin = IHeightFog.HEIGHT_FOG_MIN_DESC; + @ConfigAnnotations.Entry(minValue = -5.0, maxValue = SQRT2) + public static double heightFogMin = IHeightFog.HEIGHT_FOG_MIN_MIN_DEFAULT_MAX.defaultValue; + + @ConfigAnnotations.FileComment + public static String _heightFogMax = IHeightFog.HEIGHT_FOG_MAX_DESC; + @ConfigAnnotations.Entry(minValue = 0.0, maxValue = 5.0) + public static double heightFogMax = IHeightFog.HEIGHT_FOG_MAX_MIN_DEFAULT_MAX.defaultValue; + + @ConfigAnnotations.FileComment + public static String _heightFogType = IHeightFog.HEIGHT_FOG_TYPE_DESC; + @ConfigAnnotations.Entry + public static FogSetting.FogType heightFogType = IHeightFog.HEIGHT_FOG_TYPE_DEFAULT; + + @ConfigAnnotations.FileComment + public static String _heightFogDensity = IHeightFog.HEIGHT_FOG_DENSITY_DESC; + @ConfigAnnotations.Entry(minValue = 0.01, maxValue = 50.0) + public static double heightFogDensity = IHeightFog.HEIGHT_FOG_DENSITY_MIN_DEFAULT_MAX.defaultValue; + } + } } - - public static class AdvancedGraphics - { + + public static class AdvancedGraphics { @ConfigAnnotations.FileComment public static String _disableDirectionalCulling = IAdvancedGraphics.DISABLE_DIRECTIONAL_CULLING_DESC; @ConfigAnnotations.Entry @@ -162,6 +253,11 @@ public class Config extends ConfigGui @ConfigAnnotations.Entry public static VanillaOverdraw vanillaOverdraw = IAdvancedGraphics.VANILLA_OVERDRAW_DEFAULT; + @ConfigAnnotations.FileComment + public static String _overdrawOffset = IAdvancedGraphics.OVERDRAW_OFFSET_DESC; + @ConfigAnnotations.Entry(minValue = -16, maxValue = 16) + public static int overdrawOffset = IAdvancedGraphics.OVERDRAW_OFFSET_MIN_DEFAULT_MAX.defaultValue; + @ConfigAnnotations.FileComment public static String _useExtendedNearClipPlane = IAdvancedGraphics.USE_EXTENDED_NEAR_CLIP_PLANE_DESC; @ConfigAnnotations.Entry @@ -177,6 +273,16 @@ public class Config extends ConfigGui @ConfigAnnotations.Entry public static double saturationMultiplier = IAdvancedGraphics.SATURATION_MULTIPLIER_DEFAULT; + @ConfigAnnotations.FileComment + public static String _enableCaveCulling = IAdvancedGraphics.ENABLE_CAVE_CULLING_DESC; + @ConfigAnnotations.Entry + public static boolean enableCaveCulling = IAdvancedGraphics.ENABLE_CAVE_CULLING_DEFAULT; + + @ConfigAnnotations.FileComment + public static String _caveCullingHeight = IAdvancedGraphics.CAVE_CULLING_HEIGHT_DESC; + @ConfigAnnotations.Entry(minValue = -4096, maxValue = 4096) + public static int caveCullingHeight = IAdvancedGraphics.CAVE_CULLING_HEIGHT_MIN_DEFAULT_MAX.defaultValue; + /* @ConfigAnnotations.FileComment public static String _backsideCullingRange = IAdvancedGraphics.VANILLA_CULLING_RANGE_DESC; @@ -187,23 +293,22 @@ public class Config extends ConfigGui } - public static class WorldGenerator - { + public static class WorldGenerator { @ConfigAnnotations.FileComment public static String _enableDistantGeneration = IWorldGenerator.ENABLE_DISTANT_GENERATION_DESC; @ConfigAnnotations.Entry public static boolean enableDistantGeneration = IWorldGenerator.ENABLE_DISTANT_GENERATION_DEFAULT; -// @ConfigAnnotations.FileComment + // @ConfigAnnotations.FileComment // public static String _distanceGenerationMode = IWorldGenerator.getDistanceGenerationModeDesc(); @ConfigAnnotations.Entry public static DistanceGenerationMode distanceGenerationMode = IWorldGenerator.DISTANCE_GENERATION_MODE_DEFAULT; - + @ConfigAnnotations.FileComment public static String _lightGenerationMode = IWorldGenerator.LIGHT_GENERATION_MODE_DESC; @ConfigAnnotations.Entry public static LightGenerationMode lightGenerationMode = IWorldGenerator.LIGHT_GENERATION_MODE_DEFAULT; - + @ConfigAnnotations.FileComment public static String _generationPriority = IWorldGenerator.GENERATION_PRIORITY_DESC; @ConfigAnnotations.Entry @@ -216,7 +321,7 @@ public class Config extends ConfigGui @ConfigAnnotations.Entry public static boolean allowUnstableFeatureGeneration = true;//IWorldGenerator.ALLOW_UNSTABLE_FEATURE_GENERATION_DEFAULT; */ - + @ConfigAnnotations.FileComment public static String _blocksToAvoid = IWorldGenerator.BLOCKS_TO_AVOID_DESC; @ConfigAnnotations.Entry @@ -229,11 +334,15 @@ public class Config extends ConfigGui public static String _serverFolderNameMode = IMultiplayer.SERVER_FOLDER_NAME_MODE_DESC; @ConfigAnnotations.Entry public static ServerFolderNameMode serverFolderNameMode = IMultiplayer.SERVER_FOLDER_NAME_MODE_DEFAULT; + + @ConfigAnnotations.FileComment + public static String _multiDimensionRequiredSimilarity = IMultiplayer.MULTI_DIMENSION_REQUIRED_SIMILARITY_DESC; + @ConfigAnnotations.Entry(minValue = 0.0, maxValue = 1.0) + public static double multiDimensionRequiredSimilarity = IMultiplayer.MULTI_DIMENSION_REQUIRED_SIMILARITY_MIN_DEFAULT_MAX.defaultValue; } - public static class Advanced - { + public static class Advanced { @ConfigAnnotations.ScreenEntry public static Threading threading; @@ -243,9 +352,13 @@ public class Config extends ConfigGui @ConfigAnnotations.ScreenEntry public static Buffers buffers; + @ConfigAnnotations.FileComment + public static String _lodOnlyMode = IAdvanced.LOD_ONLY_MODE_DESC; + @ConfigAnnotations.Entry + public static boolean lodOnlyMode = IAdvanced.LOD_ONLY_MODE_DEFAULT; - public static class Threading - { + + public static class Threading { @ConfigAnnotations.FileComment public static String _numberOfWorldGenerationThreads = IThreading.NUMBER_OF_WORLD_GENERATION_THREADS_DESC; @ConfigAnnotations.Entry(minValue = 1, maxValue = 50) @@ -258,12 +371,11 @@ public class Config extends ConfigGui } - public static class Debugging - { + public static class Debugging { @ConfigAnnotations.FileComment - public static String _drawLods = IDebugging.DRAW_LODS_DESC; + public static String _rendererType = IDebugging.RENDERER_TYPE_DESC; @ConfigAnnotations.Entry - public static boolean drawLods = IDebugging.DRAW_LODS_DEFAULT; + public static RendererType rendererType = IDebugging.RENDERER_TYPE_DEFAULT; @ConfigAnnotations.FileComment public static String _debugMode = IDebugging.DEBUG_MODE_DESC; @@ -277,8 +389,69 @@ public class Config extends ConfigGui } - public static class Buffers - { + @ConfigAnnotations.ScreenEntry + public static DebugSwitch debugSwitch; + + public static class DebugSwitch { + /* The logging switches available: + * WorldGenEvent + * WorldGenPerformance + * WorldGenLoadEvent + * LodBuilderEvent + * RendererBufferEvent + * RendererGLEvent + * FileReadWriteEvent + * FileSubDimEvent + * NetworkEvent //NOT IMPL YET + */ + @ConfigAnnotations.FileComment + public static String _logWorldGenEvent = IDebugSwitch.LOG_WORLDGEN_EVENT_DESC; + @ConfigAnnotations.Entry + public static LoggerMode logWorldGenEvent = IDebugSwitch.LOG_WORLDGEN_EVENT_DEFAULT; + + @ConfigAnnotations.FileComment + public static String _logWorldGenPerformance = IDebugSwitch.LOG_WORLDGEN_PERFORMANCE_DESC; + @ConfigAnnotations.Entry + public static LoggerMode logWorldGenPerformance = IDebugSwitch.LOG_WORLDGEN_PERFORMANCE_DEFAULT; + + @ConfigAnnotations.FileComment + public static String _logWorldGenLoadEvent = IDebugSwitch.LOG_WORLDGEN_LOAD_EVENT_DESC; + @ConfigAnnotations.Entry + public static LoggerMode logWorldGenLoadEvent = IDebugSwitch.LOG_WORLDGEN_LOAD_EVENT_DEFAULT; + + @ConfigAnnotations.FileComment + public static String _logLodBuilderEvent = IDebugSwitch.LOG_LODBUILDER_EVENT_DESC; + @ConfigAnnotations.Entry + public static LoggerMode logLodBuilderEvent = IDebugSwitch.LOG_LODBUILDER_EVENT_DEFAULT; + + @ConfigAnnotations.FileComment + public static String _logRendererBufferEvent = IDebugSwitch.LOG_RENDERER_BUFFER_EVENT_DESC; + @ConfigAnnotations.Entry + public static LoggerMode logRendererBufferEvent = IDebugSwitch.LOG_RENDERER_BUFFER_EVENT_DEFAULT; + + @ConfigAnnotations.FileComment + public static String _logRendererGLEvent = IDebugSwitch.LOG_RENDERER_GL_EVENT_DESC; + @ConfigAnnotations.Entry + public static LoggerMode logRendererGLEvent = IDebugSwitch.LOG_RENDERER_GL_EVENT_DEFAULT; + + @ConfigAnnotations.FileComment + public static String _logFileReadWriteEvent = IDebugSwitch.LOG_FILE_READWRITE_EVENT_DESC; + @ConfigAnnotations.Entry + public static LoggerMode logFileReadWriteEvent = IDebugSwitch.LOG_FILE_READWRITE_EVENT_DEFAULT; + + @ConfigAnnotations.FileComment + public static String _logFileSubDimEvent = IDebugSwitch.LOG_FILE_SUB_DIM_EVENT_DESC; + @ConfigAnnotations.Entry + public static LoggerMode logFileSubDimEvent = IDebugSwitch.LOG_FILE_SUB_DIM_EVENT_DEFAULT; + + @ConfigAnnotations.FileComment + public static String _logNetworkEvent = IDebugSwitch.LOG_NETWORK_EVENT_DESC; + @ConfigAnnotations.Entry + public static LoggerMode logNetworkEvent = IDebugSwitch.LOG_NETWORK_EVENT_DEFAULT; + } + + + public static class Buffers { @ConfigAnnotations.FileComment public static String _gpuUploadMethod = IBuffers.GPU_UPLOAD_METHOD_DESC; @ConfigAnnotations.Entry diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/McObjectConverter.java b/common/src/main/java/com/seibel/lod/common/wrappers/McObjectConverter.java index 9cc6645e4..5bf0a0f69 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/McObjectConverter.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/McObjectConverter.java @@ -70,7 +70,8 @@ public class McObjectConverter { return directions[lodDirection.ordinal()]; } - public static LodDirection Convert(Direction direction) { + public static LodDirection Convert(Direction direction) + { return lodDirections[direction.ordinal()]; } } diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/VersionConstants.java b/common/src/main/java/com/seibel/lod/common/wrappers/VersionConstants.java index 0603a4f40..5876398a4 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/VersionConstants.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/VersionConstants.java @@ -21,39 +21,11 @@ public class VersionConstants implements IVersionConstants { return 0; } - @Override - public boolean isWorldGeneratorSingleThreaded(DistanceGenerationMode distanceGenerationMode) { - // We are always asking the server to generate the chunk, - // so no use running this stuff multithreaded. - return true; - /* - switch (distanceGenerationMode) { - default: - case NONE: - case BIOME_ONLY: - case BIOME_ONLY_SIMULATE_HEIGHT: - case SURFACE: - case FEATURES: - return false; - - case FULL: - return true; - } - */ - } - @Override public int getWorldGenerationCountPerThread() { return 1; } - - @Override - public boolean hasBatchGenerationImplementation() { - return true; - } - - @Override public boolean isVanillaRenderedChunkSquare() { diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/WrapperFactory.java b/common/src/main/java/com/seibel/lod/common/wrappers/WrapperFactory.java index ba8050414..5dc8a5b5e 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/WrapperFactory.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/WrapperFactory.java @@ -26,11 +26,9 @@ import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper; import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper; -import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractWorldGeneratorWrapper; import com.seibel.lod.common.wrappers.block.BlockPosWrapper; import com.seibel.lod.common.wrappers.chunk.ChunkPosWrapper; import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment; -import com.seibel.lod.common.wrappers.worldGeneration.WorldGeneratorWrapper; /** * This handles creating abstract wrapper objects. @@ -76,11 +74,6 @@ public class WrapperFactory implements IWrapperFactory { public AbstractChunkPosWrapper createChunkPos(AbstractBlockPosWrapper blockPos) { return new ChunkPosWrapper(blockPos); } - - @Override - public AbstractWorldGeneratorWrapper createWorldGenerator(LodBuilder newLodBuilder, LodDimension newLodDimension, IWorldWrapper worldWrapper) { - return new WorldGeneratorWrapper(newLodBuilder, newLodDimension, worldWrapper); - } @Override public AbstractBatchGenerationEnvionmentWrapper createBatchGenerator(LodBuilder newLodBuilder, diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/block/BlockDetailWrapper.java b/common/src/main/java/com/seibel/lod/common/wrappers/block/BlockDetailWrapper.java index b05eb92d5..dbaff1628 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/block/BlockDetailWrapper.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/block/BlockDetailWrapper.java @@ -2,34 +2,58 @@ package com.seibel.lod.common.wrappers.block; import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.Random; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Stream; +import com.seibel.lod.common.Config; import com.seibel.lod.common.wrappers.McObjectConverter; import com.seibel.lod.common.wrappers.chunk.ChunkWrapper; +import com.seibel.lod.core.api.ApiShared; import com.seibel.lod.core.enums.LodDirection; +import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; import com.seibel.lod.core.util.ColorUtil; import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper; import com.seibel.lod.core.wrapperInterfaces.block.IBlockDetailWrapper; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; +import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; +import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; +import net.minecraft.Util; import net.minecraft.client.Minecraft; +import net.minecraft.client.color.block.BlockTintCache; +import net.minecraft.client.renderer.BiomeColors; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.core.BlockPos; +import net.minecraft.core.Cursor3D; import net.minecraft.core.Direction; -import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.*; +import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.FlowerBlock; import net.minecraft.world.level.block.LeavesBlock; import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.RotatedPillarBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.lighting.LevelLightEngine; +import net.minecraft.world.level.material.FluidState; import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.Nullable; public class BlockDetailWrapper extends IBlockDetailWrapper { + private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); + public static final int FLOWER_COLOR_SCALE = 5; public static final Random random = new Random(0); @@ -195,7 +219,7 @@ public class BlockDetailWrapper extends IBlockDetailWrapper double zWidth = (bbox.maxZ - bbox.minZ); noFullFace = xWidth < 1 && zWidth < 1 && yWidth < 1; } - } else { // Liquad Block + } else { // Liquid Block dontOccludeFaces = new boolean[6]; } isShapeResolved = true; @@ -213,12 +237,23 @@ public class BlockDetailWrapper extends IBlockDetailWrapper !(state.getBlock() instanceof RotatedPillarBlock && direction == Direction.UP)) break; }; + if (quads == null || quads.isEmpty()) { + quads = Minecraft.getInstance().getModelManager().getBlockModelShaper(). + getBlockModel(state).getQuads(state, null, random); + } + if (quads != null && !quads.isEmpty()) { needPostTinting = quads.get(0).isTinted(); needShade = quads.get(0).isShade(); tintIndex = quads.get(0).getTintIndex(); baseColor = calculateColorFromTexture(quads.get(0).getSprite(), ColorMode.getColorMode(state.getBlock())); + } else { // Backup method. + needPostTinting = false; + needShade = false; + tintIndex = 0; + baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(state), + ColorMode.getColorMode(state.getBlock())); } } else { // Liquid Block @@ -232,7 +267,14 @@ public class BlockDetailWrapper extends IBlockDetailWrapper isColorResolved = true; } - + private BlockAndTintGetter wrapColorResolver(LevelReader level) { + int blendDistance = CONFIG.client().graphics().quality().getLodBiomeBlending(); + if (blendDistance == 0) { + return new TintGetterOverrideFast(level); + } else { + return new TintGetterOverrideSmooth(level, blendDistance); + } + } @Override public int getAndResolveFaceColor(LodDirection dir, IChunkWrapper chunk, AbstractBlockPosWrapper blockPos) @@ -241,7 +283,7 @@ public class BlockDetailWrapper extends IBlockDetailWrapper resolveColors(); if (!needPostTinting) return baseColor; int tintColor = Minecraft.getInstance().getBlockColors() - .getColor(state, ((ChunkWrapper)chunk).getColorResolver(), + .getColor(state, wrapColorResolver(((ChunkWrapper)chunk).getColorResolver()), McObjectConverter.Convert(blockPos), tintIndex); if (tintColor == -1) return baseColor; return ColorUtil.multiplyARGBwithRGB(baseColor, tintColor); diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/block/TintGetterOverrideFast.java b/common/src/main/java/com/seibel/lod/common/wrappers/block/TintGetterOverrideFast.java new file mode 100644 index 000000000..1454c2be7 --- /dev/null +++ b/common/src/main/java/com/seibel/lod/common/wrappers/block/TintGetterOverrideFast.java @@ -0,0 +1,192 @@ +package com.seibel.lod.common.wrappers.block; + +import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; +import net.minecraft.Util; +import net.minecraft.client.color.block.BlockTintCache; +import net.minecraft.client.renderer.BiomeColors; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Cursor3D; +import net.minecraft.core.Direction; +import net.minecraft.world.level.*; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.lighting.LevelLightEngine; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; +import java.util.stream.Stream; + +public class TintGetterOverrideFast implements BlockAndTintGetter { + LevelReader parent; + private final Object2ObjectArrayMap> tintCaches; + + public TintGetterOverrideFast(LevelReader parent) { + this.parent = parent; + this.tintCaches = Util.make(new Object2ObjectArrayMap(3), object2ObjectArrayMap -> { + object2ObjectArrayMap.put(BiomeColors.GRASS_COLOR_RESOLVER, new ConcurrentHashMap()); + object2ObjectArrayMap.put(BiomeColors.FOLIAGE_COLOR_RESOLVER, new ConcurrentHashMap()); + object2ObjectArrayMap.put(BiomeColors.WATER_COLOR_RESOLVER, new ConcurrentHashMap()); + }); + } + + private Biome _getBiome(BlockPos pos) { + return parent.getBiome(pos); + } + + @Override + public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) { + Biome b = _getBiome(blockPos); + return tintCaches.get(colorResolver).computeIfAbsent(b, (key) -> colorResolver.getColor(b, blockPos.getX(), blockPos.getZ())); + } + + @Override + public float getShade(Direction direction, boolean bl) { + return parent.getShade(direction, bl); + } + + @Override + public LevelLightEngine getLightEngine() { + return parent.getLightEngine(); + } + + @Override + public int getBrightness(LightLayer lightLayer, BlockPos blockPos) { + return parent.getBrightness(lightLayer, blockPos); + } + + @Override + public int getRawBrightness(BlockPos blockPos, int i) { + return parent.getRawBrightness(blockPos, i); + } + + @Override + public boolean canSeeSky(BlockPos blockPos) { + return parent.canSeeSky(blockPos); + } + + @Override + @Nullable + public BlockEntity getBlockEntity(BlockPos blockPos) { + return parent.getBlockEntity(blockPos); + } + + @Override + public Optional getBlockEntity(BlockPos blockPos, BlockEntityType blockEntityType) { + return parent.getBlockEntity(blockPos, blockEntityType); + } + + @Override + public BlockState getBlockState(BlockPos blockPos) { + return parent.getBlockState(blockPos); + } + + @Override + public FluidState getFluidState(BlockPos blockPos) { + return parent.getFluidState(blockPos); + } + + @Override + public int getLightEmission(BlockPos blockPos) { + return parent.getLightEmission(blockPos); + } + + @Override + public int getMaxLightLevel() { + return parent.getMaxLightLevel(); + } + + @Override + public Stream getBlockStates(AABB aABB) { + return parent.getBlockStates(aABB); + } + + @Override + public BlockHitResult isBlockInLine(ClipBlockStateContext clipBlockStateContext) { + return parent.isBlockInLine(clipBlockStateContext); + } + + @Override + public BlockHitResult clip(ClipContext clipContext) { + return parent.clip(clipContext); + } + + @Override + @Nullable + public BlockHitResult clipWithInteractionOverride(Vec3 vec3, Vec3 vec32, BlockPos blockPos, VoxelShape voxelShape, BlockState blockState) { + return parent.clipWithInteractionOverride(vec3, vec32, blockPos, voxelShape, blockState); + } + + @Override + public double getBlockFloorHeight(VoxelShape voxelShape, Supplier supplier) { + return parent.getBlockFloorHeight(voxelShape, supplier); + } + + @Override + public double getBlockFloorHeight(BlockPos blockPos) { + return parent.getBlockFloorHeight(blockPos); + } + + @Override + public int getHeight() { + return parent.getHeight(); + } + + @Override + public int getMinBuildHeight() { + return parent.getMinBuildHeight(); + } + + @Override + public int getMaxBuildHeight() { + return parent.getMaxBuildHeight(); + } + + @Override + public int getSectionsCount() { + return parent.getSectionsCount(); + } + + @Override + public int getMinSection() { + return parent.getMinSection(); + } + + @Override + public int getMaxSection() { + return parent.getMaxSection(); + } + + @Override + public boolean isOutsideBuildHeight(BlockPos blockPos) { + return parent.isOutsideBuildHeight(blockPos); + } + + @Override + public boolean isOutsideBuildHeight(int i) { + return parent.isOutsideBuildHeight(i); + } + + @Override + public int getSectionIndex(int i) { + return parent.getSectionIndex(i); + } + + @Override + public int getSectionIndexFromSectionY(int i) { + return parent.getSectionIndexFromSectionY(i); + } + + @Override + public int getSectionYFromSectionIndex(int i) { + return parent.getSectionYFromSectionIndex(i); + } +} diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/block/TintGetterOverrideSmooth.java b/common/src/main/java/com/seibel/lod/common/wrappers/block/TintGetterOverrideSmooth.java new file mode 100644 index 000000000..ec1b3f944 --- /dev/null +++ b/common/src/main/java/com/seibel/lod/common/wrappers/block/TintGetterOverrideSmooth.java @@ -0,0 +1,215 @@ +package com.seibel.lod.common.wrappers.block; + +import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; +import net.minecraft.Util; +import net.minecraft.client.color.block.BlockTintCache; +import net.minecraft.client.renderer.BiomeColors; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Cursor3D; +import net.minecraft.core.Direction; +import net.minecraft.world.level.*; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.lighting.LevelLightEngine; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; +import java.util.function.Supplier; +import java.util.stream.Stream; + +public class TintGetterOverrideSmooth implements BlockAndTintGetter { + LevelReader parent; + private final Object2ObjectArrayMap tintCaches; + public int smoothingRange; + + public TintGetterOverrideSmooth(LevelReader parent, int smoothingRange) { + this.parent = parent; + this.smoothingRange = smoothingRange; + this.tintCaches = Util.make(new Object2ObjectArrayMap(3), object2ObjectArrayMap -> { + object2ObjectArrayMap.put(BiomeColors.GRASS_COLOR_RESOLVER, new BlockTintCache((pos) -> calculateBlockTint(pos, BiomeColors.GRASS_COLOR_RESOLVER))); + object2ObjectArrayMap.put(BiomeColors.FOLIAGE_COLOR_RESOLVER, new BlockTintCache((pos) -> calculateBlockTint(pos, BiomeColors.FOLIAGE_COLOR_RESOLVER))); + object2ObjectArrayMap.put(BiomeColors.WATER_COLOR_RESOLVER, new BlockTintCache((pos) -> calculateBlockTint(pos, BiomeColors.WATER_COLOR_RESOLVER))); + }); + } + + private Biome _getBiome(BlockPos pos) { + return parent.getBiome(pos); + } + + public int calculateBlockTint(BlockPos blockPos, ColorResolver colorResolver) + { + int i = smoothingRange; + if (i == 0) + return colorResolver.getColor(_getBiome(blockPos), blockPos.getX(), blockPos.getZ()); + int j = (i * 2 + 1) * (i * 2 + 1); + int k = 0; + int l = 0; + int m = 0; + Cursor3D cursor3D = new Cursor3D(blockPos.getX() - i, blockPos.getY(), blockPos.getZ() - i, blockPos.getX() + i, blockPos.getY(), blockPos.getZ() + i); + BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); + while (cursor3D.advance()) + { + mutableBlockPos.set(cursor3D.nextX(), cursor3D.nextY(), cursor3D.nextZ()); + int n = colorResolver.getColor(_getBiome(mutableBlockPos), mutableBlockPos.getX(), mutableBlockPos.getZ()); + k += (n & 0xFF0000) >> 16; + l += (n & 0xFF00) >> 8; + m += n & 0xFF; + } + return (k / j & 0xFF) << 16 | (l / j & 0xFF) << 8 | m / j & 0xFF; + } + + @Override + public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) { + BlockTintCache blockTintCache = this.tintCaches.get(colorResolver); + return blockTintCache.getColor(blockPos, null); //FIXME + } + + @Override + public float getShade(Direction direction, boolean bl) { + return parent.getShade(direction, bl); + } + + @Override + public LevelLightEngine getLightEngine() { + return parent.getLightEngine(); + } + + @Override + public int getBrightness(LightLayer lightLayer, BlockPos blockPos) { + return parent.getBrightness(lightLayer, blockPos); + } + + @Override + public int getRawBrightness(BlockPos blockPos, int i) { + return parent.getRawBrightness(blockPos, i); + } + + @Override + public boolean canSeeSky(BlockPos blockPos) { + return parent.canSeeSky(blockPos); + } + + @Override + @Nullable + public BlockEntity getBlockEntity(BlockPos blockPos) { + return parent.getBlockEntity(blockPos); + } + + @Override + public Optional getBlockEntity(BlockPos blockPos, BlockEntityType blockEntityType) { + return parent.getBlockEntity(blockPos, blockEntityType); + } + + @Override + public BlockState getBlockState(BlockPos blockPos) { + return parent.getBlockState(blockPos); + } + + @Override + public FluidState getFluidState(BlockPos blockPos) { + return parent.getFluidState(blockPos); + } + + @Override + public int getLightEmission(BlockPos blockPos) { + return parent.getLightEmission(blockPos); + } + + @Override + public int getMaxLightLevel() { + return parent.getMaxLightLevel(); + } + + @Override + public Stream getBlockStates(AABB aABB) { + return parent.getBlockStates(aABB); + } + + @Override + public BlockHitResult isBlockInLine(ClipBlockStateContext clipBlockStateContext) { + return parent.isBlockInLine(clipBlockStateContext); + } + + @Override + public BlockHitResult clip(ClipContext clipContext) { + return parent.clip(clipContext); + } + + @Override + @Nullable + public BlockHitResult clipWithInteractionOverride(Vec3 vec3, Vec3 vec32, BlockPos blockPos, VoxelShape voxelShape, BlockState blockState) { + return parent.clipWithInteractionOverride(vec3, vec32, blockPos, voxelShape, blockState); + } + + @Override + public double getBlockFloorHeight(VoxelShape voxelShape, Supplier supplier) { + return parent.getBlockFloorHeight(voxelShape, supplier); + } + + @Override + public double getBlockFloorHeight(BlockPos blockPos) { + return parent.getBlockFloorHeight(blockPos); + } + + @Override + public int getHeight() { + return parent.getHeight(); + } + + @Override + public int getMinBuildHeight() { + return parent.getMinBuildHeight(); + } + + @Override + public int getMaxBuildHeight() { + return parent.getMaxBuildHeight(); + } + + @Override + public int getSectionsCount() { + return parent.getSectionsCount(); + } + + @Override + public int getMinSection() { + return parent.getMinSection(); + } + + @Override + public int getMaxSection() { + return parent.getMaxSection(); + } + + @Override + public boolean isOutsideBuildHeight(BlockPos blockPos) { + return parent.isOutsideBuildHeight(blockPos); + } + + @Override + public boolean isOutsideBuildHeight(int i) { + return parent.isOutsideBuildHeight(i); + } + + @Override + public int getSectionIndex(int i) { + return parent.getSectionIndex(i); + } + + @Override + public int getSectionIndexFromSectionY(int i) { + return parent.getSectionIndexFromSectionY(i); + } + + @Override + public int getSectionYFromSectionIndex(int i) { + return parent.getSectionYFromSectionIndex(i); + } +} diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/chunk/ChunkWrapper.java b/common/src/main/java/com/seibel/lod/common/wrappers/chunk/ChunkWrapper.java index f499d7a05..312f6636d 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/chunk/ChunkWrapper.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/chunk/ChunkWrapper.java @@ -1,40 +1,47 @@ package com.seibel.lod.common.wrappers.chunk; import com.seibel.lod.common.wrappers.block.BlockDetailWrapper; -import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightedWorldGenRegion; +import com.seibel.lod.core.enums.LodDirection; import com.seibel.lod.core.util.LevelPosUtil; import com.seibel.lod.core.util.LodUtil; +import com.seibel.lod.core.wrapperInterfaces.block.IBlockDetailWrapper; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper; + import com.seibel.lod.common.wrappers.WrapperUtil; import com.seibel.lod.common.wrappers.block.BlockDetailMap; import com.seibel.lod.common.wrappers.world.BiomeWrapper; +import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightedWorldGenRegion; import net.minecraft.core.BlockPos; import net.minecraft.core.QuartPos; -import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.LightLayer; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.LiquidBlock; import net.minecraft.world.level.block.LiquidBlockContainer; import net.minecraft.world.level.block.SimpleWaterloggedBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.levelgen.Heightmap; /** * * @author James Seibel - * @version 11-21-2021 + * @version 3-5-2022 */ public class ChunkWrapper implements IChunkWrapper { - private ChunkAccess chunk; - private LevelReader lightSource; + private final ChunkAccess chunk; + private final LevelReader lightSource; + + + public ChunkWrapper(ChunkAccess chunk, LevelReader lightSource) + { + this.chunk = chunk; + this.lightSource = lightSource; + } @Override public int getHeight(){ @@ -66,23 +73,27 @@ public class ChunkWrapper implements IChunkWrapper } @Override - public BlockDetailWrapper getBlockDetail(int x, int y, int z) { + public IBlockDetailWrapper getBlockDetail(int x, int y, int z) { BlockPos pos = new BlockPos(x,y,z); BlockState blockState = chunk.getBlockState(pos); - BlockDetailWrapper blockDetail = BlockDetailMap.getOrMakeBlockDetailCache(blockState, pos, lightSource); + IBlockDetailWrapper blockDetail = BlockDetailMap.getOrMakeBlockDetailCache(blockState, pos, lightSource); return blockDetail == BlockDetailWrapper.NULL_BLOCK_DETAIL ? null : blockDetail; } - @Deprecated - public ChunkWrapper(ChunkAccess chunk) - { - this.chunk = chunk; - this.lightSource = null; - } - public ChunkWrapper(ChunkAccess chunk, LevelReader lightSource) - { - this.chunk = chunk; - this.lightSource = lightSource; + @Override + public IBlockDetailWrapper getBlockDetailAtFace(int x, int y, int z, LodDirection dir) { + int fy = y+dir.getNormal().y; + if (fy < getMinBuildHeight() || fy > getMaxBuildHeight()) return null; + BlockPos pos = new BlockPos(x+dir.getNormal().x,fy,z+dir.getNormal().z); + BlockState blockState; + if (blockPosInsideChunk(x,y,z)) + blockState = chunk.getBlockState(pos); + else { + blockState = lightSource.getBlockState(pos); + } + if (blockState == null || blockState.isAir()) return null; + IBlockDetailWrapper blockDetail = BlockDetailMap.getOrMakeBlockDetailCache(blockState, pos, lightSource); + return blockDetail == BlockDetailWrapper.NULL_BLOCK_DETAIL ? null : blockDetail; } public ChunkAccess getChunk() { @@ -101,12 +112,12 @@ public class ChunkWrapper implements IChunkWrapper @Override public int getRegionPosX(){ - return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, getChunkPosX(), LodUtil.REGION_DETAIL_LEVEL); + return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, LodUtil.REGION_DETAIL_LEVEL); } @Override public int getRegionPosZ(){ - return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, getChunkPosZ(), LodUtil.REGION_DETAIL_LEVEL); + return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().z, LodUtil.REGION_DETAIL_LEVEL); } @Override @@ -131,15 +142,19 @@ public class ChunkWrapper implements IChunkWrapper return chunk.getPos().getMinBlockZ(); } - @Override - public long getLongChunkPos() { - return chunk.getPos().toLong(); - } + @Override + public long getLongChunkPos() { + return chunk.getPos().toLong(); + } @Override public boolean isLightCorrect(){ - return true; - //return chunk.isLightCorrect(); + return true; + // TODO +// if (chunk instanceof LevelChunk) { +// return ((LevelChunk) chunk).isClientLightReady(); +// } +// return chunk.isLightCorrect(); } public boolean isWaterLogged(int x, int y, int z) @@ -166,7 +181,7 @@ public class ChunkWrapper implements IChunkWrapper @Override public int getSkyLight(int x, int y, int z) { if (lightSource == null) return -1; - return lightSource.getBrightness(LightLayer.SKY, new BlockPos(x, y, z)); + return lightSource.getBrightness(LightLayer.SKY, new BlockPos(x,y,z)); } @Override @@ -185,4 +200,5 @@ public class ChunkWrapper implements IChunkWrapper { return lightSource; } + } diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/config/ConfigGui.java b/common/src/main/java/com/seibel/lod/common/wrappers/config/ConfigGui.java index 37745722b..07442ac97 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/config/ConfigGui.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/config/ConfigGui.java @@ -607,6 +607,7 @@ public abstract class ConfigGui else if (info.screenButton) { Button widget = new Button(this.width / 2 - info.width, this.height - 28, info.width * 2, 20, name, (button -> { + saveToFile(); Objects.requireNonNull(minecraft).setScreen(ConfigGui.getScreen(this, info.gotoScreen)); })); this.list.addButton(widget, null, null, null); diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/config/LodConfigWrapperSingleton.java b/common/src/main/java/com/seibel/lod/common/wrappers/config/LodConfigWrapperSingleton.java index 9c16205a4..7ab313a84 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/config/LodConfigWrapperSingleton.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/config/LodConfigWrapperSingleton.java @@ -3,7 +3,6 @@ package com.seibel.lod.common.wrappers.config; import com.seibel.lod.core.enums.config.*; import com.seibel.lod.core.enums.rendering.*; import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; -import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IMultiplayer; import com.seibel.lod.common.Config; /** @@ -185,7 +184,7 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton ConfigGui.editSingleOption.getEntry("client.graphics.quality.horizontalQuality").value = newHorizontalQuality; ConfigGui.editSingleOption.saveOption("client.graphics.quality.horizontalQuality"); } - + @Override public DropoffQuality getDropoffQuality() { return Config.Client.Graphics.Quality.dropoffQuality; @@ -195,11 +194,29 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton ConfigGui.editSingleOption.getEntry("client.graphics.quality.dropoffQuality").value = newDropoffQuality; ConfigGui.editSingleOption.saveOption("client.graphics.quality.dropoffQuality"); } + + @Override + public int getLodBiomeBlending() { + return Config.Client.Graphics.Quality.lodBiomeBlending; + } + + @Override + public void setLodBiomeBlending(int newLodBiomeBlending) { + ConfigGui.editSingleOption.getEntry("client.graphics.quality.lodBiomeBlending").value = newLodBiomeBlending; + ConfigGui.editSingleOption.saveOption("client.graphics.quality.lodBiomeBlending"); + } } public static class FogQuality implements IFogQuality { + public final IAdvancedFog advancedFog; + + FogQuality() + { + advancedFog = new AdvancedFog(); + } + @Override public FogDistance getFogDistance() { @@ -252,6 +269,167 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.disableVanillaFog").value = newDisableVanillaFog; ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.disableVanillaFog"); } + + @Override + public IAdvancedFog advancedFog() { + return advancedFog; + } + + public static class AdvancedFog implements IAdvancedFog { + public final IHeightFog heightFog; + + public AdvancedFog() { + heightFog = new HeightFog(); + } + + @Override + public double getFarFogStart() { + return Config.Client.Graphics.FogQuality.AdvancedFog.farFogStart; + } + @Override + public double getFarFogEnd() { + return Config.Client.Graphics.FogQuality.AdvancedFog.farFogEnd; + } + @Override + public double getFarFogMin() { + return Config.Client.Graphics.FogQuality.AdvancedFog.farFogMin; + } + @Override + public double getFarFogMax() { + return Config.Client.Graphics.FogQuality.AdvancedFog.farFogMax; + } + @Override + public FogSetting.FogType getFarFogType() { + return Config.Client.Graphics.FogQuality.AdvancedFog.farFogType; + } + @Override + public double getFarFogDensity() { + return Config.Client.Graphics.FogQuality.AdvancedFog.farFogDensity; + } + + @Override + public void setFarFogStart(double newFarFogStart) { + ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogStart").value = newFarFogStart; + ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogStart"); + } + @Override + public void setFarFogEnd(double newFarFogEnd) { + ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogEnd").value = newFarFogEnd; + ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogEnd"); + } + @Override + public void setFarFogMin(double newFarFogMin) { + ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogMin").value = newFarFogMin; + ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogMin"); + } + @Override + public void setFarFogMax(double newFarFogMax) { + ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogMax").value = newFarFogMax; + ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogMax"); + } + @Override + public void setFarFogType(FogSetting.FogType newFarFogType) { + ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogType").value = newFarFogType; + ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogType"); + } + @Override + public void setFarFogDensity(double newFarFogDensity) { + ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogDensity").value = newFarFogDensity; + ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogDensity"); + } + + @Override + public IHeightFog heightFog() { + return heightFog; + } + + public static class HeightFog implements IHeightFog { + + @Override + public HeightFogMixMode getHeightFogMixMode() { + return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogMixMode; + } + @Override + public HeightFogMode getHeightFogMode() { + return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogMode; + } + @Override + public double getHeightFogHeight() { + return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogHeight; + } + @Override + public double getHeightFogStart() { + return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogStart; + } + @Override + public double getHeightFogEnd() { + return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogEnd; + } + @Override + public double getHeightFogMin() { + return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogMin; + } + @Override + public double getHeightFogMax() { + return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogMax; + } + @Override + public FogSetting.FogType getHeightFogType() { + return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogType; + } + @Override + public double getHeightFogDensity() { + return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogDensity; + } + + @Override + public void setHeightFogMixMode(HeightFogMixMode newHeightFogMixMode) { + ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogMixMode").value = newHeightFogMixMode; + ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogMixMode"); + } + @Override + public void setHeightFogMode(HeightFogMode newHeightFogMode) { + ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogMode").value = newHeightFogMode; + ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogMode"); + } + @Override + public void setHeightFogHeight(double newHeightFogHeight) { + ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogHeight").value = newHeightFogHeight; + ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogHeight"); + } + @Override + public void setHeightFogStart(double newHeightFogStart) { + ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogStart").value = newHeightFogStart; + ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogStart"); + } + @Override + public void setHeightFogEnd(double newHeightFogEnd) { + ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogEnd").value = newHeightFogEnd; + ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogEnd"); + } + @Override + public void setHeightFogMin(double newHeightFogMin) { + ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogMin").value = newHeightFogMin; + ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogMin"); + } + @Override + public void setHeightFogMax(double newHeightFogMax) { + ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogMax").value = newHeightFogMax; + ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogMax"); + } + @Override + public void setHeightFogType(FogSetting.FogType newHeightFogType) { + ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogType").value = newHeightFogType; + ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogType"); + } + @Override + public void setHeightFogDensity(double newHeightFogDensity) { + ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogDensity").value = newHeightFogDensity; + ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogDensity"); + } + } + } + } @@ -269,6 +447,7 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.disableDirectionalCulling"); } + @Override public VanillaOverdraw getVanillaOverdraw() { @@ -280,6 +459,17 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.vanillaOverdraw").value = newVanillaOverdraw; ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.vanillaOverdraw"); } + + @Override + public int getOverdrawOffset() { + return Config.Client.Graphics.AdvancedGraphics.overdrawOffset; + } + + @Override + public void setOverdrawOffset(int newOverdrawOffset) { + ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.overdrawOffset").value = newOverdrawOffset; + ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.overdrawOffset"); + } /* @Override public int getBacksideCullingRange() @@ -292,7 +482,7 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.backsideCullingRange").value = newBacksideCullingRange; ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.backsideCullingRange"); }*/ - + @Override public boolean getUseExtendedNearClipPlane() { @@ -328,6 +518,30 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.saturationMultiplier").value = newSaturationMultiplier; ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.saturationMultiplier"); } + + @Override + public boolean getEnableCaveCulling() { + return Config.Client.Graphics.AdvancedGraphics.enableCaveCulling; + } + + @Override + public void setEnableCaveCulling(boolean newEnableCaveCulling) { + ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.enableCaveCulling").value = newEnableCaveCulling; + ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.enableCaveCulling"); + + } + + @Override + public int getCaveCullingHeight() { + return Config.Client.Graphics.AdvancedGraphics.caveCullingHeight; + } + + @Override + public void setCaveCullingHeight(int newCaveCullingHeight) { + ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.caveCullingHeight").value = newCaveCullingHeight; + ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.caveCullingHeight"); + + } } } @@ -364,6 +578,20 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton ConfigGui.editSingleOption.saveOption("client.worldGenerator.distanceGenerationMode"); } + /* + @Override + public boolean getAllowUnstableFeatureGeneration() + { + return Config.Client.WorldGenerator.allowUnstableFeatureGeneration; + } + @Override + public void setAllowUnstableFeatureGeneration(boolean newAllowUnstableFeatureGeneration) + { + ConfigGui.editSingleOption.getEntry("client.worldGenerator.allowUnstableFeatureGeneration").value = newAllowUnstableFeatureGeneration; + ConfigGui.editSingleOption.saveOption("client.worldGenerator.allowUnstableFeatureGeneration"); + }*/ + + @Override public BlocksToAvoid getBlocksToAvoid() { @@ -418,7 +646,18 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton ConfigGui.editSingleOption.saveOption("client.multiplayer.serverFolderNameMode"); } + @Override + public double getMultiDimensionRequiredSimilarity() + { + return Config.Client.Multiplayer.multiDimensionRequiredSimilarity; + } + @Override + public void setMultiDimensionRequiredSimilarity(double newMultiDimensionMinimumSimilarityPercent) + { + ConfigGui.editSingleOption.getEntry("client.multiplayer.multiDimensionMinimumSimilarityPercent").value = newMultiDimensionMinimumSimilarityPercent; + ConfigGui.editSingleOption.saveOption("client.multiplayer.multiDimensionMinimumSimilarityPercent"); + } } @@ -497,18 +736,28 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton //===============// public static class Debugging implements IDebugging { + public final IDebugSwitch debugSwitch; + @Override - public boolean getDrawLods() + public IDebugSwitch debugSwitch() { - return (boolean) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.drawLods").value; - } - @Override - public void setDrawLods(boolean newDrawLods) - { - ConfigGui.editSingleOption.getEntry("client.advanced.debugging.drawLods").value = newDrawLods; - ConfigGui.editSingleOption.saveOption("client.advanced.debugging.drawLods"); + return debugSwitch; } + /* RendererType: + * DEFAULT + * DEBUG + * DISABLED + * */ + @Override + public RendererType getRendererType() { + return (RendererType) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.rendererType").value; + } + @Override + public void setRendererType(RendererType newRenderType) { + ConfigGui.editSingleOption.getEntry("client.advanced.debugging.rendererType").value = newRenderType; + ConfigGui.editSingleOption.saveOption("client.advanced.debugging.rendererType"); + } @Override public DebugMode getDebugMode() @@ -534,6 +783,116 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton ConfigGui.editSingleOption.getEntry("client.advanced.debugging.enableDebugKeybindings").value = newEnableDebugKeybindings; ConfigGui.editSingleOption.saveOption("client.advanced.debugging.enableDebugKeybindings"); } + + public Debugging() + { + debugSwitch = new DebugSwitch(); + } + + public static class DebugSwitch implements IDebugSwitch { + + /* The logging switches available: + * WorldGenEvent + * WorldGenPerformance + * WorldGenLoadEvent + * LodBuilderEvent + * RendererBufferEvent + * RendererGLEvent + * FileReadWriteEvent + * FileSubDimEvent + * NetworkEvent //NOT IMPL YET + */ + + @Override + public LoggerMode getLogWorldGenEvent() { + return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenEvent").value; + } + @Override + public void setLogWorldGenEvent(LoggerMode newLogWorldGenEvent) { + ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenEvent").value = newLogWorldGenEvent; + ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logWorldGenEvent"); + } + + @Override + public LoggerMode getLogWorldGenPerformance() { + return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenPerformance").value; + } + @Override + public void setLogWorldGenPerformance(LoggerMode newLogWorldGenPerformance) { + ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenPerformance").value = newLogWorldGenPerformance; + ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logWorldGenPerformance"); + } + + @Override + public LoggerMode getLogWorldGenLoadEvent() { + return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenLoadEvent").value; + } + @Override + public void setLogWorldGenLoadEvent(LoggerMode newLogWorldGenLoadEvent) { + ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenLoadEvent").value = newLogWorldGenLoadEvent; + ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logWorldGenLoadEvent"); + } + + @Override + public LoggerMode getLogLodBuilderEvent() { + return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logLodBuilderEvent").value; + } + @Override + public void setLogLodBuilderEvent(LoggerMode newLogLodBuilderEvent) { + ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logLodBuilderEvent").value = newLogLodBuilderEvent; + ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logLodBuilderEvent"); + } + + @Override + public LoggerMode getLogRendererBufferEvent() { + return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logRendererBufferEvent").value; + } + @Override + public void setLogRendererBufferEvent(LoggerMode newLogRendererBufferEvent) { + ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logRendererBufferEvent").value = newLogRendererBufferEvent; + ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logRendererBufferEvent"); + } + + @Override + public LoggerMode getLogRendererGLEvent() { + return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logRendererGLEvent").value; + } + @Override + public void setLogRendererGLEvent(LoggerMode newLogRendererGLEvent) { + ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logRendererGLEvent").value = newLogRendererGLEvent; + ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logRendererGLEvent"); + } + + @Override + public LoggerMode getLogFileReadWriteEvent() { + return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logFileReadWriteEvent").value; + } + @Override + public void setLogFileReadWriteEvent(LoggerMode newLogFileReadWriteEvent) { + ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logFileReadWriteEvent").value = newLogFileReadWriteEvent; + ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logFileReadWriteEvent"); + } + + @Override + public LoggerMode getLogFileSubDimEvent() { + return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logFileSubDimEvent").value; + } + @Override + public void setLogFileSubDimEvent(LoggerMode newLogFileSubDimEvent) { + ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logFileSubDimEvent").value = newLogFileSubDimEvent; + ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logFileSubDimEvent"); + } + + @Override + public LoggerMode getLogNetworkEvent() { + return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logNetworkEvent").value; + } + @Override + public void setLogNetworkEvent(LoggerMode newLogNetworkEvent) { + ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logNetworkEvent").value = newLogNetworkEvent; + ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logNetworkEvent"); + } + } } @@ -577,6 +936,18 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton ConfigGui.editSingleOption.saveOption("client.advanced.buffers.newBufferRebuildTimes"); } } + + @Override + public boolean getLodOnlyMode() { + return Config.Client.Advanced.lodOnlyMode; + } + + @Override + public void setLodOnlyMode(boolean newLodOnlyMode) { + ConfigGui.editSingleOption.getEntry("client.advanced.buffers.lodOnlyMode").value = newLodOnlyMode; + ConfigGui.editSingleOption.saveOption("client.advanced.buffers.lodOnlyMode"); + + } } } } diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/minecraft/MinecraftClientWrapper.java b/common/src/main/java/com/seibel/lod/common/wrappers/minecraft/MinecraftClientWrapper.java index 7d56db903..7835923cb 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/minecraft/MinecraftClientWrapper.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/minecraft/MinecraftClientWrapper.java @@ -189,7 +189,7 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper { if (lightMap == null) { - sendChatMessage("new"); + //sendChatMessage("new"); // make sure the lightMap is up-to-date getCurrentLightMap(); } @@ -197,22 +197,6 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper return lightMap.getPixelRGBA(blockLight, skyLight); } - /** - * Returns the Color at the given pixel coordinates - * from the current lightmap. - * @param blockLight x location in texture space - * @param skyLight z location in texture space - */ - @Override - public Color getColorFromLightMap(int blockLight, int skyLight) { - if (lightMap == null) { - // make sure the lightMap is up-to-date - getCurrentLightMap(); - } - - return LodUtil.intToColor(lightMap.getPixelRGBA(blockLight, skyLight)); - } - diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/minecraft/MinecraftRenderWrapper.java b/common/src/main/java/com/seibel/lod/common/wrappers/minecraft/MinecraftRenderWrapper.java index 12ad0f893..b3df4daf9 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/minecraft/MinecraftRenderWrapper.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/minecraft/MinecraftRenderWrapper.java @@ -2,19 +2,19 @@ package com.seibel.lod.common.wrappers.minecraft; import java.awt.*; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.stream.Collectors; +import com.mojang.blaze3d.pipeline.RenderTarget; import com.mojang.blaze3d.platform.NativeImage; import com.mojang.blaze3d.systems.RenderSystem; import com.seibel.lod.common.wrappers.misc.LightMapWrapper; import com.seibel.lod.core.api.ApiShared; import com.seibel.lod.core.api.ClientApi; -import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.handlers.dependencyInjection.ModAccessorHandler; import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; -import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; -import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor; +import com.seibel.lod.core.util.LodUtil; + import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minecraft.client.renderer.LightTexture; @@ -22,9 +22,11 @@ import com.mojang.math.Vector3f; import com.seibel.lod.core.objects.math.Mat4f; import com.seibel.lod.core.objects.math.Vec3d; import com.seibel.lod.core.objects.math.Vec3f; +import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper; import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor; import com.seibel.lod.core.wrapperInterfaces.modAccessor.ISodiumAccessor; import com.seibel.lod.common.wrappers.McObjectConverter; import com.seibel.lod.common.wrappers.WrapperFactory; @@ -57,7 +59,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper private static final Minecraft MC = Minecraft.getInstance(); private static final GameRenderer GAME_RENDERER = MC.gameRenderer; - private static final WrapperFactory FACTORY = WrapperFactory.INSTANCE; + private static final IWrapperFactory FACTORY = WrapperFactory.INSTANCE; @Override public Vec3f getLookAtVector() @@ -143,11 +145,32 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper return MC.getWindow().getHeight(); } + private RenderTarget getRenderTarget() { + RenderTarget r = null; //MC.levelRenderer.getCloudsTarget(); + return r!=null ? r : MC.getMainRenderTarget(); + } + + @Override + public int getTargetFrameBuffer() { + return getRenderTarget().frameBufferId; + } + + @Override + public int getTargetFrameBufferViewportWidth() { + return getRenderTarget().viewWidth; + } + + @Override + public int getTargetFrameBufferViewportHeight() { + return getRenderTarget().viewHeight; + } + /** * This method returns the ChunkPos of all chunks that Minecraft * is going to render this frame.

*

*/ + public boolean usingBackupGetVanillaRenderedChunks = false; @Override public HashSet getVanillaRenderedChunks() @@ -161,36 +184,34 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper if (optifine != null) { HashSet pos = optifine.getNormalRenderedChunks(); - if (pos==null) + if (pos == null) pos = getMaximumRenderedChunks(); return pos; } - if (!usingBackupGetVanillaRenderedChunks) { - try { - LevelRenderer levelRenderer = MC.levelRenderer; - ObjectArrayList chunks = levelRenderer.renderChunks; - return (chunks.stream().map((chunk) -> { - AABB chunkBoundingBox = chunk.chunk.bb; - return FACTORY.createChunkPos(Math.floorDiv((int) chunkBoundingBox.minX, 16), - Math.floorDiv((int) chunkBoundingBox.minZ, 16)); - }).collect(Collectors.toCollection(HashSet::new))); - } catch (LinkageError e) { - try { - MinecraftClientWrapper.INSTANCE.sendChatMessage( - "\u00A7e\u00A7l\u00A7uWARNING: Distant Horizons: getVanillaRenderedChunks method failed." - + " Using Backup Method."); - MinecraftClientWrapper.INSTANCE.sendChatMessage( - "\u00A7eOverdraw prevention will be worse than normal."); - } catch (Exception e2) {} - ApiShared.LOGGER.error("getVanillaRenderedChunks Error: {}", e); - usingBackupGetVanillaRenderedChunks = true; - } - } - return getMaximumRenderedChunks(); - + if (!usingBackupGetVanillaRenderedChunks) { + try { + LevelRenderer levelRenderer = MC.levelRenderer; + ObjectArrayList chunks = levelRenderer.renderChunks; + return (chunks.stream().map((chunk) -> { + AABB chunkBoundingBox = chunk.chunk.bb; + return FACTORY.createChunkPos(Math.floorDiv((int) chunkBoundingBox.minX, 16), + Math.floorDiv((int) chunkBoundingBox.minZ, 16)); + }).collect(Collectors.toCollection(HashSet::new))); + } catch (LinkageError e) { + try { + MinecraftClientWrapper.INSTANCE.sendChatMessage( + "\u00A7e\u00A7l\u00A7uWARNING: Distant Horizons: getVanillaRenderedChunks method failed." + + " Using Backup Method."); + MinecraftClientWrapper.INSTANCE.sendChatMessage( + "\u00A7eOverdraw prevention will be worse than normal."); + } catch (Exception e2) {} + ApiShared.LOGGER.error("getVanillaRenderedChunks Error: ", e); + usingBackupGetVanillaRenderedChunks = true; + } + } + return getMaximumRenderedChunks(); } - @Override public int[] getLightmapPixels() { @@ -208,10 +229,10 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper { for (int v = 0; v < lightMapWidth; v++) { - // this could probably be kept as an int, but + // this could probably be kept as a int, but // it is easier to test and see the colors when debugging this way. // When creating a new release this should be changed to the int version. - Color c = LodUtil.intToColor(lightMap.getLightValue(u, v)); + int col = lightMap.getLightValue(u, v); // these should both create a totally white image // int col = @@ -222,11 +243,11 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper // (0b11111111 << 16) + // blue // (0b11111111 << 24); // blue - int col = - ((c.getRed() & 0xFF) << 16) | // blue - ((c.getGreen() & 0xFF) << 8) | // green - ((c.getBlue() & 0xFF)) | // red - ((c.getAlpha() & 0xFF) << 24); // alpha +// int col = +// ((c.getRed() & 0xFF) << 16) | // blue +// ((c.getGreen() & 0xFF) << 8) | // green +// ((c.getBlue() & 0xFF)) | // red +// ((c.getAlpha() & 0xFF) << 24); // alpha // 2D array stored in a 1D array. // Thank you Tim from College ;) @@ -292,13 +313,13 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper @Override public boolean isFogStateSpecial() { - Entity entity = GAME_RENDERER.getMainCamera().getEntity(); - boolean isBlind = (entity instanceof LivingEntity) && ((LivingEntity)entity).hasEffect(MobEffects.BLINDNESS); - return GAME_RENDERER.getMainCamera().getFluidInCamera() != FogType.NONE || isBlind; + Entity entity = GAME_RENDERER.getMainCamera().getEntity(); + boolean isBlind = (entity instanceof LivingEntity) && ((LivingEntity)entity).hasEffect(MobEffects.BLINDNESS); + return GAME_RENDERER.getMainCamera().getFluidInCamera() != FogType.NONE || isBlind; } - @Override - public boolean tryDisableVanillaFog() { - return true; // Handled via MixinFogRenderer in both Fabric and Forge - } + @Override + public boolean tryDisableVanillaFog() { + return true; // Handled via MixinFogRenderer in both forge and fabric + } } diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/world/BiomeWrapper.java b/common/src/main/java/com/seibel/lod/common/wrappers/world/BiomeWrapper.java index 20cb22114..173969ae5 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/world/BiomeWrapper.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/world/BiomeWrapper.java @@ -65,7 +65,7 @@ public class BiomeWrapper implements IBiomeWrapper { int colorInt; - switch (biome.getBiomeCategory()) + switch (biome.biomeCategory) { case NETHER: @@ -110,9 +110,11 @@ public class BiomeWrapper implements IBiomeWrapper case SAVANNA: case SWAMP: default: - Color tmp = LodUtil.intToColor(biome.getGrassColor(x, z)); - tmp = tmp.darker(); - colorInt = LodUtil.colorToInt(tmp); + colorInt = biome.getGrassColor(x,z); + //FIXME: Repair what James did - LeeTom +// Color tmp = LodUtil.intToColor(biome.getGrassColor(x, z)); +// tmp = tmp.darker(); +// colorInt = LodUtil.colorToInt(tmp); break; } diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/world/WorldWrapper.java b/common/src/main/java/com/seibel/lod/common/wrappers/world/WorldWrapper.java index 45a05362e..267c13d73 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/world/WorldWrapper.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/world/WorldWrapper.java @@ -36,6 +36,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LightLayer; import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkSource; import net.minecraft.world.level.chunk.ChunkStatus; import org.jetbrains.annotations.Nullable; @@ -175,5 +176,12 @@ public class WorldWrapper implements IWorldWrapper return new ChunkWrapper(chunk, world); } + @Override + public boolean hasChunkLoaded(int chunkX, int chunkZ) { + // world.hasChunk(chunkX, chunkZ); THIS DOES NOT WORK FOR CLIENT LEVEL CAUSE MOJANG ALWAYS RETURN TRUE FOR THAT! + ChunkSource source = world.getChunkSource(); + return source.hasChunk(chunkX, chunkZ); + } + } diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/BatchGenerationEnvironment.java b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/BatchGenerationEnvironment.java index be6eb2599..ab406e488 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/BatchGenerationEnvironment.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/BatchGenerationEnvironment.java @@ -25,10 +25,12 @@ import com.seibel.lod.core.builders.lodBuilding.LodBuilder; import com.seibel.lod.core.builders.lodBuilding.LodBuilderConfig; import com.seibel.lod.core.enums.config.DistanceGenerationMode; import com.seibel.lod.core.enums.config.LightGenerationMode; +import com.seibel.lod.core.logging.ConfigBasedLogger; +import com.seibel.lod.core.logging.ConfigBasedSpamLogger; import com.seibel.lod.core.objects.lod.LodDimension; -import com.seibel.lod.core.util.GridList; import com.seibel.lod.core.util.LodThreadFactory; import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; +import com.seibel.lod.core.util.gridList.ArrayGridList; import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; @@ -71,6 +73,7 @@ import net.minecraft.world.level.levelgen.FlatLevelSource; import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.lighting.LevelLightEngine; +import org.apache.logging.log4j.LogManager; /* Total: 3.135214124s @@ -88,9 +91,16 @@ Lod Generation: 0.269023348s public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnvionmentWrapper { - public static final boolean ENABLE_PERF_LOGGING = false; - public static final boolean ENABLE_EVENT_LOGGING = false; - public static final boolean ENABLE_LOAD_EVENT_LOGGING = false; + private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); + public static final ConfigBasedSpamLogger PREF_LOGGER = + new ConfigBasedSpamLogger(LogManager.getLogger("LodWorldGen"), + () -> CONFIG.client().advanced().debugging().debugSwitch().getLogWorldGenPerformance(),1); + public static final ConfigBasedLogger EVENT_LOGGER = + new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"), + () -> CONFIG.client().advanced().debugging().debugSwitch().getLogWorldGenEvent()); + public static final ConfigBasedLogger LOAD_LOGGER = + new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"), + () -> CONFIG.client().advanced().debugging().debugSwitch().getLogWorldGenLoadEvent()); //TODO: Make actual proper support for StarLight public static class PrefEvent @@ -191,7 +201,6 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv if (e.endNano != 0) { lodTime.add(e.endNano - preTime); - preTime = e.endNano; } } @@ -215,7 +224,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv //=================Generation Step=================== - public final LinkedList events = new LinkedList(); + public final LinkedList events = new LinkedList<>(); public final GlobalParameters params; public final StepStructureStart stepStructureStart = new StepStructureStart(this); public final StepStructureReference stepStructureReference = new StepStructureReference(this); @@ -226,16 +235,16 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv public final StepLight stepLight = new StepLight(this); public boolean unsafeThreadingRecorded = false; //public boolean safeMode = false; - private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class); public static final long EXCEPTION_TIMER_RESET_TIME = TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS); public static final int EXCEPTION_COUNTER_TRIGGER = 20; + public static final int RANGE_TO_RANGE_EMPTY_EXTENSION = 1; public int unknownExceptionCount = 0; public long lastExceptionTriggerTime = 0; public static final LodThreadFactory threadFactory = new LodThreadFactory("Gen-Worker-Thread", Thread.MIN_PRIORITY); - public static ThreadLocal isDistantGeneratorThread = new ThreadLocal(); + public static ThreadLocal isDistantGeneratorThread = new ThreadLocal<>(); public static boolean isCurrentThreadDistantGeneratorThread() { return (isDistantGeneratorThread.get() != null); @@ -250,9 +259,8 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv public T joinSync(CompletableFuture f) { if (!unsafeThreadingRecorded && !f.isDone()) { - MC.sendChatMessage("\u00A74\u00A7l\u00A7uERROR: Distant Horizons: Unsafe Threading in Chunk Generator Detected!"); - MC.sendChatMessage("\u00A7eTo increase stability, it is recommended to set world generation threads count to 1."); - ApiShared.LOGGER.error("Unsafe Threading in Chunk Generator: ", new RuntimeException("Concurrent future")); + EVENT_LOGGER.error("Unsafe Threading in Chunk Generator: ", new RuntimeException("Concurrent future")); + EVENT_LOGGER.error("To increase stability, it is recommended to set world generation threads count to 1."); unsafeThreadingRecorded = true; } return f.join(); @@ -300,8 +308,8 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv } catch (Throwable e) { - ApiShared.LOGGER.error("Batching World Generator: Event {} gotten an exception", event); - ApiShared.LOGGER.error("Exception: ", e); + EVENT_LOGGER.error("Batching World Generator: Event {} gotten an exception", event); + EVENT_LOGGER.error("Exception: ", e); unknownExceptionCount++; lastExceptionTriggerTime = System.nanoTime(); } @@ -312,12 +320,12 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv } else if (event.hasTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)) { - ApiShared.LOGGER.error("Batching World Generator: " + event + " timed out and terminated!"); - ApiShared.LOGGER.info("Dump PrefEvent: " + event.pEvent); + EVENT_LOGGER.error("Batching World Generator: " + event + " timed out and terminated!"); + EVENT_LOGGER.info("Dump PrefEvent: " + event.pEvent); try { if (!event.terminate()) - ApiShared.LOGGER.error("Failed to terminate the stuck generation event!"); + EVENT_LOGGER.error("Failed to terminate the stuck generation event!"); } finally { @@ -326,10 +334,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv } } if (unknownExceptionCount > EXCEPTION_COUNTER_TRIGGER) { - try { - MC.sendChatMessage("\u00A74\u00A7l\u00A7uERROR: Distant Horizons: Too many exceptions in Batching World Generator! Disabling the generator."); - } catch (Exception e) {} - ApiShared.LOGGER.error("Too many exceptions in Batching World Generator! Now disabling."); + EVENT_LOGGER.error("Too many exceptions in Batching World Generator! Disabling the generator."); unknownExceptionCount = 0; CONFIG.client().worldGenerator().setEnableDistantGeneration(false); } @@ -338,13 +343,13 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv public BatchGenerationEnvironment(IWorldWrapper serverlevel, LodBuilder lodBuilder, LodDimension lodDim) { super(serverlevel, lodBuilder, lodDim); - ApiShared.LOGGER.info("================WORLD_GEN_STEP_INITING============="); + EVENT_LOGGER.info("================WORLD_GEN_STEP_INITING============="); ChunkGenerator generator = ((WorldWrapper) serverlevel).getServerWorld().getChunkSource().getGenerator(); if (!(generator instanceof NoiseBasedChunkGenerator || generator instanceof DebugLevelSource || generator instanceof FlatLevelSource)) { - MC.sendChatMessage("\u00A74\u00A7l\u00A7uWARNING: Distant Horizons: Unknown Chunk Generator Detected! Distant Generation May Fail!"); - MC.sendChatMessage("\u00A7eIf it does crash, set Distant Generation to OFF or Generation Mode to None."); + EVENT_LOGGER.warn("Unknown Chunk Generator detected: [{}], Distant Generation May Fail!", generator.getClass()); + EVENT_LOGGER.warn("If it does crash, set Distant Generation to OFF or Generation Mode to None."); ApiShared.LOGGER.warn("Unknown Chunk Generator detected: {}", generator.getClass()); } params = new GlobalParameters((ServerLevel) ((WorldWrapper) serverlevel).getWorld(), lodBuilder, lodDim); @@ -360,7 +365,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv } catch (Exception e) { - ApiShared.LOGGER.error("DistantHorizons: Couldn't load chunk {}", chunkPos, e); + LOAD_LOGGER.error("DistantHorizons: Couldn't load chunk {}", chunkPos, e); } if (chunkData == null) { @@ -371,7 +376,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv try { return ChunkLoader.read(level, lightEngine, chunkPos, chunkData); } catch (Exception e) { - ApiShared.LOGGER.error("DistantHorizons: Couldn't load chunk {}", chunkPos, e); + LOAD_LOGGER.error("DistantHorizons: Couldn't load chunk {}", chunkPos, e); return new ProtoChunk(chunkPos, UpgradeData.EMPTY, level); } } @@ -380,25 +385,23 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv public void generateLodFromList(GenerationEvent e) { - if (ENABLE_EVENT_LOGGING) - ApiShared.LOGGER.info("Lod Generate Event: " + e.pos); + EVENT_LOGGER.debug("Lod Generate Event: " + e.pos); e.pEvent.beginNano = System.nanoTime(); - GridList referencedChunks; + ArrayGridList referencedChunks; + ArrayGridList genChunks; DistanceGenerationMode generationMode; LightedWorldGenRegion region; WorldGenLevelLightEngine lightEngine; LightGetterAdaptor adaptor; - + int refRange = e.range + RANGE_TO_RANGE_EMPTY_EXTENSION; + int refOffsetX = e.pos.x - refRange; + int refOffsetZ = e.pos.z - refRange; + try { adaptor = new LightGetterAdaptor(params.level); lightEngine = new WorldGenLevelLightEngine(adaptor); - - int cx = e.pos.x; - int cy = e.pos.z; - int rangeEmpty = e.range + 1; - GridList chunks = new GridList(rangeEmpty); - + @SuppressWarnings("resource") EmptyChunkGenerator generator = (int x, int z) -> { @@ -416,23 +419,19 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv target = new ProtoChunk(chunkPos, UpgradeData.EMPTY, params.level); return target; }; - - for (int oy = -rangeEmpty; oy <= rangeEmpty; oy++) - { - for (int ox = -rangeEmpty; ox <= rangeEmpty; ox++) - { - ChunkAccess target = generator.generate(cx + ox, cy + oy); - chunks.add(target); - } - } + + referencedChunks = new ArrayGridList<>(refRange*2+1, + (x,z) -> generator.generate(x + refOffsetX,z + refOffsetZ) + ); e.pEvent.emptyNano = System.nanoTime(); e.refreshTimeout(); - region = new LightedWorldGenRegion(params.level, lightEngine, chunks, ChunkStatus.STRUCTURE_STARTS, rangeEmpty, e.lightMode, generator); + region = new LightedWorldGenRegion(params.level, lightEngine, referencedChunks, + ChunkStatus.STRUCTURE_STARTS, refRange, e.lightMode, generator); adaptor.setRegion(region); - e.tParam.makeStructFeat(region); - referencedChunks = chunks.subGrid(e.range); - referencedChunks = generateDirect(e, referencedChunks, e.target, region); - + e.tParam.makeStructFeat(region, params); + genChunks = new ArrayGridList<>(referencedChunks, RANGE_TO_RANGE_EMPTY_EXTENSION, + referencedChunks.gridSize - RANGE_TO_RANGE_EMPTY_EXTENSION); + generateDirect(e, genChunks, e.target, region); } catch (StepStructureStart.StructStartCorruptedException f) { @@ -464,14 +463,12 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv default: return; } - int centreIndex = referencedChunks.size() / 2; - - for (int oy = -e.range; oy <= e.range; oy++) + + for (int oy = 0; oy < genChunks.gridSize; oy++) { - for (int ox = -e.range; ox <= e.range; ox++) + for (int ox = 0; ox < genChunks.gridSize; ox++) { - int targetIndex = referencedChunks.offsetOf(centreIndex, ox, oy); - ChunkAccess target = referencedChunks.get(targetIndex); + ChunkAccess target = genChunks.get(ox, oy); target.setLightCorrect(true); //if (target instanceof LevelChunk) // ((LevelChunk) target).setClientLightReady(true); @@ -479,8 +476,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv //boolean isPartial = target.isOldNoiseGeneration(); if (isFull) { - if (ENABLE_LOAD_EVENT_LOGGING) - ApiShared.LOGGER.info("Detected full existing chunk at {}", target.getPos()); + LOAD_LOGGER.info("Detected full existing chunk at {}", target.getPos()); params.lodBuilder.generateLodNodeFromChunk(params.lodDim, new ChunkWrapper(target, region), new LodBuilderConfig(DistanceGenerationMode.FULL), true, e.genAllDetails); } @@ -503,15 +499,15 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv } e.pEvent.endNano = System.nanoTime(); e.refreshTimeout(); - if (ENABLE_PERF_LOGGING) + if (PREF_LOGGER.canMaybeLog()) { e.tParam.perf.recordEvent(e.pEvent); - ApiShared.LOGGER.info(e.tParam.perf); + PREF_LOGGER.infoInc("{}", e.tParam.perf); } } - - public GridList generateDirect(GenerationEvent e, GridList subRange, Steps step, - LightedWorldGenRegion region) + + public void generateDirect(GenerationEvent e, ArrayGridList subRange, Steps step, + LightedWorldGenRegion region) { try { @@ -524,38 +520,38 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv } }); if (step == Steps.Empty) - return subRange; + return; stepStructureStart.generateGroup(e.tParam, region, subRange); e.pEvent.structStartNano = System.nanoTime(); e.refreshTimeout(); if (step == Steps.StructureStart) - return subRange; + return; stepStructureReference.generateGroup(e.tParam, region, subRange); e.pEvent.structRefNano = System.nanoTime(); e.refreshTimeout(); if (step == Steps.StructureReference) - return subRange; + return; stepBiomes.generateGroup(e.tParam, region, subRange); e.pEvent.biomeNano = System.nanoTime(); e.refreshTimeout(); if (step == Steps.Biomes) - return subRange; + return; stepNoise.generateGroup(e.tParam, region, subRange); e.pEvent.noiseNano = System.nanoTime(); e.refreshTimeout(); if (step == Steps.Noise) - return subRange; + return; stepSurface.generateGroup(e.tParam, region, subRange); e.pEvent.surfaceNano = System.nanoTime(); e.refreshTimeout(); if (step == Steps.Surface) - return subRange; + return; if (step == Steps.Carvers) - return subRange; + return; stepFeatures.generateGroup(e.tParam, region, subRange); e.pEvent.featureNano = System.nanoTime(); e.refreshTimeout(); - return subRange; + return; } finally { @@ -589,14 +585,14 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv @Override public void stop(boolean blocking) { - ApiShared.LOGGER.info("Batch Chunk Generator shutting down..."); + EVENT_LOGGER.info("Batch Chunk Generator shutting down..."); executors.shutdownNow(); if (blocking) try { if (!executors.awaitTermination(10, TimeUnit.SECONDS)) { - ApiShared.LOGGER.error("Batch Chunk Generator shutdown failed! Ignoring child threads..."); + EVENT_LOGGER.error("Batch Chunk Generator shutdown failed! Ignoring child threads..."); } } catch (InterruptedException e) { - ApiShared.LOGGER.error("Batch Chunk Generator shutdown failed! Ignoring child threads...", e); + EVENT_LOGGER.error("Batch Chunk Generator shutdown failed! Ignoring child threads...", e); } } } \ No newline at end of file diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/ThreadedParameters.java b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/ThreadedParameters.java index f641a5bc0..aa4d543c4 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/ThreadedParameters.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/ThreadedParameters.java @@ -12,7 +12,7 @@ public final class ThreadedParameters { private static final ThreadLocal localParam = new ThreadLocal(); final ServerLevel level; - public final WorldGenStructFeatManager structFeat; + public WorldGenStructFeatManager structFeat = null; boolean isValid = true; public final PerfCalculator perf = new PerfCalculator(); @@ -34,11 +34,9 @@ public final class ThreadedParameters private ThreadedParameters(GlobalParameters param) { level = param.level; - structFeat = new WorldGenStructFeatManager(level, param.worldGenSettings, null); + structFeat = new WorldGenStructFeatManager(level, param.worldGenSettings); } - - public void makeStructFeat(WorldGenLevel genLevel) - { - structFeat.setGenLevel(genLevel); + public void makeStructFeat(WorldGenLevel genLevel, GlobalParameters param) { + structFeat = new WorldGenStructFeatManager(param.worldGenSettings, genLevel); } } \ No newline at end of file diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/WorldGeneratorWrapper.java b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/WorldGeneratorWrapper.java deleted file mode 100644 index cda496fd8..000000000 --- a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/WorldGeneratorWrapper.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.seibel.lod.common.wrappers.worldGeneration; - -import com.seibel.lod.core.builders.lodBuilding.LodBuilder; -import com.seibel.lod.core.builders.lodBuilding.LodBuilderConfig; -import com.seibel.lod.core.enums.config.DistanceGenerationMode; -import com.seibel.lod.core.objects.lod.LodDimension; -//import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; -import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper; -//import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; -import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; -import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractWorldGeneratorWrapper; -import com.seibel.lod.common.wrappers.chunk.ChunkWrapper; -import com.seibel.lod.common.wrappers.world.WorldWrapper; - -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.chunk.*; - -/** - * @author James Seibel - * @version 11-13-2021 - */ -public class WorldGeneratorWrapper extends AbstractWorldGeneratorWrapper -{ - public final ServerLevel serverWorld; - public final LodDimension lodDim; - public final LodBuilder lodBuilder; - - public WorldGeneratorWrapper(LodBuilder newLodBuilder, LodDimension newLodDimension, IWorldWrapper worldWrapper) - { - super(newLodBuilder, newLodDimension, worldWrapper); - - lodBuilder = newLodBuilder; - lodDim = newLodDimension; - serverWorld = ((WorldWrapper) worldWrapper).getServerWorld(); - } - - - /** takes about 2-5 ms */ - @Override - public void generateBiomesOnly(AbstractChunkPosWrapper pos, DistanceGenerationMode generationMode) - { - generate(pos.getX(), pos.getZ(), generationMode); - } - - - /** takes about 10 - 20 ms */ - @Override - public void generateSurface(AbstractChunkPosWrapper pos) - { - generate(pos.getX(), pos.getZ(), DistanceGenerationMode.SURFACE); - } - - - /** - * takes about 15 - 20 ms - *

- */ - @Override - public void generateFeatures(AbstractChunkPosWrapper pos) - { - generate(pos.getX(), pos.getZ(), DistanceGenerationMode.FEATURES); - } - - - /** - * Generates using MC's ServerWorld. - *

- * on pre generated chunks 0 - 1 ms
- * on un generated chunks 0 - 50 ms
- * with the median seeming to hover around 15 - 30 ms
- * and outliers in the 100 - 200 ms range
- *

- * Note this should not be multithreaded and does cause server/simulation lag - * (Higher lag for generating than loading) - */ - @Override - public void generateFull(AbstractChunkPosWrapper pos) - { - generate(pos.getX(), pos.getZ(), DistanceGenerationMode.FULL); - } - - private void generate(int chunkX, int chunkZ, DistanceGenerationMode generationMode) { - -// long t = System.nanoTime(); - - ChunkStatus targetStatus; - switch (generationMode) { - case BIOME_ONLY: - targetStatus = ChunkStatus.BIOMES; - break; - case BIOME_ONLY_SIMULATE_HEIGHT: - targetStatus = ChunkStatus.NOISE; - break; - case SURFACE: - targetStatus = ChunkStatus.SURFACE; - break; - case FEATURES: - targetStatus = ChunkStatus.FEATURES; - break; - case FULL: - targetStatus = ChunkStatus.FULL; - break; - case NONE: - default: - return; - } - - // The bool=true means that we want to generate chunk, and that the returned ChunkAccess must not be null - - ChunkAccess ca = serverWorld.getChunkSource().getChunk(chunkX, chunkZ, targetStatus, true); - if (ca == null) throw new RuntimeException("This should NEVER be null due to bool being true"); - lodBuilder.generateLodNodeFromChunk(lodDim, new ChunkWrapper(ca, serverWorld), new LodBuilderConfig(generationMode), false, true); - - // long duration = System.nanoTime()-t; - - // Debug print the duration - // System.out.println("LodChunkGenFull["+chunkX+","+chunkZ+"]: "+(double)(duration)/1000.); - } - - - - - - - - /* TODO: Ask leetom to update chart - * performance/generation tests related to - * serverWorld.getChunk(x, z, ChunkStatus. *** ) - - true/false is whether they generated blocks or not - the time is how long it took to generate - - ChunkStatus.EMPTY 0 - 1 ms false (empty, what did you expect? :P) - ChunkStatus.STRUCTURE_REFERENCES 1 - 2 ms false (no height, only generates some chunks) - ChunkStatus.BIOMES 1 - 10 ms false (no height) - ChunkStatus.NOISE 4 - 15 ms true (all blocks are stone) - ChunkStatus.LIQUID_CARVERS 6 - 12 ms true (no snow/trees, just grass) - ChunkStatus.SURFACE 5 - 15 ms true (no snow/trees, just grass) - ChunkStatus.CARVERS 5 - 30 ms true (no snow/trees, just grass) - ChunkStatus.FEATURES 7 - 25 ms true - ChunkStatus.HEIGHTMAPS 20 - 40 ms true - ChunkStatus.LIGHT 20 - 40 ms true - ChunkStatus.FULL 30 - 50 ms true - ChunkStatus.SPAWN 50 - 80 ms true - - - At this point I would suggest using FEATURES, as it generates snow and trees - (and any other object that are needed to make biomes distinct) - - Otherwise, if snow/trees aren't necessary SURFACE is the next fastest (although not by much) - */ -} diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/mimicObject/ChunkLoader.java b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/mimicObject/ChunkLoader.java index 480aa91eb..a9c9727d6 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/mimicObject/ChunkLoader.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/mimicObject/ChunkLoader.java @@ -1,10 +1,12 @@ package com.seibel.lod.common.wrappers.worldGeneration.mimicObject; +import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment; import com.seibel.lod.core.api.ApiShared; import java.util.Objects; +import com.seibel.lod.core.logging.ConfigBasedLogger; import net.minecraft.core.Registry; import net.minecraft.core.SectionPos; import net.minecraft.nbt.CompoundTag; @@ -30,7 +32,7 @@ import net.minecraft.world.level.material.Fluids; import org.apache.logging.log4j.Logger; public class ChunkLoader { - private static final Logger LOGGER = ApiShared.LOGGER; + private static final ConfigBasedLogger LOGGER = BatchGenerationEnvironment.LOAD_LOGGER; private static LevelChunkSection[] readSections(WorldGenLevel level, LevelLightEngine lightEngine, ChunkPos chunkPos, CompoundTag tagLevel) { @@ -102,8 +104,7 @@ public class ChunkLoader { ChunkPos actualPos = new ChunkPos(tagLevel.getInt("xPos"), tagLevel.getInt("zPos")); if (!Objects.equals(chunkPos, actualPos)) { - LOGGER.error("Distant Horizons: Chunk file at {} is in the wrong location; Ignoring. (Expected {}, got {})", - (Object) chunkPos, (Object) chunkPos, (Object) actualPos); + LOGGER.error("Chunk file at {} is in the wrong location; Ignoring. (Expected {}, got {})", (Object) chunkPos, (Object) chunkPos, (Object) actualPos); return null; } diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/mimicObject/LightedWorldGenRegion.java b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/mimicObject/LightedWorldGenRegion.java index e3b15c7ef..a98dc45fe 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/mimicObject/LightedWorldGenRegion.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/mimicObject/LightedWorldGenRegion.java @@ -91,6 +91,13 @@ public class LightedWorldGenRegion extends WorldGenRegion { return true; } + // TODO Check this +// @Override +// public List> startsForFeature(SectionPos sectionPos, +// StructureFeature structureFeature) { +// return structFeat.startsForFeature(sectionPos, structureFeature); +// } + // Skip updating the related tile entities @Override public boolean setBlock(BlockPos blockPos, BlockState blockState, int i, int j) { @@ -240,6 +247,10 @@ public class LightedWorldGenRegion extends WorldGenRegion { return blockTintCache.getColor(blockPos, null); // FIXME[Generator]: Replace this null with something else } + private Biome _getBiome(BlockPos pos) { + return getBiome(pos); + } + public int calculateBlockTint(BlockPos blockPos, ColorResolver colorResolver) { int i = (Minecraft.getInstance()).options.biomeBlendRadius; diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/mimicObject/WorldGenStructFeatManager.java b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/mimicObject/WorldGenStructFeatManager.java index 1be8dfc4b..8b56392ec 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/mimicObject/WorldGenStructFeatManager.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/mimicObject/WorldGenStructFeatManager.java @@ -15,24 +15,25 @@ import net.minecraft.world.level.levelgen.feature.StructureFeature; import net.minecraft.world.level.levelgen.structure.StructureStart; public class WorldGenStructFeatManager extends StructureFeatureManager { - WorldGenLevel genLevel; + final WorldGenLevel genLevel; WorldGenSettings worldGenSettings; - public WorldGenStructFeatManager(LevelAccessor levelAccessor, WorldGenSettings worldGenSettings, + public WorldGenStructFeatManager(WorldGenSettings worldGenSettings, WorldGenLevel genLevel) { - super(levelAccessor, worldGenSettings); + super(genLevel, worldGenSettings); this.genLevel = genLevel; this.worldGenSettings = worldGenSettings; } - - public void setGenLevel(WorldGenLevel genLevel) { - this.genLevel = genLevel; - } @Override public WorldGenStructFeatManager forWorldGenRegion(WorldGenRegion worldGenRegion) { if (worldGenRegion == genLevel) return this; - return new WorldGenStructFeatManager(worldGenRegion, worldGenSettings, worldGenRegion); + return new WorldGenStructFeatManager(worldGenSettings, worldGenRegion); + } + + private ChunkAccess _getChunk(int x, int z, ChunkStatus status) { + if (genLevel == null) return null; + return genLevel.getChunk(x, z, status, false); } @Override diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepFeatures.java b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepFeatures.java index 0383c3b21..3c1645e09 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepFeatures.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepFeatures.java @@ -5,8 +5,8 @@ import java.util.ArrayList; import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters; import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightedWorldGenRegion; import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment; -import com.seibel.lod.core.util.GridList; +import com.seibel.lod.core.util.gridList.ArrayGridList; import net.minecraft.ReportedException; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkStatus; @@ -27,7 +27,7 @@ public final class StepFeatures { public final ChunkStatus STATUS = ChunkStatus.FEATURES; - public void generateGroup(ThreadedParameters tParams, LightedWorldGenRegion worldGenRegion, GridList chunks) { + public void generateGroup(ThreadedParameters tParams, LightedWorldGenRegion worldGenRegion, ArrayGridList chunks) { ArrayList chunksToDo = new ArrayList(); for (ChunkAccess chunk : chunks) { diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepLight.java b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepLight.java index 13728799b..23c438538 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepLight.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/worldGeneration/step/StepLight.java @@ -2,8 +2,8 @@ package com.seibel.lod.common.wrappers.worldGeneration.step; import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment; import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.WorldGenLevelLightEngine; -import com.seibel.lod.core.util.GridList; +import com.seibel.lod.core.util.gridList.ArrayGridList; import net.minecraft.server.level.ThreadedLevelLightEngine; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkStatus; @@ -28,7 +28,7 @@ public final class StepLight { public final ChunkStatus STATUS = ChunkStatus.LIGHT; public void generateGroup(LightEventListener lightEngine, - GridList chunks) { + ArrayGridList chunks) { //ArrayList chunksToDo = new ArrayList(); for (ChunkAccess chunk : chunks) { diff --git a/common/src/main/resources/lod.accesswidener b/common/src/main/resources/lod.accesswidener index c639800fb..b84cb29fd 100644 --- a/common/src/main/resources/lod.accesswidener +++ b/common/src/main/resources/lod.accesswidener @@ -1,6 +1,6 @@ accessWidener v1 named -# used when determining where to save files too +# used when determining where to save files to accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File; # used when rendering @@ -25,7 +25,10 @@ accessible field net/minecraft/world/level/lighting/LevelLightEngine skyEngine L # world generation accessible method net/minecraft/world/level/levelgen/Heightmap setHeight (III)V accessible field net/minecraft/world/level/biome/Biome generationSettings Lnet/minecraft/world/level/biome/BiomeGenerationSettings; +accessible field net/minecraft/world/level/biome/Biome biomeCategory Lnet/minecraft/world/level/biome/Biome$BiomeCategory; +# accessible field net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator settings Lnet/minecraft/core/Holder; accessible field net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator settings Ljava/util/function/Supplier; +#accessible method net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator doCreateBiomes (Lnet/minecraft/core/Registry;Lnet/minecraft/world/level/levelgen/blending/Blender;Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkAccess;)V accessible method net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator doFill (Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkAccess;II)Lnet/minecraft/world/level/chunk/ChunkAccess; accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V diff --git a/core b/core index bca2b6180..4c984c5c1 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit bca2b61800b613b630def131e9c9f85f9736493d +Subproject commit 4c984c5c102aaee9fd5a34acf94aa0ffbdbfacb1 diff --git a/fabric/src/main/java/com/seibel/lod/fabric/ClientProxy.java b/fabric/src/main/java/com/seibel/lod/fabric/ClientProxy.java index f4bb45710..122f80e9c 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/ClientProxy.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/ClientProxy.java @@ -19,6 +19,7 @@ package com.seibel.lod.fabric; +import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment; import com.seibel.lod.core.api.ClientApi; import com.seibel.lod.core.api.EventApi; import com.mojang.blaze3d.platform.InputConstants; @@ -42,6 +43,7 @@ import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.chunk.LevelChunk; import java.util.HashSet; +import java.util.function.Supplier; import org.lwjgl.glfw.GLFW; @@ -58,6 +60,7 @@ public class ClientProxy private final EventApi eventApi = EventApi.INSTANCE; private final ClientApi clientApi = ClientApi.INSTANCE; + public static Supplier isGenerationThreadChecker = null; /** * Registers Fabric Events @@ -89,6 +92,7 @@ public class ClientProxy ClientTickEvents.END_CLIENT_TICK.register(client -> { if (client.player != null) onKeyInput(); }); + isGenerationThreadChecker = BatchGenerationEnvironment::isCurrentThreadDistantGeneratorThread; } diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinUtilBackgroudThread.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinUtilBackgroudThread.java index c1b67baca..879c264f1 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinUtilBackgroudThread.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinUtilBackgroudThread.java @@ -2,6 +2,7 @@ package com.seibel.lod.fabric.mixins; import java.util.concurrent.Executor; +import com.seibel.lod.fabric.ClientProxy; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -29,7 +30,7 @@ public class MixinUtilBackgroudThread at = @At("HEAD"), cancellable = true) private static void overrideUtil$wrapThreadWithTaskName(String string, Runnable r, CallbackInfoReturnable ci) { - if (DependencySetupDoneCheck.isDone && doTriggerOverride()) + if (ClientProxy.isGenerationThreadChecker != null && ClientProxy.isGenerationThreadChecker.get()) { // ApiShared.LOGGER.info("util wrapThreadWithTaskName(Runnable) triggered"); ci.setReturnValue(r); @@ -39,7 +40,7 @@ public class MixinUtilBackgroudThread @Inject(method = "backgroundExecutor", at = @At("HEAD"), cancellable = true) private static void overrideUtil$backgroundExecutor(CallbackInfoReturnable ci) { - if (DependencySetupDoneCheck.isDone && doTriggerOverride()) + if (ClientProxy.isGenerationThreadChecker != null && ClientProxy.isGenerationThreadChecker.get()) { // ApiShared.LOGGER.info("util backgroundExecutor triggered"); ci.setReturnValue(Runnable::run); diff --git a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinWorldRenderer.java b/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinWorldRenderer.java index 9264da68f..a7403fdd3 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinWorldRenderer.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/mixins/MixinWorldRenderer.java @@ -21,6 +21,7 @@ package com.seibel.lod.fabric.mixins; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Matrix4f; +import com.seibel.lod.common.Config; import com.seibel.lod.common.wrappers.McObjectConverter; import com.seibel.lod.core.api.ClientApi; import com.seibel.lod.core.objects.math.Mat4f; @@ -60,8 +61,11 @@ public class MixinWorldRenderer previousPartialTicks = tickDelta; } + // Inject rendering at first call to renderChunkLayer // HEAD or RETURN - @Inject(at = @At("HEAD"), method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V") + @Inject(at = @At("HEAD"), + method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V", + cancellable = true) private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback) { // only render before solid blocks @@ -72,5 +76,8 @@ public class MixinWorldRenderer ClientApi.INSTANCE.renderLods(mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks); } + if (Config.Client.Advanced.lodOnlyMode) { + callback.cancel(); + } } } diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 8c55b17d5..7f5921c3d 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -34,8 +34,8 @@ "depends": { "fabricloader": "*", "fabric": "*", - "minecraft": "1.17.x", - "java": ">=16" + "minecraft": "${minecraft_version}", + "java": ">=${java_version}" }, "suggests": { "another-mod": "*" diff --git a/forge/src/main/java/com/seibel/lod/forge/ForgeMain.java b/forge/src/main/java/com/seibel/lod/forge/ForgeMain.java index 44d3067a3..f0f3b3d80 100644 --- a/forge/src/main/java/com/seibel/lod/forge/ForgeMain.java +++ b/forge/src/main/java/com/seibel/lod/forge/ForgeMain.java @@ -70,20 +70,9 @@ public class ForgeMain implements LodForgeMethodCaller { LodCommonMain.initConfig(); LodCommonMain.startup(this, !FMLLoader.getDist().isClient()); - - ApiShared.LOGGER.info("Distant Horizons initializing..."); - - - // make sure the dependencies are set up before the mod needs them ForgeDependencySetup.createInitialBindings(); ForgeDependencySetup.finishBinding(); - - // mod dependencies - if (ReflectionHandler.instance.optifinePresent()) { - ModAccessorHandler.bind(IOptifineAccessor.class, new OptifineAccessor()); - } - - ModAccessorHandler.finishBinding(); + ApiShared.LOGGER.info("Distant Horizons initializing..."); } @@ -99,6 +88,15 @@ public class ForgeMain implements LodForgeMethodCaller private void onClientStart(final FMLClientSetupEvent event) { + if (ReflectionHandler.instance.optifinePresent()) { + ModAccessorHandler.bind(IOptifineAccessor.class, new OptifineAccessor()); + } + + ModAccessorHandler.finishBinding(); + + + ModAccessorHandler.finishBinding(); + ModLoadingContext.get().registerExtensionPoint(ConfigGuiHandler.ConfigGuiFactory.class, () -> new ConfigGuiHandler.ConfigGuiFactory((client, parent) -> ConfigGui.getScreen(parent, ""))); forgeClientProxy = new ForgeClientProxy(); diff --git a/forge/src/main/java/com/seibel/lod/forge/mixins/MixinWorldRenderer.java b/forge/src/main/java/com/seibel/lod/forge/mixins/MixinWorldRenderer.java index 9a3947d32..cad7b44e8 100644 --- a/forge/src/main/java/com/seibel/lod/forge/mixins/MixinWorldRenderer.java +++ b/forge/src/main/java/com/seibel/lod/forge/mixins/MixinWorldRenderer.java @@ -21,6 +21,7 @@ package com.seibel.lod.forge.mixins; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Matrix4f; +import com.seibel.lod.common.Config; import com.seibel.lod.common.wrappers.McObjectConverter; import com.seibel.lod.core.api.ClientApi; import com.seibel.lod.core.objects.math.Mat4f; @@ -61,7 +62,9 @@ public class MixinWorldRenderer } // HEAD or RETURN - @Inject(at = @At("HEAD"), method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V") + @Inject(at = @At("HEAD"), + method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V", + cancellable = true) private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback) { // only render before solid blocks @@ -72,5 +75,8 @@ public class MixinWorldRenderer ClientApi.INSTANCE.renderLods(mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks); } + if (Config.Client.Advanced.lodOnlyMode) { + callback.cancel(); + } } } diff --git a/gradle.properties b/gradle.properties index 3c8eaee09..297c34e5f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,13 +1,11 @@ org.gradle.jvmargs=-Xmx2048M +org.gradle.daemon=false -minecraft_version=1.17.1 - -archives_base_name=DistantHorizons -mod_version=1.6.2a maven_group=com.seibel.lod -toml_version=3.6.4 +archives_base_name=DistantHorizons # Mod info +mod_version=1.6.2a mod_name=Distant Horizons mod_description=This mod generates and renders simplified terrain beyond the normal view distance at a low performance cost. Allowing you to see much farther without turning your game into a slideshow. mod_authors=James Seibel, Leonardo Amato, Cola, coolGi2007, Ran, Leetom @@ -15,35 +13,9 @@ mod_homepage=https://www.curseforge.com/minecraft/mc-mods/distant-horizons mod_source=https://gitlab.com/jeseibel/minecraft-lod-mod/ mod_issues=https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues +# Global Plugin versions +toml_version=3.6.4 +manifold_version=2022.1.7 -# Fabric loader -fabric_loader_version=0.13.2 -fabric_api_version=0.46.1+1.17 - # Fabric mod versions - modmenu_version=2.0.14 - starlight_version_fabric=3442770 - lithium_version=mc1.17.1-0.7.5 - sodium_version=3605275 - iris_version=1.17.x-v1.1.4 - immersive_portals_version = 0.14-1.17 - - # Fabric mod run - # 0 = Dont enable and dont run - # 1 = Can be refranced in code but dosnt run - # 2 = Can be refranced in code and runs in client - enable_starlight=0 - enable_lithium=0 - enable_sodium=1 - enable_iris=0 - - -# Forge loader -forge_version=37.1.1 - # Forge mod versions - starlight_version_forge=3457784 - - # Forge mod run - # 0 = Dont enable and dont run - # 1 = Can be refranced in code but dosnt run - # 2 = Can be refranced in code and runs in client - enable_starlight_forge=0 +##### FOR IDE SUPPORT AND TELL IDE TO USE CERTIAN MC VERSION: SWITCH THIS: +mcVer=1.17.1 \ No newline at end of file diff --git a/plugins/DHJarMerger-1.0.jar b/plugins/DHJarMerger-1.0.jar index a38dae5e7db13ff0e1069cb8024b5be76cec5454..acec82e0b721889e26a55a92be5a39831bd5b0c3 100644 GIT binary patch delta 7757 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 delta 7691 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