Merge branch 'main' of https://gitlab.com/jeseibel/minecraft-lod-mod
This commit is contained in:
+18
-2
@@ -5,7 +5,9 @@ image: gradle:eclipse-temurin
|
||||
|
||||
# all stages need to be defined here
|
||||
stages:
|
||||
# TODO: Make stages depending on what is in versionProperties
|
||||
# TODO: Make stages depend on what is in versionProperties
|
||||
- build_1_16_5
|
||||
- build_1_17_1
|
||||
- build_1_18_2
|
||||
- build_1_19_2
|
||||
- build_1_19_4
|
||||
@@ -54,6 +56,20 @@ variables:
|
||||
extends: .build_java
|
||||
|
||||
|
||||
# 1.16.5 build
|
||||
build_1_16_5:
|
||||
stage: build_1_16_5
|
||||
variables:
|
||||
MC_VER: "1.16.5"
|
||||
extends: .build_mc
|
||||
|
||||
# 1.17.1 build
|
||||
build_1_17_1:
|
||||
stage: build_1_17_1
|
||||
variables:
|
||||
MC_VER: "1.17.1"
|
||||
extends: .build_mc
|
||||
|
||||
# 1.18.2 build
|
||||
build_1_18_2:
|
||||
stage: build_1_18_2
|
||||
@@ -130,7 +146,7 @@ pages:
|
||||
|
||||
|
||||
|
||||
# ============================== Previos CI for future reference ============================== #
|
||||
# ============================== Previous CI for future reference ============================== #
|
||||
## all stages need to be defined here
|
||||
# # Don't build the standalone jar yet because it isn't done yet
|
||||
# # - build_standalone
|
||||
|
||||
@@ -20,31 +20,31 @@ If you want to see a quick demo, check out a video covering the mod here:
|
||||
|
||||
### This branch supports the following versions of Minecraft:
|
||||
|
||||
#### 1.19.4 (BROKE)
|
||||
#### 1.20.1, 1.20
|
||||
Fabric: 0.14.21\
|
||||
Fabric API: 0.85.0+1.20.1\
|
||||
Forge: 45.1.0\
|
||||
Parchment: 1.19.3:2023.03.25\
|
||||
Modmenu: 7.0.1
|
||||
|
||||
#### 1.19.4
|
||||
Fabric: 0.14.21\
|
||||
Fabric API: 0.83.0+1.19.4\
|
||||
Forge: 45.1.0\
|
||||
Parchment: 1.19.3:2023.03.12\
|
||||
Parchment: 1.19.3:2023.06.25\
|
||||
Modmenu: 6.2.3
|
||||
|
||||
#### 1.19.2 (BROKE)
|
||||
#### 1.19.2
|
||||
Fabric: 0.14.21\
|
||||
Fabric API: 0.76.0+1.19.2\
|
||||
Forge: 43.2.14\
|
||||
Parchment: 1.19.2:2022.11.27\
|
||||
Modmenu: 4.2.0-beta.2
|
||||
|
||||
#### 1.19 (BROKE)
|
||||
Fabric: 0.14.21\
|
||||
Fabric API: 0.58.0+1.19\
|
||||
Forge: 41.1.0\
|
||||
Parchment: 1.19.2:2022.11.27\
|
||||
Modmenu: 4.0.4
|
||||
|
||||
#### 1.18.2
|
||||
#### 1.18.2 (Default)
|
||||
Fabric: 0.14.21\
|
||||
Fabric API: 0.76.0+1.18.2\
|
||||
Forge: 40.2.9\
|
||||
Forge: 40.2.10\
|
||||
Parchment: 1.18.2:2022.11.06\
|
||||
Modmenu: 3.2.5
|
||||
|
||||
@@ -64,6 +64,8 @@ Modmenu: 1.16.22
|
||||
|
||||
### Versions no longer supported
|
||||
- 1.18.1, 1.18
|
||||
- 1.19.1, 1.19
|
||||
- 1.19.3
|
||||
<br><br>
|
||||
|
||||
### Plugin and Library versions
|
||||
@@ -119,7 +121,7 @@ From the File Explorer:
|
||||
1. Download and extract the project zip
|
||||
2. Download the core from https://gitlab.com/jeseibel/distant-horizons-core and extract into a folder called `coreSubProjects`
|
||||
3. Open a terminal emulator in the project folder (On Windows you can type `cmd` in the title bar)
|
||||
4. Run the commands: `./gradlew assemble`
|
||||
4. Run the commands: `./gradlew assemble` (You may need to use a `.\` on Windows)
|
||||
5. Merge the jars wih `./gradlew mergeJars`
|
||||
6. The compiled jar file will be in the folder `Merged`
|
||||
|
||||
@@ -178,7 +180,7 @@ https://github.com/PacifistMC/Forgix
|
||||
LZ4 for Java (data compression)\
|
||||
https://github.com/lz4/lz4-java
|
||||
|
||||
Json & Toml for Java (config handling)\
|
||||
NightConfig for Json & Toml (config handling)\
|
||||
https://github.com/TheElectronWill/night-config
|
||||
|
||||
SVG Salamander for SVG support\
|
||||
|
||||
+29
-7
@@ -31,6 +31,7 @@ def writeBuildGradlePredefine(List<String> mcVers, int mcIndex) {
|
||||
|
||||
if (mcIndex < i) {
|
||||
// exclusive before
|
||||
// FIXME doesn't function correctly for 1.16.5 (IE the first item in the list)
|
||||
redefineList.add("PRE_MC_" + mcStr)
|
||||
}
|
||||
if (mcIndex <= i) {
|
||||
@@ -230,6 +231,7 @@ subprojects { p ->
|
||||
forgeShadowMe("com.formdev:flatlaf-extras:${rootProject.flatlaf_version}")
|
||||
|
||||
// Netty
|
||||
// Breaks 1.16.5
|
||||
forgeShadowMe("io.netty:netty-all:${rootProject.netty_version}")
|
||||
|
||||
// Remember, for lwjgl dependencies that arent included in Minecraft, you need to also need to add it to the ShadowJar thing
|
||||
@@ -324,13 +326,17 @@ subprojects { p ->
|
||||
// Put stuff from gradle.properties into the mod info
|
||||
processResources {
|
||||
def resourceTargets = [ // Location of where to inject the properties
|
||||
// Properties for each of the loaders
|
||||
"fabric.mod.json",
|
||||
"quilt.mod.json",
|
||||
"META-INF/mods.toml",
|
||||
// Holds info like git commit
|
||||
// TODO: For some reason this script doesnt work with the core project
|
||||
"build_info.json",
|
||||
|
||||
// The mixins for each of the loaders
|
||||
"DistantHorizons."+ p.name +".fabricLike.mixins.json"
|
||||
// Properties for each of the loaders
|
||||
"fabric.mod.json",
|
||||
"quilt.mod.json",
|
||||
"META-INF/mods.toml",
|
||||
|
||||
// The mixins for each of the loaders
|
||||
"DistantHorizons."+ p.name +".fabricLike.mixins.json"
|
||||
]
|
||||
def intoTargets = ["$buildDir/resources/main/"] // Location of the built resources folder
|
||||
|
||||
@@ -353,6 +359,18 @@ subprojects { p ->
|
||||
// TODOI: Find something we can use so we can basically re-map only when the jar is shadowed and relocated
|
||||
// println p.tasks.findByName('shadowJar')
|
||||
|
||||
// Gets git info for the project
|
||||
def git_main_commit = "Git_not_found"
|
||||
def git_core_commit = "Git_not_found"
|
||||
def git_main_branch = "Git_not_found"
|
||||
try {
|
||||
"git rev-parse --is-inside-work-tree".execute() // If git doesnt exist, or this isnt cloned from git, then this wont work
|
||||
git_main_commit = 'git rev-parse --verify HEAD'.execute().text.trim()
|
||||
git_core_commit = 'git ls-tree --object-only HEAD coreSubProjects'.execute().text.trim()
|
||||
git_main_branch = 'git symbolic-ref --short HEAD'.execute().text.trim()
|
||||
} catch (Exception e) {
|
||||
println "Git or Git project not found"
|
||||
}
|
||||
|
||||
def replaceProperties = [
|
||||
version : mod_version,
|
||||
@@ -368,7 +386,11 @@ subprojects { p ->
|
||||
compatible_minecraft_versions: compatible_minecraft_versions,
|
||||
compatible_forgemc_versions : compatible_forgemc_versions,
|
||||
java_version : java_version,
|
||||
quilt_contributors : "{"+quilt_contributors.join(", ")+"}"
|
||||
quilt_contributors : "{"+quilt_contributors.join(", ")+"}",
|
||||
|
||||
git_main_commit : git_main_commit,
|
||||
git_core_commit : git_core_commit,
|
||||
git_main_branch : git_main_branch
|
||||
]
|
||||
// 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
|
||||
|
||||
|
||||
+34
-3
@@ -7,6 +7,8 @@ import org.joml.Matrix4f;
|
||||
#endif
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
@@ -30,15 +32,44 @@ public class SeamlessOverdraw
|
||||
minecraftProjectionMatrix.get(matrixFloatArray);
|
||||
#endif
|
||||
|
||||
return overwriteMinecraftNearFarClipPlanes(matrixFloatArray, previousPartialTicks);
|
||||
}
|
||||
|
||||
public static float[] overwriteMinecraftNearFarClipPlanes(Mat4f minecraftProjectionMatrix, float previousPartialTicks)
|
||||
{
|
||||
return overwriteMinecraftNearFarClipPlanes(minecraftProjectionMatrix.getValuesAsArray(), previousPartialTicks);
|
||||
}
|
||||
|
||||
private static float[] overwriteMinecraftNearFarClipPlanes(float[] projectionMatrixFloatArray, float previousPartialTicks)
|
||||
{
|
||||
float dhFarClipPlane = RenderUtil.getNearClipPlaneDistanceInBlocks(previousPartialTicks);
|
||||
|
||||
// works for fabric, bad not for forge for some reason :/
|
||||
float farClip = dhFarClipPlane * 5.1f; // magic number found via trial and error, James has no idea what it represents, except that it makes the seam between DH and vanilla rendering pretty close
|
||||
float nearClip = 0.5f; // this causes issues with some vanilla rendering, specifically the wireframe around selected blocks is slightly off. Unfortunately the ratio between the near and far clip plane can't be easily modified without completely screwing up the rendering.
|
||||
|
||||
// these may be the wrong index locations in any version of MC other than 1.18.2
|
||||
matrixFloatArray[10] = -((farClip + nearClip) / (farClip - nearClip)); // near clip plane
|
||||
matrixFloatArray[11] = -((2 * farClip * nearClip) / (farClip - nearClip)); // far clip plane
|
||||
projectionMatrixFloatArray[10] = -((farClip + nearClip) / (farClip - nearClip)); // near clip plane
|
||||
projectionMatrixFloatArray[11] = -((2 * farClip * nearClip) / (farClip - nearClip)); // far clip plane
|
||||
|
||||
return matrixFloatArray;
|
||||
|
||||
return projectionMatrixFloatArray;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper methods //
|
||||
//================//
|
||||
|
||||
public static void applyLegacyProjectionMatrix(float[] projectionMatrixFloatArray)
|
||||
{
|
||||
int glMatrixMode = GL15.glGetInteger(GL15.GL_MATRIX_MODE);
|
||||
GL15.glMatrixMode(GL15.GL_PROJECTION);
|
||||
|
||||
GL15.glLoadMatrixf(projectionMatrixFloatArray);
|
||||
|
||||
GL15.glMatrixMode(glMatrixMode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -95,23 +95,25 @@ public class WrapperFactory implements IWrapperFactory
|
||||
}
|
||||
}
|
||||
|
||||
// MC 1.18, 1.19, 1.20
|
||||
#if POST_MC_1_17_1
|
||||
// MC 1.16, 1.18, 1.19, 1.20
|
||||
#if POST_MC_1_17_1 || MC_1_16_5
|
||||
else if (objectArray.length == 2)
|
||||
{
|
||||
// correct number of parameters from the API
|
||||
|
||||
// chunk
|
||||
if (!(objectArray[0] instanceof ChunkAccess chunk))
|
||||
if (!(objectArray[0] instanceof ChunkAccess))
|
||||
{
|
||||
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
|
||||
}
|
||||
ChunkAccess chunk = (ChunkAccess)objectArray[0];
|
||||
|
||||
// light source
|
||||
if (!(objectArray[1] instanceof LevelReader lightSource))
|
||||
if (!(objectArray[1] instanceof LevelReader))
|
||||
{
|
||||
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
|
||||
}
|
||||
LevelReader lightSource = (LevelReader)objectArray[1];
|
||||
|
||||
|
||||
return new ChunkWrapper(chunk, lightSource, /*A DH wrapped level isn't necessary*/null);
|
||||
@@ -142,8 +144,8 @@ public class WrapperFactory implements IWrapperFactory
|
||||
"Chunk wrapper creation failed. \n" +
|
||||
"Expected parameters: \n");
|
||||
|
||||
// MC 1.18, 1.19, 1.20
|
||||
#if POST_MC_1_17_1
|
||||
// MC 1.16, 1.18, 1.19, 1.20
|
||||
#if POST_MC_1_17_1 || MC_1_16_5
|
||||
message.append("["+ChunkAccess.class.getName()+"], \n");
|
||||
message.append("["+LevelReader.class.getName()+"]. \n");
|
||||
#else
|
||||
|
||||
+60
-15
@@ -26,7 +26,6 @@ import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
@@ -36,7 +35,9 @@ import net.minecraft.core.Holder;
|
||||
import net.minecraft.data.worldgen.biome.EndBiomes;
|
||||
import net.minecraft.data.worldgen.biome.NetherBiomes;
|
||||
#endif
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
@@ -72,14 +73,7 @@ public class BiomeWrapper implements IBiomeWrapper
|
||||
return biome.unwrapKey().orElse(Biomes.THE_VOID).registry().toString();
|
||||
#endif
|
||||
}
|
||||
|
||||
@Override
|
||||
public String serialize(ILevelWrapper levelWrapper) {
|
||||
String data = Biome.CODEC.encodeStart(RegistryOps.create(JsonOps.INSTANCE, ((Level)levelWrapper.getWrappedMcObject()).registryAccess()),
|
||||
biome).get().orThrow().toString();
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@@ -93,19 +87,70 @@ public class BiomeWrapper implements IBiomeWrapper
|
||||
return Objects.hash(biome);
|
||||
}
|
||||
|
||||
public static IBiomeWrapper deserialize(String str, ILevelWrapper levelWrapper) throws IOException
|
||||
@Override
|
||||
public String serialize(ILevelWrapper levelWrapper) // FIXME pass in level to prevent null pointers (or maybe just RegistryAccess?)
|
||||
{
|
||||
|
||||
net.minecraft.core.RegistryAccess registryAccess = ((Level)levelWrapper.getWrappedMcObject()).registryAccess();
|
||||
|
||||
ResourceLocation resourceLocation;
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome);
|
||||
#elif MC_1_18_2 || MC_1_19_2
|
||||
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome.value());
|
||||
#else
|
||||
resourceLocation = registryAccess.registryOrThrow(Registries.BIOME).getKey(this.biome.value());
|
||||
#endif
|
||||
|
||||
if (resourceLocation == null)
|
||||
{
|
||||
// shouldn't normally happen, but just in case
|
||||
return "";
|
||||
}
|
||||
else
|
||||
{
|
||||
String resourceLocationString = resourceLocation.getNamespace()+":"+resourceLocation.getPath();
|
||||
return resourceLocationString;
|
||||
}
|
||||
}
|
||||
|
||||
public static IBiomeWrapper deserialize(String resourceLocationString, ILevelWrapper levelWrapper) throws IOException // FIXME pass in level to prevent null pointers (or maybe just RegistryAccess?)
|
||||
{
|
||||
if (resourceLocationString.trim().isEmpty() || resourceLocationString.equals(""))
|
||||
{
|
||||
// shouldn't normally happen, but just in case
|
||||
new ResourceLocation("minecraft", "the_void"); // just "void" in MC 1.12 through 1.9 (inclusive)
|
||||
}
|
||||
|
||||
|
||||
// parse the resource location
|
||||
int separatorIndex = resourceLocationString.indexOf(":");
|
||||
if (separatorIndex == -1)
|
||||
{
|
||||
throw new IOException("Unable to parse resource location string: ["+resourceLocationString+"].");
|
||||
}
|
||||
ResourceLocation resourceLocation = new ResourceLocation(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex+1));
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
#if PRE_MC_1_18_2 Biome #else
|
||||
Holder<Biome> #endif
|
||||
biome = Biome.CODEC.decode(RegistryOps.create(JsonOps.INSTANCE, ((Level)levelWrapper.getWrappedMcObject()).registryAccess()),
|
||||
JsonParser.parseString(str)).get().orThrow().getFirst();
|
||||
net.minecraft.core.RegistryAccess registryAccess = ((Level)levelWrapper.getWrappedMcObject()).registryAccess();
|
||||
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
Biome biome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
|
||||
#elif MC_1_18_2 || MC_1_19_2
|
||||
Biome unwrappedBiome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
|
||||
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
|
||||
#else
|
||||
Biome unwrappedBiome = registryAccess.registryOrThrow(Registries.BIOME).get(resourceLocation);
|
||||
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
|
||||
#endif
|
||||
|
||||
return getBiomeWrapper(biome);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new IOException("Failed to deserialize the string ["+str+"] into a BiomeWrapper: "+e.getMessage(), e);
|
||||
throw new IOException("Failed to deserialize the string ["+resourceLocationString+"] into a BiomeWrapper: "+e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+134
-17
@@ -1,29 +1,50 @@
|
||||
package com.seibel.distanthorizons.common.wrappers.block;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
import net.minecraft.client.resources.model.Material;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.EmptyBlockGetter;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
import net.minecraft.core.Registry;
|
||||
#elif MC_1_18_2 || MC_1_19_2
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
#else
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.world.level.EmptyBlockGetter;
|
||||
#endif
|
||||
|
||||
public class BlockStateWrapper implements IBlockStateWrapper
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
public static final BlockStateWrapper AIR = new BlockStateWrapper(null);
|
||||
/** example "minecraft:plains" */
|
||||
public static final String RESOURCE_LOCATION_SEPARATOR = ":";
|
||||
/** example "minecraft:water_state_{level:0}" */
|
||||
public static final String STATE_STRING_SEPARATOR = "_STATE_";
|
||||
|
||||
|
||||
// must be defined before AIR, otherwise a null pointer will be thrown
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
|
||||
public static final BlockStateWrapper AIR = new BlockStateWrapper(null);
|
||||
|
||||
|
||||
public static ConcurrentHashMap<BlockState, BlockStateWrapper> cache = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// constructors //
|
||||
//==============//
|
||||
@@ -72,34 +93,130 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
|
||||
|
||||
@Override
|
||||
public String serialize()
|
||||
public String serialize() // FIXME pass in level to prevent null pointers (or maybe just RegistryAccess?)
|
||||
{
|
||||
if (this.blockState == null)
|
||||
{
|
||||
return "AIR";
|
||||
}
|
||||
|
||||
return BlockState.CODEC.encodeStart(JsonOps.INSTANCE, this.blockState).get().orThrow().toString();
|
||||
ResourceLocation resourceLocation;
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
resourceLocation = Registry.BLOCK.getKey(this.blockState.getBlock());
|
||||
#elif MC_1_18_2 || MC_1_19_2
|
||||
net.minecraft.core.RegistryAccess registryAccess = Minecraft.getInstance().level.registryAccess();
|
||||
resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(this.blockState.getBlock());
|
||||
#else
|
||||
net.minecraft.core.RegistryAccess registryAccess = Minecraft.getInstance().level.registryAccess();
|
||||
resourceLocation = registryAccess.registryOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock());
|
||||
#endif
|
||||
|
||||
String resourceStateString = resourceLocation.getNamespace() + RESOURCE_LOCATION_SEPARATOR + resourceLocation.getPath()
|
||||
+ STATE_STRING_SEPARATOR + serializeBlockStateProperties(this.blockState);
|
||||
return resourceStateString;
|
||||
}
|
||||
|
||||
public static BlockStateWrapper deserialize(String str) throws IOException
|
||||
public static BlockStateWrapper deserialize(String resourceStateString) throws IOException // FIXME pass in level to prevent null pointers (or maybe just RegistryAccess?)
|
||||
{
|
||||
if (str.equals("AIR"))
|
||||
if (resourceStateString.equals("AIR") || resourceStateString.equals("")) // the empty string shouldn't normally happen, but just in case
|
||||
{
|
||||
return AIR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// parse the BlockState
|
||||
int stateSeparatorIndex = resourceStateString.indexOf(STATE_STRING_SEPARATOR);
|
||||
if (stateSeparatorIndex == -1)
|
||||
{
|
||||
throw new IOException("Unable to parse BlockState out of string: ["+resourceStateString+"].");
|
||||
}
|
||||
String blockStatePropertiesString = resourceStateString.substring(stateSeparatorIndex+STATE_STRING_SEPARATOR.length());
|
||||
resourceStateString = resourceStateString.substring(0, stateSeparatorIndex);
|
||||
|
||||
// parse the resource location
|
||||
int resourceSeparatorIndex = resourceStateString.indexOf(RESOURCE_LOCATION_SEPARATOR);
|
||||
if (resourceSeparatorIndex == -1)
|
||||
{
|
||||
throw new IOException("Unable to parse Resource Location out of string: ["+resourceStateString+"].");
|
||||
}
|
||||
ResourceLocation resourceLocation = new ResourceLocation(resourceStateString.substring(0, resourceSeparatorIndex), resourceStateString.substring(resourceSeparatorIndex+1));
|
||||
|
||||
|
||||
|
||||
// attempt to get the BlockState from all possible BlockStates
|
||||
try
|
||||
{
|
||||
return new BlockStateWrapper(
|
||||
BlockState.CODEC.decode(JsonOps.INSTANCE, JsonParser.parseString(str)).get().orThrow().getFirst()
|
||||
);
|
||||
Block block;
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
block = Registry.BLOCK.get(resourceLocation);
|
||||
#elif MC_1_18_2 || MC_1_19_2
|
||||
net.minecraft.core.RegistryAccess registryAccess = Minecraft.getInstance().level.registryAccess();
|
||||
block = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).get(resourceLocation);
|
||||
#else
|
||||
net.minecraft.core.RegistryAccess registryAccess = Minecraft.getInstance().level.registryAccess();
|
||||
block = registryAccess.registryOrThrow(Registries.BLOCK).get(resourceLocation);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
BlockState foundState = null;
|
||||
List<BlockState> possibleStateList = block.getStateDefinition().getPossibleStates();
|
||||
for (BlockState possibleState : possibleStateList)
|
||||
{
|
||||
String possibleStatePropertiesString = serializeBlockStateProperties(possibleState);
|
||||
if (possibleStatePropertiesString.equals(blockStatePropertiesString))
|
||||
{
|
||||
foundState = possibleState;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// use the default if no state was found
|
||||
if (foundState == null)
|
||||
{
|
||||
LOGGER.debug("Unable to find BlockState for Block ["+resourceLocation+"] with properties: ["+blockStatePropertiesString+"].");
|
||||
foundState = block.defaultBlockState();
|
||||
}
|
||||
return new BlockStateWrapper(foundState);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new IOException("Failed to deserialize the string ["+str+"] into a BlockStateWrapper: "+e.getMessage(), e);
|
||||
throw new IOException("Failed to deserialize the string ["+resourceStateString+"] into a BlockStateWrapper: "+e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** used to compare and save BlockStates based on their properties */
|
||||
private static String serializeBlockStateProperties(BlockState blockState)
|
||||
{
|
||||
// get the property list for this block (doesn't contain this block state's values, just the names and possible values)
|
||||
java.util.Collection<net.minecraft.world.level.block.state.properties.Property<?>> blockPropertyCollection = blockState.getProperties();
|
||||
|
||||
// alphabetically sort the list so they are always in the same order
|
||||
List<net.minecraft.world.level.block.state.properties.Property<?>> sortedBlockPropteryList = new ArrayList<>(blockPropertyCollection);
|
||||
sortedBlockPropteryList.sort((a,b) -> a.getName().compareTo(b.getName()));
|
||||
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (net.minecraft.world.level.block.state.properties.Property<?> property : sortedBlockPropteryList)
|
||||
{
|
||||
String propertyName = property.getName();
|
||||
|
||||
String value = "NULL";
|
||||
if (blockState.hasProperty(property))
|
||||
{
|
||||
value = blockState.getValue(property).toString();
|
||||
}
|
||||
|
||||
stringBuilder.append("{");
|
||||
stringBuilder.append(propertyName).append(RESOURCE_LOCATION_SEPARATOR).append(value);
|
||||
stringBuilder.append("}");
|
||||
}
|
||||
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
|
||||
+9
-1
@@ -21,7 +21,6 @@ package com.seibel.distanthorizons.common.wrappers.block;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.world.level.*;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
@@ -30,6 +29,10 @@ import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
#if POST_MC_1_18_2
|
||||
import net.minecraft.core.Holder;
|
||||
#endif
|
||||
|
||||
public class TintWithoutLevelOverrider implements BlockAndTintGetter {
|
||||
final BiomeWrapper biome;
|
||||
|
||||
@@ -70,6 +73,9 @@ public class TintWithoutLevelOverrider implements BlockAndTintGetter {
|
||||
public FluidState getFluidState(BlockPos pos) {
|
||||
throw new UnsupportedOperationException("ERROR: getFluidState() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||
}
|
||||
|
||||
|
||||
#if MC_1_17_1 || POST_MC_1_18_2
|
||||
@Override
|
||||
public int getHeight() {
|
||||
throw new UnsupportedOperationException("ERROR: getHeight() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||
@@ -78,4 +84,6 @@ public class TintWithoutLevelOverrider implements BlockAndTintGetter {
|
||||
public int getMinBuildHeight() {
|
||||
throw new UnsupportedOperationException("ERROR: getMinBuildHeight() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
+9
-1
@@ -21,7 +21,6 @@ package com.seibel.distanthorizons.common.wrappers.block;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.ColorResolver;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
@@ -31,6 +30,10 @@ import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
#if POST_MC_1_18_2
|
||||
import net.minecraft.core.Holder;
|
||||
#endif
|
||||
|
||||
public class TintWithoutLevelSmoothOverrider implements BlockAndTintGetter {
|
||||
final BiomeWrapper biome;
|
||||
public int smoothingRange;
|
||||
@@ -102,6 +105,9 @@ public class TintWithoutLevelSmoothOverrider implements BlockAndTintGetter {
|
||||
public FluidState getFluidState(BlockPos pos) {
|
||||
throw new UnsupportedOperationException("ERROR: getFluidState() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||
}
|
||||
|
||||
|
||||
#if MC_1_17_1 || POST_MC_1_18_2
|
||||
@Override
|
||||
public int getHeight() {
|
||||
throw new UnsupportedOperationException("ERROR: getHeight() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||
@@ -110,4 +116,6 @@ public class TintWithoutLevelSmoothOverrider implements BlockAndTintGetter {
|
||||
public int getMinBuildHeight() {
|
||||
throw new UnsupportedOperationException("ERROR: getMinBuildHeight() called on TintWithoutLevelOverrider. Object is for tinting only.");
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
+40
-27
@@ -74,18 +74,20 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
|
||||
private LinkedList<DhBlockPos> blockLightPosList = null;
|
||||
|
||||
private final boolean useDhLightingEngine;
|
||||
private boolean useDhLighting;
|
||||
|
||||
// Due to vanilla `isClientLightReady()` not designed to be used by non-render thread, that value may return 'true'
|
||||
// just before the light engine is ticked, (right after all light changes is marked to the engine to be processed).
|
||||
// To fix this, on client-only mode, we mixin-redirect the `isClientLightReady()` so that after the call, it will
|
||||
// trigger a synchronous update of this flag here on all chunks that are wrapped.
|
||||
//
|
||||
// Note: Using a static weak hash map to store the chunks that need to be updated, as instance of chunk wrapper
|
||||
// can be duplicated, with same chunk instance. And the data stored here are all temporary, and thus will not be
|
||||
// visible when a chunk is re-wrapped later.
|
||||
// (Also, thread safety done via a reader writer lock)
|
||||
private final static WeakHashMap<ChunkAccess, Boolean> chunksToUpdateClientLightReady = new WeakHashMap<>();
|
||||
/**
|
||||
* Due to vanilla `isClientLightReady()` not designed to be used by non-render thread, that value may return 'true'
|
||||
* just before the light engine is ticked, (right after all light changes is marked to the engine to be processed).
|
||||
* To fix this, on client-only mode, we mixin-redirect the `isClientLightReady()` so that after the call, it will
|
||||
* trigger a synchronous update of this flag here on all chunks that are wrapped. <br><br>
|
||||
*
|
||||
* Note: Using a static weak hash map to store the chunks that need to be updated, as instance of chunk wrapper
|
||||
* can be duplicated, with same chunk instance. And the data stored here are all temporary, and thus will not be
|
||||
* visible when a chunk is re-wrapped later. <br>
|
||||
* (Also, thread safety done via a reader writer lock)
|
||||
*/
|
||||
private final static WeakHashMap<ChunkAccess, Boolean> chunksToUpdateClientLightReady = new WeakHashMap<>(); // TODO this is never cleared
|
||||
private final static ReentrantReadWriteLock weakMapLock = new ReentrantReadWriteLock();
|
||||
|
||||
|
||||
@@ -103,7 +105,7 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
|
||||
// TODO is this the best way to differentiate between when we are generating chunks and when MC gave us a chunk?
|
||||
boolean isDhGeneratedChunk = (this.lightSource.getClass() == DhLitWorldGenRegion.class);
|
||||
this.useDhLightingEngine = isDhGeneratedChunk && (Config.Client.Advanced.WorldGenerator.worldGenLightingEngine.get() == ELightGenerationMode.DISTANT_HORIZONS);
|
||||
this.useDhLighting = isDhGeneratedChunk && (Config.Client.Advanced.WorldGenerator.worldGenLightingEngine.get() == ELightGenerationMode.DISTANT_HORIZONS);
|
||||
|
||||
weakMapLock.writeLock().lock();
|
||||
chunksToUpdateClientLightReady.put(chunk, false);
|
||||
@@ -153,16 +155,16 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
//if (wrappedLevel != null) return wrappedLevel.getBiome(new DhBlockPos(x + getMinX(), y, z + getMinZ()));
|
||||
|
||||
#if PRE_MC_1_17_1
|
||||
return BiomeWrapper.getBiomeWrapper(chunk.getBiomes().getNoiseBiome(
|
||||
x >> 2, y >> 2, z >> 2));
|
||||
return BiomeWrapper.getBiomeWrapper(this.chunk.getBiomes().getNoiseBiome(
|
||||
relX >> 2, relY >> 2, relZ >> 2));
|
||||
#elif PRE_MC_1_18_2
|
||||
return BiomeWrapper.getBiomeWrapper(chunk.getBiomes().getNoiseBiome(
|
||||
QuartPos.fromBlock(x), QuartPos.fromBlock(y), QuartPos.fromBlock(z)));
|
||||
return BiomeWrapper.getBiomeWrapper(this.chunk.getBiomes().getNoiseBiome(
|
||||
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)));
|
||||
#elif PRE_MC_1_18_2
|
||||
return BiomeWrapper.getBiomeWrapper(chunk.getNoiseBiome(
|
||||
QuartPos.fromBlock(x), QuartPos.fromBlock(y), QuartPos.fromBlock(z)));
|
||||
return BiomeWrapper.getBiomeWrapper(this.chunk.getNoiseBiome(
|
||||
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)));
|
||||
#else //Now returns a Holder<Biome> instead of Biome
|
||||
return BiomeWrapper.getBiomeWrapper(chunk.getNoiseBiome(
|
||||
return BiomeWrapper.getBiomeWrapper(this.chunk.getNoiseBiome(
|
||||
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)));
|
||||
#endif
|
||||
}
|
||||
@@ -187,10 +189,15 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
@Override
|
||||
public void setIsDhLightCorrect(boolean isDhLightCorrect) { this.isDhLightCorrect = isDhLightCorrect; }
|
||||
|
||||
@Override
|
||||
public void setUseDhLighting(boolean useDhLighting) { this.useDhLighting = useDhLighting; }
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isLightCorrect()
|
||||
{
|
||||
if (this.useDhLightingEngine)
|
||||
if (this.useDhLighting)
|
||||
{
|
||||
return this.isDhLightCorrect;
|
||||
}
|
||||
@@ -255,7 +262,7 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(relX, relY, relZ);
|
||||
|
||||
// use the full lighting engine when the chunks are within render distance or the config requests it
|
||||
if (this.useDhLightingEngine)
|
||||
if (this.useDhLighting)
|
||||
{
|
||||
// DH lighting method
|
||||
return this.blockLightAtRelBlockPos.getOrDefault(new DhBlockPos(relX, relY, relZ), 0);
|
||||
@@ -275,7 +282,7 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(relX, relY, relZ);
|
||||
|
||||
// use the full lighting engine when the chunks are within render distance or the config requests it
|
||||
if (this.useDhLightingEngine)
|
||||
if (this.useDhLighting)
|
||||
{
|
||||
// DH lighting method
|
||||
return this.skyLightAtRelBlockPos.getOrDefault(new DhBlockPos(relX, relY, relZ), 0);
|
||||
@@ -370,15 +377,20 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
#endif
|
||||
|
||||
// Should be called after client light updates are triggered.
|
||||
private static boolean updateClientLightReady(ChunkAccess chunk, boolean oldValue) {
|
||||
private static boolean updateClientLightReady(ChunkAccess chunk, boolean oldValue)
|
||||
{
|
||||
if (chunk instanceof LevelChunk && ((LevelChunk)chunk).getLevel() instanceof ClientLevel)
|
||||
{
|
||||
LevelChunk levelChunk = (LevelChunk)chunk;
|
||||
ClientChunkCache clientChunkCache = ((ClientLevel)levelChunk.getLevel()).getChunkSource();
|
||||
return clientChunkCache.getChunkForLighting(chunk.getPos().x, chunk.getPos().z) != null &&
|
||||
#if PRE_MC_1_20_1 levelChunk.isClientLightReady()
|
||||
#else checkLightSectionsOnChunk(levelChunk, levelChunk.getLevel().getLightEngine())
|
||||
#endif;
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
levelChunk.isLightCorrect();
|
||||
#elif PRE_MC_1_20_1
|
||||
levelChunk.isClientLightReady();
|
||||
#else
|
||||
checkLightSectionsOnChunk(levelChunk, levelChunk.getLevel().getLightEngine());
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -396,7 +408,8 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
{
|
||||
chunksToUpdateClientLightReady.replaceAll(ChunkWrapper::updateClientLightReady);
|
||||
}
|
||||
finally {
|
||||
finally
|
||||
{
|
||||
weakMapLock.writeLock().unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
+22
-5
@@ -285,6 +285,7 @@ public class ClassicConfigGUI
|
||||
widget.setValue(value -> Translatable(translationPrefix + "enum." + info.getType().getSimpleName() + "." + info.get().toString()));
|
||||
}
|
||||
this.list.addButton(MakeBtn(widget.getValue().apply(info.get()), this.width - 150 - ConfigScreenConfigs.SpaceFromRightScreen, 0, 150, 20, widget.getKey()), resetButton, null, name);
|
||||
return;
|
||||
} else if (((EntryInfo) info.guiValue).widget != null) {
|
||||
EditBox widget = new EditBox(font, this.width - 150 - ConfigScreenConfigs.SpaceFromRightScreen + 2, 0, 150 - 4, 20, null);
|
||||
widget.setMaxLength(150);
|
||||
@@ -292,18 +293,34 @@ public class ClassicConfigGUI
|
||||
Predicate<String> processor = ((BiFunction<EditBox, Button, Predicate<String>>) ((EntryInfo) info.guiValue).widget).apply(widget, doneButton);
|
||||
widget.setFilter(processor);
|
||||
this.list.addButton(widget, resetButton, null, name);
|
||||
return;
|
||||
}
|
||||
} else if (ConfigCategory.class.isAssignableFrom(info.getClass())) {
|
||||
}
|
||||
if (ConfigCategory.class.isAssignableFrom(info.getClass())) {
|
||||
Button widget = MakeBtn(name, this.width / 2 - 100, this.height - 28, 100 * 2, 20, (button -> {
|
||||
ConfigBase.INSTANCE.configFileINSTANCE.saveToFile();
|
||||
Objects.requireNonNull(minecraft).setScreen(ClassicConfigGUI.getScreen(this.configBase, this, ((ConfigCategory) info).getDestination()));
|
||||
}));
|
||||
this.list.addButton(widget, null, null, null);
|
||||
} else if (ConfigUIComment.class.isAssignableFrom(info.getClass())) {
|
||||
this.list.addButton(null, null, null, name);
|
||||
} else if (ConfigLinkedEntry.class.isAssignableFrom(info.getClass())) {
|
||||
this.addMenuItem(((ConfigLinkedEntry) info).get());
|
||||
return;
|
||||
}
|
||||
if (ConfigUIButton.class.isAssignableFrom(info.getClass())) {
|
||||
Button widget = MakeBtn(name, this.width / 2 - 100, this.height - 28, 100 * 2, 20, (button -> {
|
||||
((ConfigUIButton) info).runAction();
|
||||
}));
|
||||
this.list.addButton(widget, null, null, null);
|
||||
return;
|
||||
}
|
||||
if (ConfigUIComment.class.isAssignableFrom(info.getClass())) {
|
||||
this.list.addButton(null, null, null, name);
|
||||
return;
|
||||
}
|
||||
if (ConfigLinkedEntry.class.isAssignableFrom(info.getClass())) {
|
||||
this.addMenuItem(((ConfigLinkedEntry) info).get());
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.warn("Config ["+ info.getNameWCategory() +"] failed to show. Please try something like changing its type.");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+10
-6
@@ -25,13 +25,17 @@ public class GetConfigScreen
|
||||
// This shouldn't be here, but I need a way to test it after Minecraft inits its assets
|
||||
//System.out.println(ConfigBase.INSTANCE.generateLang(false, true));
|
||||
|
||||
return switch (useScreen)
|
||||
switch (useScreen)
|
||||
{
|
||||
case Classic -> ClassicConfigGUI.getScreen(ConfigBase.INSTANCE, parent, "client");
|
||||
case OpenGL -> MinecraftScreen.getScreen(parent, new OpenGLConfigScreen(), ModInfo.ID + ".title");
|
||||
case Classic:
|
||||
return ClassicConfigGUI.getScreen(ConfigBase.INSTANCE, parent, "client");
|
||||
case OpenGL: MinecraftScreen.getScreen(parent, new OpenGLConfigScreen(), ModInfo.ID + ".title");
|
||||
return null;
|
||||
// case JavaFX -> MinecraftScreen.getScreen(parent, new JavaScreenHandlerScreen(new JavaScreenHandlerScreen.ExampleScreen()), ModInfo.ID + ".title");
|
||||
case JavaFX -> MinecraftScreen.getScreen(parent, new JavaScreenHandlerScreen(new ConfigScreen()), ModInfo.ID + ".title");
|
||||
default -> null;
|
||||
};
|
||||
case JavaFX:
|
||||
return MinecraftScreen.getScreen(parent, new JavaScreenHandlerScreen(new ConfigScreen()), ModInfo.ID + ".title");
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -22,10 +22,16 @@ package com.seibel.distanthorizons.common.wrappers.gui;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.gui.components.ImageButton;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
#if PRE_MC_1_17_1
|
||||
import net.minecraft.client.Minecraft;
|
||||
#else
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Creates a button with a texture on it
|
||||
*/
|
||||
|
||||
+23
-13
@@ -9,19 +9,22 @@ import com.seibel.distanthorizons.core.jar.installer.MarkdownFormatter;
|
||||
import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.components.AbstractWidget;
|
||||
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
#if POST_MC_1_17_1
|
||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||
#endif
|
||||
|
||||
#if PRE_MC_1_20_1
|
||||
import net.minecraft.client.gui.GuiComponent;
|
||||
#else
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
#endif
|
||||
import net.minecraft.client.gui.components.AbstractWidget;
|
||||
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
#if PRE_MC_1_19_2
|
||||
#endif
|
||||
|
||||
|
||||
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.*;
|
||||
|
||||
@@ -69,10 +72,10 @@ public class ChangelogScreen extends DhScreen {
|
||||
this.changelog.add("");
|
||||
|
||||
// Get the release changelog and split it by the new lines
|
||||
List<String> unwrappedChangelog =
|
||||
List.of(new MarkdownFormatter.MinecraftFormat().convertTo( // This formats markdown to minecraft's "§" characters
|
||||
String[] unwrappedChangelog = // Arrays.asList could be used if a list object is desired here vs List.of which is only available for Java 9+
|
||||
new MarkdownFormatter.MinecraftFormat().convertTo( // This formats markdown to minecraft's "§" characters
|
||||
ModrinthGetter.changeLogs.get(versionID)
|
||||
).split("\\n"));
|
||||
).split("\\n");
|
||||
// Makes the words wrap around to not go off the screen
|
||||
for (String str: unwrappedChangelog) {
|
||||
this.changelog.addAll(
|
||||
@@ -116,7 +119,13 @@ public class ChangelogScreen extends DhScreen {
|
||||
|
||||
// Set the scroll position to the mouse height relative to the screen
|
||||
// This is a bit of a hack as we cannot scroll on this area
|
||||
this.changelogArea.scrollAmount = ((double) mouseY)/((double) this.height) * 1.1 * this.changelogArea.getMaxScroll();
|
||||
double scrollAmount = ((double) mouseY)/((double) this.height) * 1.1 * this.changelogArea.getMaxScroll();
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
this.changelogArea.setScrollAmount(scrollAmount);
|
||||
#else
|
||||
this.changelogArea.scrollAmount = scrollAmount;
|
||||
#endif
|
||||
|
||||
|
||||
this.changelogArea.render(matrices, mouseX, mouseY, delta); // Render the changelog
|
||||
|
||||
@@ -149,7 +158,8 @@ public class ChangelogScreen extends DhScreen {
|
||||
}
|
||||
}
|
||||
|
||||
public static class ButtonEntry extends ContainerObjectSelectionList.Entry<ButtonEntry> {
|
||||
public static class ButtonEntry extends ContainerObjectSelectionList.Entry<ButtonEntry>
|
||||
{
|
||||
private static final Font textRenderer = Minecraft.getInstance().font;
|
||||
private final Component text;
|
||||
private final List<AbstractWidget> children = new ArrayList<>();
|
||||
|
||||
-5
@@ -326,11 +326,6 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
||||
#endif
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryDisableVanillaFog() {
|
||||
return true; // Handled via MixinFogRenderer in both forge and fabric
|
||||
}
|
||||
|
||||
public void updateLightmap(NativeImage lightPixels) {
|
||||
if (lightmap== null) {
|
||||
lightmap = new LightMapWrapper();
|
||||
|
||||
+10
-5
@@ -374,16 +374,17 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
||||
|
||||
public ChunkAccess loadOrMakeChunk(ChunkPos chunkPos, WorldGenLevelLightEngine lightEngine)
|
||||
{
|
||||
ServerLevel level = params.level;
|
||||
|
||||
ServerLevel level = this.params.level;
|
||||
|
||||
CompoundTag chunkData = null;
|
||||
try
|
||||
{
|
||||
// Warning: if multiple threads attempt to access this method at the same time,
|
||||
// it can throw EOFExceptions that are caught and logged by Minecraft
|
||||
//chunkData = level.getChunkSource().chunkMap.readChunk(chunkPos);
|
||||
RegionFileStorage storage = params.level.getChunkSource().chunkMap.worker.storage;
|
||||
RegionFileStorageExternalCache cache = getOrCreateRegionFileCache(storage);
|
||||
|
||||
RegionFileStorage storage = this.params.level.getChunkSource().chunkMap.worker.storage;
|
||||
RegionFileStorageExternalCache cache = this.getOrCreateRegionFileCache(storage);
|
||||
chunkData = cache.read(chunkPos);
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -499,7 +500,11 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
||||
ChunkAccess target = wrappedChunk.getChunk();
|
||||
if (target instanceof LevelChunk)
|
||||
{
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
((LevelChunk) target).setLoaded(true);
|
||||
#else
|
||||
((LevelChunk) target).loaded = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!wrappedChunk.isLightCorrect())
|
||||
@@ -692,7 +697,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
||||
}
|
||||
|
||||
// clear the chunk cache
|
||||
var regionStorage = this.regionFileStorageCacheRef.get();
|
||||
RegionFileStorageExternalCache regionStorage = this.regionFileStorageCacheRef.get();
|
||||
if (regionStorage != null)
|
||||
{
|
||||
try
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ public final class ThreadedParameters
|
||||
}
|
||||
|
||||
|
||||
#if PRE_MC_1_19_2
|
||||
#if POST_MC_1_18_2 && PRE_MC_1_19_2
|
||||
public void recreateStructureCheck()
|
||||
{
|
||||
if (previousGlobalParameters != null)
|
||||
|
||||
+35
-16
@@ -14,23 +14,28 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class RegionFileStorageExternalCache implements AutoCloseable {
|
||||
public class RegionFileStorageExternalCache implements AutoCloseable
|
||||
{
|
||||
public final RegionFileStorage storage;
|
||||
public static final int MAX_CACHE_SIZE = 16;
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
public void close() throws IOException
|
||||
{
|
||||
RegionFileCache cache;
|
||||
while ((cache = regionFileCache.poll()) != null) {
|
||||
while ((cache = this.regionFileCache.poll()) != null)
|
||||
{
|
||||
cache.file.close();
|
||||
}
|
||||
}
|
||||
|
||||
static class RegionFileCache {
|
||||
static class RegionFileCache
|
||||
{
|
||||
public final long pos;
|
||||
public final RegionFile file;
|
||||
|
||||
public RegionFileCache(long pos, RegionFile file) {
|
||||
public RegionFileCache(long pos, RegionFile file)
|
||||
{
|
||||
this.pos = pos;
|
||||
this.file = file;
|
||||
}
|
||||
@@ -38,9 +43,7 @@ public class RegionFileStorageExternalCache implements AutoCloseable {
|
||||
|
||||
public ConcurrentLinkedQueue<RegionFileCache> regionFileCache = new ConcurrentLinkedQueue<>();
|
||||
|
||||
public RegionFileStorageExternalCache(RegionFileStorage storage) {
|
||||
this.storage = storage;
|
||||
}
|
||||
public RegionFileStorageExternalCache(RegionFileStorage storage) { this.storage = storage; }
|
||||
|
||||
@Nullable
|
||||
public RegionFile getRegionFile(ChunkPos pos) throws IOException
|
||||
@@ -53,7 +56,12 @@ public class RegionFileStorageExternalCache implements AutoCloseable {
|
||||
{
|
||||
try
|
||||
{
|
||||
rFile = this.storage.regionCache.getOrDefault(posLong, null);
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
rFile = this.storage.getRegionFile(pos);
|
||||
#else
|
||||
rFile = this.storage.regionCache.getOrDefault(posLong, null);
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e)
|
||||
@@ -77,18 +85,29 @@ public class RegionFileStorageExternalCache implements AutoCloseable {
|
||||
}
|
||||
|
||||
// Otherwise, check if file exist, and if so, add it to the cache
|
||||
Path p = storage.folder;
|
||||
if (!Files.exists(p))
|
||||
Path storageFolderPath;
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
storageFolderPath = this.storage.folder.toPath();
|
||||
#else
|
||||
storageFolderPath = this.storage.folder;
|
||||
#endif
|
||||
|
||||
if (!Files.exists(storageFolderPath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Path rFilePath = p.resolve("r." + pos.getRegionX() + "." + pos.getRegionZ() + ".mca");
|
||||
rFile = new RegionFile(rFilePath, p, false);
|
||||
regionFileCache.add(new RegionFileCache(ChunkPos.asLong(pos.getRegionX(), pos.getRegionZ()), rFile));
|
||||
while (regionFileCache.size() > MAX_CACHE_SIZE)
|
||||
Path regionFilePath = storageFolderPath.resolve("r." + pos.getRegionX() + "." + pos.getRegionZ() + ".mca");
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
rFile = new RegionFile(regionFilePath.toFile(), storageFolderPath.toFile(), false);
|
||||
#else
|
||||
rFile = new RegionFile(regionFilePath, storageFolderPath, false);
|
||||
#endif
|
||||
|
||||
this.regionFileCache.add(new RegionFileCache(ChunkPos.asLong(pos.getRegionX(), pos.getRegionZ()), rFile));
|
||||
while (this.regionFileCache.size() > MAX_CACHE_SIZE)
|
||||
{
|
||||
regionFileCache.poll().file.close();
|
||||
this.regionFileCache.poll().file.close();
|
||||
}
|
||||
|
||||
return rFile;
|
||||
|
||||
+9
-5
@@ -50,13 +50,17 @@ import net.minecraft.world.level.StructureManager;
|
||||
#if POST_MC_1_18_2
|
||||
import net.minecraft.world.level.levelgen.structure.StructureCheck;
|
||||
#endif
|
||||
|
||||
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
||||
|
||||
#if PRE_MC_1_19_2
|
||||
public class WorldGenStructFeatManager extends StructureFeatureManager {
|
||||
#else
|
||||
public class WorldGenStructFeatManager extends StructureManager {
|
||||
#endif
|
||||
#if PRE_MC_1_18_2
|
||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
public class WorldGenStructFeatManager extends #if PRE_MC_1_19_2 StructureFeatureManager #else StructureManager #endif
|
||||
{
|
||||
final WorldGenLevel genLevel;
|
||||
|
||||
#if PRE_MC_1_19_4
|
||||
|
||||
+4
@@ -29,7 +29,11 @@ import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||
#if PRE_MC_1_17_1
|
||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||
#else
|
||||
import net.minecraft.world.level.lighting.LightEventListener;
|
||||
#endif
|
||||
|
||||
public final class StepLight {
|
||||
/**
|
||||
|
||||
@@ -35,6 +35,10 @@ accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSecti
|
||||
# lod generation from save file
|
||||
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
||||
accessible method net/minecraft/server/level/ChunkMap readChunk (Lnet/minecraft/world/level/ChunkPos;)Lnet/minecraft/nbt/CompoundTag;
|
||||
accessible method net/minecraft/world/level/chunk/storage/RegionFileStorage getRegionFile (Lnet/minecraft/world/level/ChunkPos;)Lnet/minecraft/world/level/chunk/storage/RegionFile;
|
||||
accessible field net/minecraft/world/level/chunk/storage/RegionFileStorage folder Ljava/io/File;
|
||||
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
||||
accessible field net/minecraft/world/level/chunk/storage/IOWorker storage Lnet/minecraft/world/level/chunk/storage/RegionFileStorage;
|
||||
|
||||
# grabbing textures
|
||||
accessible field net/minecraft/client/renderer/block/model/BakedQuad sprite Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;
|
||||
|
||||
@@ -35,7 +35,10 @@ accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSecti
|
||||
# lod generation from save file
|
||||
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
||||
accessible method net/minecraft/server/level/ChunkMap readChunk (Lnet/minecraft/world/level/ChunkPos;)Lnet/minecraft/nbt/CompoundTag;
|
||||
|
||||
accessible method net/minecraft/world/level/chunk/storage/RegionFileStorage getRegionFile (Lnet/minecraft/world/level/ChunkPos;)Lnet/minecraft/world/level/chunk/storage/RegionFile;
|
||||
accessible field net/minecraft/world/level/chunk/storage/RegionFileStorage folder Ljava/io/File;
|
||||
accessible field net/minecraft/world/level/chunk/storage/ChunkStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
||||
accessible field net/minecraft/world/level/chunk/storage/IOWorker storage Lnet/minecraft/world/level/chunk/storage/RegionFileStorage;
|
||||
|
||||
# grabbing textures
|
||||
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite animatedTexture Lnet/minecraft/client/renderer/texture/TextureAtlasSprite$AnimatedTexture;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"git_main_commit": "${git_main_commit}",
|
||||
"git_core_commit": "${git_core_commit}",
|
||||
"git_main_branch": "${git_main_branch}"
|
||||
}
|
||||
+1
-1
Submodule coreSubProjects updated: 6bf32ff85c...52f9e3e9e4
+5
-5
@@ -76,11 +76,11 @@ dependencies {
|
||||
|
||||
// Sodium
|
||||
addMod("maven.modrinth:sodium:${rootProject.sodium_version}", rootProject.enable_sodium)
|
||||
// if (rootProject.enable_sodium != "0") {
|
||||
// implementation "org.joml:joml:1.10.2"
|
||||
// modImplementation(fabricApi.module("fabric-rendering-data-attachment-v1", rootProject.fabric_api_version))
|
||||
// modImplementation(fabricApi.module("fabric-rendering-fluids-v1", rootProject.fabric_api_version))
|
||||
// }
|
||||
if (rootProject.enable_sodium == "2") {
|
||||
implementation "org.joml:joml:1.10.2"
|
||||
modImplementation(fabricApi.module("fabric-rendering-data-attachment-v1", rootProject.fabric_api_version))
|
||||
modImplementation(fabricApi.module("fabric-rendering-fluids-v1", rootProject.fabric_api_version))
|
||||
}
|
||||
|
||||
// Lithium
|
||||
addMod("maven.modrinth:lithium:${rootProject.lithium_version}", rootProject.enable_lithium)
|
||||
|
||||
@@ -62,6 +62,7 @@ import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
|
||||
/**
|
||||
* This handles all events sent to the client,
|
||||
@@ -211,7 +212,9 @@ public class FabricClientProxy
|
||||
{
|
||||
float[] matrixFloatArray = SeamlessOverdraw.overwriteMinecraftNearFarClipPlanes(renderContext.projectionMatrix(), renderContext.tickDelta());
|
||||
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_1_16_5
|
||||
SeamlessOverdraw.applyLegacyProjectionMatrix(matrixFloatArray);
|
||||
#elif PRE_MC_1_19_4
|
||||
renderContext.projectionMatrix().load(FloatBuffer.wrap(matrixFloatArray));
|
||||
#else
|
||||
renderContext.projectionMatrix().set(matrixFloatArray);
|
||||
|
||||
@@ -22,6 +22,7 @@ package com.seibel.distanthorizons.fabric;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeDhInitEvent;
|
||||
import com.seibel.distanthorizons.core.config.ConfigBase;
|
||||
import com.seibel.distanthorizons.core.jar.ModGitInfo;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.*;
|
||||
import com.seibel.distanthorizons.common.LodCommonMain;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
@@ -72,6 +73,11 @@ public class FabricMain
|
||||
FabricDependencySetup.createInitialBindings();
|
||||
LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
|
||||
|
||||
// Print git info (Useful for dev builds)
|
||||
LOGGER.info("DH Branch: "+ ModGitInfo.Git_Main_Branch);
|
||||
LOGGER.info("DH Commit: "+ ModGitInfo.Git_Main_Commit);
|
||||
LOGGER.info("DH-Core Commit: "+ ModGitInfo.Git_Core_Commit);
|
||||
|
||||
if (SingletonInjector.INSTANCE.get(IModChecker.class).isModLoaded("sodium")) {
|
||||
ModAccessorInjector.INSTANCE.bind(ISodiumAccessor.class, new SodiumAccessor());
|
||||
}
|
||||
|
||||
+20
-22
@@ -17,16 +17,6 @@ public class MixinGameRenderer
|
||||
|
||||
|
||||
#if POST_MC_1_17_1
|
||||
@Inject(method = "shutdownShaders", at = @At("HEAD"))
|
||||
public void onShutdownShaders(CallbackInfo ci) {
|
||||
LOGGER.info("Shutting down renderer (fabric)");
|
||||
if (!DependencySetupDoneCheck.isDone) {
|
||||
LOGGER.warn("Dependency setup is not done yet, skipping renderer this shutdown event!");
|
||||
return;
|
||||
}
|
||||
ClientApi.INSTANCE.rendererShutdownEvent();
|
||||
}
|
||||
|
||||
// FIXME: This I think will dup multiple renderStartupEvent calls...
|
||||
@Inject(method = {"reloadShaders", "preloadUiShader"}, at = @At("TAIL"))
|
||||
public void onStartupShaders(CallbackInfo ci) {
|
||||
@@ -37,20 +27,28 @@ public class MixinGameRenderer
|
||||
}
|
||||
ClientApi.INSTANCE.rendererStartupEvent();
|
||||
}
|
||||
#else
|
||||
// FIXME: on 1.16 we dont have stuff for reloading/shutting down shaders
|
||||
|
||||
@Inject(method = "shutdownShaders", at = @At("HEAD"))
|
||||
|
||||
@Inject(method = "shutdownShaders", at = @At("HEAD"))
|
||||
public void onShutdownShaders(CallbackInfo ci) {
|
||||
LOGGER.info("Shutting down renderer");
|
||||
LOGGER.info("Shutting down renderer (fabric)");
|
||||
if (!DependencySetupDoneCheck.isDone) {
|
||||
LOGGER.warn("Dependency setup is not done yet, skipping renderer this shutdown event!");
|
||||
return;
|
||||
}
|
||||
ClientApi.INSTANCE.rendererShutdownEvent();
|
||||
}
|
||||
|
||||
// FIXME: This I think will dup multiple renderStartupEvent calls...
|
||||
@Inject(method = {"reloadShaders", "preloadUiShader", "preloadShader"}, at = @At("TAIL"))
|
||||
public void onStartupShaders(CallbackInfo ci) {
|
||||
LOGGER.info("Starting up renderer");
|
||||
ClientApi.INSTANCE.rendererStartupEvent();
|
||||
}
|
||||
#else
|
||||
// FIXME: on 1.16 we dont have stuff for reloading/shutting down shaders
|
||||
|
||||
// FIXME: This I think will dup multiple renderStartupEvent calls...
|
||||
@Inject(method = {"loadEffect"}, at = @At("TAIL"))
|
||||
public void onStartupShaders(CallbackInfo ci) {
|
||||
ClientApi.INSTANCE.rendererStartupEvent();
|
||||
}
|
||||
|
||||
@Inject(method = "shutdownEffect", at = @At("HEAD"))
|
||||
public void onShutdownShaders(CallbackInfo ci) {
|
||||
ClientApi.INSTANCE.rendererShutdownEvent();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
+4
-3
@@ -96,10 +96,11 @@ public class MixinLevelRenderer
|
||||
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
|
||||
#endif
|
||||
{
|
||||
if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
||||
// FIXME completely disables rendering when sodium is installed
|
||||
if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
||||
{
|
||||
callback.cancel();
|
||||
}
|
||||
callback.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(method =
|
||||
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
package com.seibel.distanthorizons.fabric.mixins.mods.sodium;
|
||||
|
||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
||||
import com.seibel.distanthorizons.fabric.wrappers.modAccessor.SodiumAccessor;
|
||||
import me.jellysquid.mods.sodium.client.gl.device.CommandList;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.ChunkCameraContext;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.ChunkRenderList;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.ChunkRenderMatrices;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.RegionChunkRenderer;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.passes.BlockRenderPass;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(RegionChunkRenderer.class)
|
||||
public class MixinSodiumChunkRenderer {
|
||||
@Unique SodiumAccessor accessor = null;
|
||||
@Inject(remap = false, method = "render", at = @At(value = "INVOKE", target = "Lme/jellysquid/mods/sodium/client/render/chunk/ShaderChunkRenderer;begin(Lme/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPass;)V", shift = At.Shift.AFTER))
|
||||
private void injectDHLoDRendering(ChunkRenderMatrices matrices, CommandList commandList, ChunkRenderList list, BlockRenderPass pass, ChunkCameraContext camera, CallbackInfo ci) {
|
||||
if (accessor == null) {
|
||||
accessor = (SodiumAccessor)ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class);
|
||||
}
|
||||
if (pass.equals(BlockRenderPass.SOLID)) {
|
||||
//TODO: use matrices.modelView() and matrices.projection() instead of
|
||||
// SodiumAccessor.mcModelViewMatrix,
|
||||
// SodiumAccessor.mcProjectionMatrix,
|
||||
ClientApi.INSTANCE.renderLods(accessor.levelWrapper,
|
||||
accessor.mcModelViewMatrix,
|
||||
accessor.mcProjectionMatrix,
|
||||
accessor.partialTicks);
|
||||
}
|
||||
}
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
package com.seibel.distanthorizons.fabric.mixins.mods.sodium;
|
||||
|
||||
#if POST_MC_1_20_1
|
||||
// Sodium 0.5
|
||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
||||
import com.seibel.distanthorizons.fabric.wrappers.modAccessor.SodiumAccessor;
|
||||
import me.jellysquid.mods.sodium.client.gl.device.CommandList;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.ChunkCameraContext;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.ChunkRenderMatrices;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.RegionChunkRenderer;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.lists.SortedRenderLists;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.region.RenderRegionManager;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.terrain.DefaultTerrainRenderPasses;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.terrain.TerrainRenderPass;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(RegionChunkRenderer.class)
|
||||
public class MixinSodiumRenderer
|
||||
{
|
||||
@Unique SodiumAccessor accessor = null;
|
||||
|
||||
@Inject(remap = false, method = "render", at = @At(value = "INVOKE", target = "Lme/jellysquid/mods/sodium/client/render/chunk/ShaderChunkRenderer;begin(Lme/jellysquid/mods/sodium/client/render/chunk/terrain/TerrainRenderPass;)V", shift = At.Shift.AFTER))
|
||||
private void injectDHLoDRendering(ChunkRenderMatrices matrices, CommandList commandList, RenderRegionManager regions, SortedRenderLists renderLists, TerrainRenderPass renderPass, ChunkCameraContext camera, CallbackInfo ci)
|
||||
{
|
||||
if (accessor == null)
|
||||
{
|
||||
accessor = (SodiumAccessor)ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class);
|
||||
}
|
||||
|
||||
if (renderPass.equals(DefaultTerrainRenderPasses.SOLID))
|
||||
{
|
||||
//TODO: use matrices.modelView() and matrices.projection() instead of
|
||||
// SodiumAccessor.mcModelViewMatrix,
|
||||
// SodiumAccessor.mcProjectionMatrix,
|
||||
ClientApi.INSTANCE.renderLods(accessor.levelWrapper,
|
||||
accessor.mcModelViewMatrix,
|
||||
accessor.mcProjectionMatrix,
|
||||
accessor.partialTicks);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#elif POST_MC_1_17_1
|
||||
// Sodium 0.3 to 0.4
|
||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
||||
import com.seibel.distanthorizons.fabric.wrappers.modAccessor.SodiumAccessor;
|
||||
import me.jellysquid.mods.sodium.client.gl.device.CommandList;
|
||||
import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.ChunkCameraContext;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.ChunkRenderList;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.ChunkRenderMatrices;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.RegionChunkRenderer;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.passes.BlockRenderPass;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(RegionChunkRenderer.class)
|
||||
public class MixinSodiumRenderer
|
||||
{
|
||||
@Unique SodiumAccessor accessor = null;
|
||||
|
||||
@Inject(remap = false, method = "render", at = @At(value = "INVOKE", target = "Lme/jellysquid/mods/sodium/client/render/chunk/ShaderChunkRenderer;begin(Lme/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPass;)V", shift = At.Shift.AFTER))
|
||||
private void injectDHLoDRendering(ChunkRenderMatrices matrices, CommandList commandList, ChunkRenderList list, BlockRenderPass pass, ChunkCameraContext camera, CallbackInfo ci)
|
||||
{
|
||||
if (accessor == null)
|
||||
{
|
||||
accessor = (SodiumAccessor)ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class);
|
||||
}
|
||||
|
||||
if (pass.equals(BlockRenderPass.SOLID))
|
||||
{
|
||||
//TODO: use matrices.modelView() and matrices.projection() instead of
|
||||
// SodiumAccessor.mcModelViewMatrix,
|
||||
// SodiumAccessor.mcProjectionMatrix,
|
||||
ClientApi.INSTANCE.renderLods(accessor.levelWrapper,
|
||||
accessor.mcModelViewMatrix,
|
||||
accessor.mcProjectionMatrix,
|
||||
accessor.partialTicks);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#else
|
||||
// Sodium 0.2 and under
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
||||
import com.seibel.distanthorizons.fabric.wrappers.modAccessor.SodiumAccessor;
|
||||
import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(SodiumWorldRenderer.class)
|
||||
public class MixinSodiumRenderer
|
||||
{
|
||||
@Unique SodiumAccessor accessor = null;
|
||||
|
||||
@Inject(method="drawChunkLayer", remap = false, at = @At("HEAD"))
|
||||
private void drawChunkLayer(RenderType renderLayer, PoseStack matrixStack, double x, double y, double z, CallbackInfo callback)
|
||||
{
|
||||
if (this.accessor == null)
|
||||
{
|
||||
this.accessor = (SodiumAccessor) ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class);
|
||||
}
|
||||
|
||||
if (renderLayer == RenderType.solid())
|
||||
{
|
||||
ClientApi.INSTANCE.renderLods(this.accessor.levelWrapper,
|
||||
this.accessor.mcModelViewMatrix,
|
||||
this.accessor.mcProjectionMatrix,
|
||||
this.accessor.partialTicks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+11
-1
@@ -28,7 +28,17 @@ public class MixinChunkMap {
|
||||
ServerLevel level;
|
||||
|
||||
@Inject(method = "save", at = @At(value = "INVOKE", target = CHUNK_SERIALIZER_WRITE))
|
||||
private void onChunkSave(ChunkAccess chunk, CallbackInfoReturnable<Boolean> ci) {
|
||||
private void onChunkSave(ChunkAccess chunk, CallbackInfoReturnable<Boolean> ci)
|
||||
{
|
||||
#if MC_1_16_5
|
||||
if (chunk.getBiomes() == null)
|
||||
{
|
||||
// in 1.16.5 some chunks may be missing their biomes, which cause issues when attempting to save them
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
ServerApi.INSTANCE.serverChunkSaveEvent(
|
||||
new ChunkWrapper(chunk, level, ServerLevelWrapper.getWrapper(level)),
|
||||
ServerLevelWrapper.getWrapper(level)
|
||||
|
||||
+5
-1
@@ -35,6 +35,7 @@ import java.util.concurrent.Semaphore;
|
||||
|
||||
/**
|
||||
* Why does this exist? But okay! (Will be probably removed when the experimental generator is done)
|
||||
* FIXME: Recheck this
|
||||
*/
|
||||
@Mixin(ThreadingDetector.class)
|
||||
public class MixinThreadingDetector {
|
||||
@@ -48,6 +49,9 @@ public class MixinThreadingDetector {
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
|
||||
@Mixin(ServerLevel.class)
|
||||
public class MixinThreadingDectector {} //FIXME: Is there some way to make this file just not be added?
|
||||
public class MixinThreadingDetector { } //FIXME: Is there some way to make this file just not be added?
|
||||
#endif
|
||||
|
||||
+11
-7
@@ -1,7 +1,8 @@
|
||||
package com.seibel.distanthorizons.fabric.wrappers.modAccessor;
|
||||
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IBCLibAccessor;
|
||||
#if PRE_MC_1_19_2
|
||||
#if MC_1_16_5
|
||||
#elif PRE_MC_1_19_2
|
||||
import ru.bclib.config.ClientConfig;
|
||||
import ru.bclib.config.Configs;
|
||||
#else
|
||||
@@ -9,15 +10,18 @@ import org.betterx.bclib.config.ClientConfig;
|
||||
import org.betterx.bclib.config.Configs;
|
||||
#endif
|
||||
|
||||
public class BCLibAccessor implements IBCLibAccessor {
|
||||
public class BCLibAccessor implements IBCLibAccessor
|
||||
{
|
||||
@Override
|
||||
public String getModName() {
|
||||
return "BCLib";
|
||||
}
|
||||
public String getModName() { return "BCLib"; }
|
||||
|
||||
public void setRenderCustomFog(boolean newValue) {
|
||||
// Change the value of CUSTOM_FOG_RENDERING in the bclib client config
|
||||
public void setRenderCustomFog(boolean newValue)
|
||||
{
|
||||
#if MC_1_16_5 || MC_1_17_1
|
||||
#elif PRE_MC_1_19_2
|
||||
// Change the value of CUSTOM_FOG_RENDERING in the bclib client config
|
||||
// This disabled fog from rendering within bclib
|
||||
Configs.CLIENT_CONFIG.set(ClientConfig.CUSTOM_FOG_RENDERING, newValue);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
+11
-4
@@ -64,7 +64,14 @@ public class SodiumAccessor implements ISodiumAccessor {
|
||||
SodiumWorldRenderer renderer = SodiumWorldRenderer.instance();
|
||||
LevelHeightAccessor height = Minecraft.getInstance().level;
|
||||
|
||||
#if POST_MC_1_18_2
|
||||
#if POST_MC_1_20_1
|
||||
// TODO: This is just a tmp solution, use a proper solution later
|
||||
return MC_RENDER.getMaximumRenderedChunks().stream().filter((DhChunkPos chunk) -> {
|
||||
return (renderer.isBoxVisible(
|
||||
chunk.getMinBlockX()+1, height.getMinBuildHeight()+1, chunk.getMinBlockZ()+1,
|
||||
chunk.getMinBlockX()+15, height.getMaxBuildHeight()-1, chunk.getMinBlockZ()+15));
|
||||
}).collect(Collectors.toCollection(HashSet::new));
|
||||
#elif POST_MC_1_18_2
|
||||
// 0b11 = Lighted chunk & loaded chunk
|
||||
return renderer.getChunkTracker().getChunks(0b00).filter(
|
||||
(long l) -> {
|
||||
@@ -72,7 +79,7 @@ public class SodiumAccessor implements ISodiumAccessor {
|
||||
}).mapToObj(DhChunkPos::new).collect(Collectors.toCollection(HashSet::new));
|
||||
#else
|
||||
// TODO: Maybe use a mixin to make this more efficient, and maybe ignore changes behind the camera
|
||||
return MC_RENDER.getMaximumRenderedChunks().stream().filter((DHChunkPos chunk) -> {
|
||||
return MC_RENDER.getMaximumRenderedChunks().stream().filter((DhChunkPos chunk) -> {
|
||||
return (renderer.isBoxVisible(
|
||||
chunk.getMinBlockX()+1, height.getMinBuildHeight()+1, chunk.getMinBlockZ()+1,
|
||||
chunk.getMinBlockX()+15, height.getMaxBuildHeight()-1, chunk.getMinBlockZ()+15));
|
||||
@@ -81,11 +88,11 @@ public class SodiumAccessor implements ISodiumAccessor {
|
||||
}
|
||||
#else
|
||||
@Override
|
||||
public HashSet<DHChunkPos> getNormalRenderedChunks() {
|
||||
public HashSet<DhChunkPos> getNormalRenderedChunks() {
|
||||
SodiumWorldRenderer renderer = SodiumWorldRenderer.getInstance();
|
||||
LevelAccessor height = Minecraft.getInstance().level;
|
||||
// TODO: Maybe use a mixin to make this more efficient
|
||||
return MC_RENDER.getMaximumRenderedChunks().stream().filter((DHChunkPos chunk) -> {
|
||||
return MC_RENDER.getMaximumRenderedChunks().stream().filter((DhChunkPos chunk) -> {
|
||||
FakeChunkEntity AABB = new FakeChunkEntity(chunk.getX(), chunk.getZ(), height.getMaxBuildHeight());
|
||||
return (renderer.isEntityVisible(AABB));
|
||||
}).collect(Collectors.toCollection(HashSet::new));
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"client.MixinMinecraft",
|
||||
"client.MixinTextureUtil",
|
||||
|
||||
"mods.sodium.MixinSodiumChunkRenderer"
|
||||
"mods.sodium.MixinSodiumRenderer"
|
||||
],
|
||||
"server": [],
|
||||
"injectors": {
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.seibel.distanthorizons.common.forge.LodForgeMethodCaller;
|
||||
import com.seibel.distanthorizons.common.wrappers.DependencySetup;
|
||||
import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.jar.ModGitInfo;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import com.seibel.distanthorizons.core.ReflectionHandler;
|
||||
@@ -112,6 +113,11 @@ public class ForgeMain implements LodForgeMethodCaller
|
||||
ForgeDependencySetup.createInitialBindings();
|
||||
LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
|
||||
|
||||
// Print git info (Useful for dev builds)
|
||||
LOGGER.info("DH Branch: "+ ModGitInfo.Git_Main_Branch);
|
||||
LOGGER.info("DH Commit: "+ ModGitInfo.Git_Main_Commit);
|
||||
LOGGER.info("DH-Core Commit: "+ ModGitInfo.Git_Core_Commit);
|
||||
|
||||
client_proxy = new ForgeClientProxy();
|
||||
MinecraftForge.EVENT_BUS.register(client_proxy);
|
||||
server_proxy = new ForgeServerProxy(false);
|
||||
@@ -124,7 +130,7 @@ public class ForgeMain implements LodForgeMethodCaller
|
||||
#if PRE_MC_1_17_1
|
||||
ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY,
|
||||
() -> (client, parent) -> GetConfigScreen.getScreen(parent));
|
||||
#elif POST_MC_1_18_2 && PRE_MC_1_19_2
|
||||
#elif MC_1_17_1 || MC_1_18_2 || PRE_MC_1_19_2
|
||||
ModLoadingContext.get().registerExtensionPoint(ConfigGuiHandler.ConfigGuiFactory.class,
|
||||
() -> new ConfigGuiHandler.ConfigGuiFactory((client, parent) -> GetConfigScreen.getScreen(parent)));
|
||||
#else
|
||||
|
||||
@@ -8,14 +8,9 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.TitleScreen;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.event.server.ServerAboutToStartEvent;
|
||||
import net.minecraftforge.event.server.ServerStoppingEvent;
|
||||
#if PRE_MC_1_19_2
|
||||
import net.minecraftforge.event.world.ChunkEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
@@ -24,6 +19,19 @@ import net.minecraftforge.event.level.ChunkEvent;
|
||||
import net.minecraftforge.event.level.LevelEvent;
|
||||
#endif
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
|
||||
#if MC_1_16_5
|
||||
import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
|
||||
#elif MC_1_17_1
|
||||
import net.minecraftforge.fmlserverevents.FMLServerAboutToStartEvent;
|
||||
import net.minecraftforge.fmlserverevents.FMLServerStoppingEvent;
|
||||
#else
|
||||
import net.minecraftforge.event.server.ServerAboutToStartEvent;
|
||||
import net.minecraftforge.event.server.ServerStoppingEvent;
|
||||
#endif
|
||||
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
@@ -74,7 +82,7 @@ public class ForgeServerProxy
|
||||
|
||||
// ServerWorldLoadEvent
|
||||
@SubscribeEvent
|
||||
public void dedicatedWorldLoadEvent(ServerAboutToStartEvent event)
|
||||
public void dedicatedWorldLoadEvent(#if MC_1_16_5 || MC_1_17_1 FMLServerAboutToStartEvent #else ServerAboutToStartEvent #endif event)
|
||||
{
|
||||
if (this.isValidTime())
|
||||
{
|
||||
@@ -84,7 +92,7 @@ public class ForgeServerProxy
|
||||
|
||||
// ServerWorldUnloadEvent
|
||||
@SubscribeEvent
|
||||
public void serverWorldUnloadEvent(ServerStoppingEvent event)
|
||||
public void serverWorldUnloadEvent(#if MC_1_16_5 || MC_1_17_1 FMLServerStoppingEvent #else ServerStoppingEvent #endif event)
|
||||
{
|
||||
if (this.isValidTime())
|
||||
{
|
||||
@@ -125,22 +133,26 @@ public class ForgeServerProxy
|
||||
@SubscribeEvent
|
||||
public void serverChunkLoadEvent(ChunkEvent.Load event)
|
||||
{
|
||||
if (isValidTime()) {
|
||||
if (GetLevel(event) instanceof ServerLevel) {
|
||||
ServerLevelWrapper wrappedLevel = ServerLevelWrapper.getWrapper((ServerLevel) GetLevel(event));
|
||||
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), GetLevel(event), wrappedLevel);
|
||||
serverApi.serverChunkLoadEvent(chunk, getLevelWrapper((ServerLevel) GetLevel(event)));
|
||||
}
|
||||
if (this.isValidTime())
|
||||
{
|
||||
if (GetLevel(event) instanceof ServerLevel)
|
||||
{
|
||||
ServerLevelWrapper wrappedLevel = ServerLevelWrapper.getWrapper((ServerLevel) GetLevel(event));
|
||||
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), GetLevel(event), wrappedLevel);
|
||||
this.serverApi.serverChunkLoadEvent(chunk, this.getLevelWrapper((ServerLevel) GetLevel(event)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@SubscribeEvent
|
||||
public void serverChunkSaveEvent(ChunkEvent.Unload event)
|
||||
{
|
||||
if (isValidTime()) {
|
||||
if (GetLevel(event) instanceof ServerLevel) {
|
||||
if (this.isValidTime())
|
||||
{
|
||||
if (GetLevel(event) instanceof ServerLevel)
|
||||
{
|
||||
ServerLevelWrapper wrappedLevel = ServerLevelWrapper.getWrapper((ServerLevel) GetLevel(event));
|
||||
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), GetLevel(event), wrappedLevel);
|
||||
serverApi.serverChunkSaveEvent(chunk, getLevelWrapper((ServerLevel) GetLevel(event)));
|
||||
this.serverApi.serverChunkSaveEvent(chunk, this.getLevelWrapper((ServerLevel) GetLevel(event)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -50,7 +50,7 @@ public class MixinFogRenderer {
|
||||
|
||||
@Inject(at = @At("RETURN"),
|
||||
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V",
|
||||
remap = #if MC_1_16_5 || POST_AND_MC_1_19_2 true #else false #endif) // Remap messiness due to this being added by forge.
|
||||
remap = #if MC_1_18_2 false #else true #endif) // Remap messiness due to this being weird in forge
|
||||
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback)
|
||||
{
|
||||
#if PRE_MC_1_17_1
|
||||
@@ -60,7 +60,8 @@ public class MixinFogRenderer {
|
||||
FogType fogTypes = camera.getFluidInCamera();
|
||||
boolean cameraNotInFluid = fogTypes == FogType.NONE;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
Entity entity = camera.getEntity();
|
||||
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
|
||||
if (!isSpecialFog && cameraNotInFluid && fogMode == FogMode.FOG_TERRAIN
|
||||
|
||||
+17
-20
@@ -17,16 +17,6 @@ public class MixinGameRenderer
|
||||
private static final Logger LOGGER = LogManager.getLogger(MixinGameRenderer.class.getSimpleName());
|
||||
|
||||
#if POST_MC_1_17_1
|
||||
@Inject(method = "shutdownShaders", at = @At("HEAD"))
|
||||
public void onShutdownShaders(CallbackInfo ci) {
|
||||
LOGGER.info("Shutting down renderer (forge)");
|
||||
if (!DependencySetupDoneCheck.isDone) {
|
||||
LOGGER.warn("Dependency setup is not done yet, skipping renderer this shutdown event!");
|
||||
return;
|
||||
}
|
||||
ClientApi.INSTANCE.rendererShutdownEvent();
|
||||
}
|
||||
|
||||
// FIXME: This I think will dup multiple renderStartupEvent calls...
|
||||
@Inject(method = {"reloadShaders", "preloadUiShader"}, at = @At("TAIL"))
|
||||
public void onStartupShaders(CallbackInfo ci) {
|
||||
@@ -37,21 +27,28 @@ public class MixinGameRenderer
|
||||
}
|
||||
ClientApi.INSTANCE.rendererStartupEvent();
|
||||
}
|
||||
#else
|
||||
// FIXME: on 1.16 we dont have stuff for reloading/shutting down shaders
|
||||
|
||||
@Inject(method = "shutdownShaders", at = @At("HEAD"))
|
||||
|
||||
@Inject(method = "shutdownShaders", at = @At("HEAD"))
|
||||
public void onShutdownShaders(CallbackInfo ci) {
|
||||
LOGGER.info("Shutting down renderer");
|
||||
LOGGER.info("Shutting down renderer (forge)");
|
||||
if (!DependencySetupDoneCheck.isDone) {
|
||||
LOGGER.warn("Dependency setup is not done yet, skipping renderer this shutdown event!");
|
||||
return;
|
||||
}
|
||||
ClientApi.INSTANCE.rendererShutdownEvent();
|
||||
}
|
||||
|
||||
// FIXME: This I think will dup multiple renderStartupEvent calls...
|
||||
@Inject(method = {"reloadShaders", "preloadUiShader", "preloadShader"}, at = @At("TAIL"))
|
||||
#else
|
||||
|
||||
|
||||
@Inject(method = {"loadEffect"}, at = @At("TAIL"))
|
||||
public void onStartupShaders(CallbackInfo ci) {
|
||||
LOGGER.info("Starting up renderer");
|
||||
ClientApi.INSTANCE.rendererStartupEvent();
|
||||
}
|
||||
|
||||
@Inject(method = "shutdownEffect", at = @At("HEAD"))
|
||||
public void onShutdownShaders(CallbackInfo ci) {
|
||||
ClientApi.INSTANCE.rendererShutdownEvent();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
+34
-37
@@ -46,6 +46,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
#if PRE_MC_1_17_1
|
||||
import org.lwjgl.opengl.GL15;
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* This class is used to mix in my rendering code
|
||||
* before Minecraft starts rendering blocks.
|
||||
@@ -75,43 +80,18 @@ public class MixinLevelRenderer
|
||||
#if PRE_MC_1_17_1
|
||||
@Inject(at = @At("RETURN"), method = "renderSky(Lcom/mojang/blaze3d/vertex/PoseStack;F)V")
|
||||
private void renderSky(PoseStack matrixStackIn, float partialTicks, CallbackInfo callback)
|
||||
#else
|
||||
@Inject(method = "renderClouds", at = @At("HEAD"), cancellable = true)
|
||||
public void renderClouds(PoseStack poseStack, Matrix4f projectionMatrix, float partialTicks, double cameraX, double cameraY, double cameraZ, CallbackInfo ci)
|
||||
#endif
|
||||
{
|
||||
// get the partial ticks since renderBlockLayer doesn't
|
||||
// have access to them
|
||||
previousPartialTicks = partialTicks;
|
||||
}
|
||||
|
||||
@Inject(at = @At("HEAD"),
|
||||
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V",
|
||||
cancellable = true)
|
||||
private void renderChunkLayer(RenderType renderType, PoseStack matrixStackIn, double xIn, double yIn, double zIn, CallbackInfo callback)
|
||||
{
|
||||
// only render before solid blocks
|
||||
if (renderType.equals(RenderType.solid()))
|
||||
{
|
||||
// get MC's current projection matrix
|
||||
float[] mcProjMatrixRaw = new float[16];
|
||||
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
|
||||
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
|
||||
mcProjectionMatrix.transpose();
|
||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
|
||||
|
||||
ClientApi.INSTANCE.renderLods(LevelWrapper.getWorldWrapper(level), mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
|
||||
}
|
||||
if (Config.Client.Advanced.lodOnlyMode.get()) {
|
||||
callback.cancel();
|
||||
}
|
||||
}
|
||||
#else
|
||||
@Inject(method = "renderClouds", at = @At("HEAD"), cancellable = true)
|
||||
public void renderClouds(PoseStack poseStack, Matrix4f projectionMatrix, float tickDelta, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) {
|
||||
// get the partial ticks since renderChunkLayer doesn't
|
||||
// have access to them
|
||||
previousPartialTicks = tickDelta;
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: Can we move this o forge's client proxy simmilar to how fabric does it
|
||||
|
||||
|
||||
// TODO: Can we move this to forge's client proxy similarly to how fabric does it
|
||||
#if PRE_MC_1_17_1
|
||||
@Inject(at = @At("HEAD"),
|
||||
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V",
|
||||
@@ -129,20 +109,37 @@ public class MixinLevelRenderer
|
||||
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
|
||||
#endif
|
||||
{
|
||||
// get MC's model view and projection matrices
|
||||
#if MC_1_16_5
|
||||
// get the matrices from the OpenGL fixed pipeline
|
||||
float[] mcProjMatrixRaw = new float[16];
|
||||
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
|
||||
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
|
||||
mcProjectionMatrix.transpose();
|
||||
|
||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
|
||||
|
||||
#else
|
||||
// get the matrices directly from MC
|
||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
|
||||
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// only render before solid blocks
|
||||
if (renderType.equals(RenderType.solid()))
|
||||
{
|
||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
|
||||
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
|
||||
|
||||
ClientApi.INSTANCE.renderLods(ClientLevelWrapper.getWrapper(level), mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
|
||||
|
||||
// experimental proof-of-concept option
|
||||
if (Config.Client.Advanced.Graphics.AdvancedGraphics.seamlessOverdraw.get())
|
||||
{
|
||||
float[] matrixFloatArray = SeamlessOverdraw.overwriteMinecraftNearFarClipPlanes(projectionMatrix, previousPartialTicks);
|
||||
float[] matrixFloatArray = SeamlessOverdraw.overwriteMinecraftNearFarClipPlanes(mcProjectionMatrix, previousPartialTicks);
|
||||
|
||||
#if PRE_MC_1_19_4
|
||||
#if MC_1_16_5
|
||||
SeamlessOverdraw.applyLegacyProjectionMatrix(matrixFloatArray);
|
||||
#elif PRE_MC_1_19_4
|
||||
projectionMatrix.load(FloatBuffer.wrap(matrixFloatArray));
|
||||
#else
|
||||
projectionMatrix.set(matrixFloatArray);
|
||||
|
||||
+5
-3
@@ -13,13 +13,15 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
* @author coolGi
|
||||
*/
|
||||
@Mixin(TextureUtil.class)
|
||||
public class MixinTextureUtil {
|
||||
@Redirect(method = "Lcom/mojang/blaze3d/platform/TextureUtil;prepareImage(Lcom/mojang/blaze3d/platform/NativeImage$InternalGlFormat;IIII)V",
|
||||
public class MixinTextureUtil
|
||||
{
|
||||
@Redirect(method = "prepareImage(Lcom/mojang/blaze3d/platform/NativeImage$InternalGlFormat;IIII)V",
|
||||
at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/GlStateManager;_texParameter(IIF)V"), remap=false)
|
||||
private static void setLodBias(int target, int pname, float param)
|
||||
{
|
||||
float biasValue = Config.Client.Advanced.Graphics.AdvancedGraphics.lodBias.get().floatValue();
|
||||
if (biasValue != 0) {
|
||||
if (biasValue != 0)
|
||||
{
|
||||
// The target is GL11.GL_TEXTURE_2D
|
||||
// And the pname is GL14.GL_TEXTURE_LOD_BIAS
|
||||
GlStateManager._texParameter(target, pname, biasValue);
|
||||
|
||||
+10
-5
@@ -3,7 +3,13 @@ package com.seibel.distanthorizons.forge.mixins.server;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
#if PRE_MC_1_17_1
|
||||
#if MC_1_16_5
|
||||
@Mixin(ChunkGenerator.class)
|
||||
class MixinTFChunkGenerator
|
||||
{
|
||||
// not currently implemented, attempting to run with the mod enabled in the IDE causes the game to lock up
|
||||
}
|
||||
#elif PRE_MC_1_17_1
|
||||
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
@@ -14,11 +20,11 @@ import java.util.Random;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
|
||||
@Mixin(FeatureGenerator.class)
|
||||
public class MixinTFChunkGenerator {
|
||||
public class MixinTFChunkGenerator
|
||||
{
|
||||
|
||||
@Redirect(method = "decorate("
|
||||
+ "Lnet/minecraft/world/level/StructureFeatureManager;"
|
||||
@@ -51,6 +57,5 @@ public class MixinTFChunkGenerator {
|
||||
|
||||
#else
|
||||
@Mixin(ChunkGenerator.class)
|
||||
class MixinTFChunkGenerator {
|
||||
}
|
||||
class MixinTFChunkGenerator { }
|
||||
#endif
|
||||
+5
-2
@@ -32,7 +32,7 @@ import java.util.concurrent.Semaphore;
|
||||
|
||||
/**
|
||||
* Why does this exist? But okay! (Will be probably removed when the experimental generator is done)
|
||||
* FIXME: Recheck this
|
||||
* FIXME: Recheck this // STILL check this
|
||||
*/
|
||||
@Mixin(ThreadingDetector.class)
|
||||
public class MixinThreadingDetector {
|
||||
@@ -47,6 +47,9 @@ public class MixinThreadingDetector {
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
|
||||
@Mixin(ChunkGenerator.class)
|
||||
public class MixinThreadingDectector {}
|
||||
public class MixinThreadingDetector { }
|
||||
#endif
|
||||
+1
-1
@@ -18,7 +18,7 @@ mod_issues=https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues
|
||||
mod_discord=https://discord.gg/xAB8G4cENx
|
||||
|
||||
# Global Plugin Versions
|
||||
manifold_version=2023.1.10
|
||||
manifold_version=2023.1.11
|
||||
toml_version=3.6.4
|
||||
lz4_version=1.8.0
|
||||
nightconfig_version=3.6.6
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ project(":api").projectDir = file('coreSubProjects/api')
|
||||
include("common")
|
||||
// Enables or disables the subprojects depending on whats in the versionProperties/mcVer.properties
|
||||
for (loader in ((String) gradle.builds_for).split(",")) {
|
||||
include(loader)
|
||||
include(loader.strip()) // Strip it in case a space is added before or after the comma
|
||||
}
|
||||
//if (gradle.builds_for.contains("fabric") || gradle.builds_for.contains("quilt"))
|
||||
// include("fabricLike")
|
||||
|
||||
@@ -16,7 +16,7 @@ fabric_api_version=0.42.0+1.16
|
||||
lithium_version=mc1.16.5-0.6.6
|
||||
sodium_version=mc1.16.5-0.2.0
|
||||
iris_version=1.16.x-v1.2.5
|
||||
bclib_version=0.1.41
|
||||
bclib_version=
|
||||
immersive_portals_version=
|
||||
canvas_version=
|
||||
|
||||
@@ -29,6 +29,7 @@ fabric_api_version=0.42.0+1.16
|
||||
enable_lithium=0
|
||||
enable_sodium=1
|
||||
enable_iris=0
|
||||
# not available via github, use curse.maven if necessary
|
||||
enable_bclib=0
|
||||
enable_immersive_portals=0
|
||||
enable_canvas=0
|
||||
@@ -37,12 +38,12 @@ fabric_api_version=0.42.0+1.16
|
||||
forge_version=36.2.39
|
||||
# Forge mod versions
|
||||
starlight_version_forge=
|
||||
terraforged_version=3285909
|
||||
terraforged_version=4044290
|
||||
|
||||
# Forge mod run
|
||||
# 0 = Don't enable and don't run
|
||||
# 1 = Can be referenced in code but doesn't run
|
||||
# 2 = Can be referenced in code and runs in client
|
||||
enable_starlight_forge=0
|
||||
enable_terraforged=2
|
||||
enable_terraforged=1
|
||||
enable_terrafirmacraft=0
|
||||
|
||||
@@ -14,7 +14,7 @@ fabric_api_version=0.85.0+1.20.1
|
||||
starlight_version_fabric=
|
||||
phosphor_version_fabric=
|
||||
lithium_version=
|
||||
sodium_version=mc1.20-0.4.10
|
||||
sodium_version=mc1.20.1-0.5.0
|
||||
iris_version=1.6.4+1.20.1
|
||||
bclib_version=3.0.12
|
||||
immersive_portals_version=
|
||||
|
||||
Reference in New Issue
Block a user