Compare commits

...

77 Commits

Author SHA1 Message Date
James Seibel d09ddf57d3 remove dev from version number 2025-07-19 14:57:19 -05:00
James Seibel 486edac1d8 replace 1.21.7 with 1.21.8 in gitlab CI 2025-07-19 14:56:32 -05:00
James Seibel 3b3731a137 Replace 1.21.7 support with 1.21.8 2025-07-19 13:29:29 -05:00
s809 563ec70154 Load level on player add if missing 2025-07-19 19:05:59 +05:00
James Seibel 175f5ed6d6 Improve logging for initial DH startup 2025-07-16 07:28:15 -05:00
James Seibel 1e63607233 Fix AfterDhInitEvent not firing on Neo
Fixes some Iris shader compile issues
2025-07-16 07:18:23 -05:00
James Seibel 4dd8be23fa Merge !81 (forge AfterInit API Event not firing on clients) 2025-07-16 06:56:38 -05:00
James Seibel 7fac5b4c6e Remove chunky incompatibility
I'm still a bit annoyed that problems can arise, but if people are able to configure DH/Chunky to work well together, I won't stop them from running together.

Note that a warning will be printed to the chat/log, if chunky is detected.
2025-07-15 07:49:44 -05:00
James Seibel f2ec1ecf3f Update all neoforge references to latest
Hopefully will fix some shader issues #1087
2025-07-15 07:41:19 -05:00
James Seibel 2674e6b2e9 up the version number 2.3.3 -> 2.3.4 2025-07-12 09:35:52 -05:00
James Seibel bcbe3f0fb7 remove dev from the version number 2025-07-12 09:35:24 -05:00
James Seibel f85108ed11 Fix API config renderingEnabled() changing the user value
Fixes #1083
2025-07-12 08:16:40 -05:00
James Seibel 2bc5169ce5 Closes #1084 (AfterDhInitEvent firing before DH config setup) 2025-07-12 08:02:08 -05:00
James Seibel 1edd809708 Fix config UI not showing DH version for MC 1.21.6+ 2025-07-11 07:29:46 -05:00
James Seibel 475111b38b full data DTO close data source if corrupted 2025-07-10 22:25:41 -05:00
James Seibel b44a967e56 Fix monoliths when connected to a server 2025-07-10 07:29:52 -05:00
James Seibel acea685e75 fix some neo running issues with dependency ranges 2025-07-09 07:28:54 -05:00
James Seibel 20f15a6b39 Fixes !1078 (lag due to beacon updating on server) 2025-07-09 07:28:37 -05:00
James Seibel debf52418c Potentially fix an issue with AMD GPU shader compiling
Fix from Cortex and the Canvas mod
2025-07-08 07:22:41 -05:00
James Seibel cf71491381 Disable vanilla fading when shaders are active 2025-07-07 07:49:46 -05:00
James Seibel 0a4a8466cf Add comments to MixinFogRenderer 2025-07-04 09:21:02 -05:00
James Seibel 31fac60d34 Increment default dev MC version 1.21.6 -> 1.21.7 2025-07-04 09:12:36 -05:00
James Seibel c335020c2f Fix sodium fog for MC 1.21.7 2025-07-04 09:05:42 -05:00
James Seibel 4db4f2fbc6 Fix Neoforge 1.21.7 packet registration changes 2025-07-04 09:05:23 -05:00
James Seibel f9f4a208e7 Fix 1.21.7 compiling 2025-07-03 07:52:17 -05:00
James Seibel b5fa5936b3 Add 1.21.7 version (may not compile) 2025-07-02 07:52:07 -05:00
James Seibel 6ceabe7895 Force vanilla fading and overdraw prevention with Sodium 2025-07-02 07:42:55 -05:00
s809 ec3d8afbfc Disable enableAdaptiveTransferSpeed bby default 2025-07-01 22:03:16 +05:00
James Seibel e9a0c6d097 Fix config UI changes not always saving 2025-07-01 07:45:31 -05:00
James Seibel 0238568370 Fix neo config crashing and fix some warnings 2025-07-01 07:22:43 -05:00
James Seibel 74be00e025 Fix neoforge vanilla fade for MC 1.21.6 2025-07-01 07:11:08 -05:00
James Seibel c10af6dd04 fix build-all scripts 2025-06-30 07:46:18 -05:00
James Seibel 85ee5ac833 fix forge compiling 2025-06-30 07:46:12 -05:00
James Seibel 21877d67a5 Add neo version dependency and roll back 6.20 -> 6.19
6.20 had some issue preventing running in dev
2025-06-30 07:38:37 -05:00
James Seibel ae33a79d6e update to Neo 21.6.20 2025-06-30 06:56:08 -05:00
James Seibel 9204b357d8 comment out Z_STD compression
comment out Z_STD compression
2025-06-30 06:55:47 -05:00
James Seibel 78b1b74036 Mark Chunky as incompatible
Done as a test
2025-06-28 13:58:12 -05:00
James Seibel 864c5b5f86 Re-Add Z_STD compression for testing 2025-06-28 11:37:17 -05:00
James Seibel b271c8e119 Fix MinecraftGLWrapper.getActiveTexture() 2025-06-28 10:10:03 -05:00
James Seibel 79bdae5b8b Fix auto-updater for MC 1.21.6 2025-06-28 09:56:51 -05:00
James Seibel d5dc9f6b79 Fix multiplayer null pointer 2025-06-28 09:22:32 -05:00
James Seibel a50f13caa0 Mostly fix Iris transparent rendering for 1.21.6 2025-06-28 08:37:18 -05:00
James Seibel 75b3649a97 Fix world-gen progress not showing in release builds 2025-06-27 07:29:43 -05:00
James Seibel 69adb54b91 disable blending data parsing in chunk loading for MC 1.21.6
There appears to be a parsing issue and since it doesn't appear to change how the chunks load I'm going to ignore it for now
2025-06-27 07:18:01 -05:00
James Seibel 458c1ae7e0 re-add LevelTicks mixin for MC 1.21.4+ 2025-06-27 07:10:12 -05:00
James Seibel a647551d26 Move RenderState to core 2025-06-26 07:50:59 -05:00
James Seibel 3a45bdd2a2 remove broken var in NeoClientProxy 2025-06-26 07:29:51 -05:00
James Seibel 4806cd2445 Move RenderState object into ClientApi 2025-06-26 07:21:33 -05:00
James Seibel af7f90f128 add 1.21.6 to the CI script 2025-06-26 07:10:39 -05:00
James Seibel f72ad60f58 Fix old MC version compiling 2025-06-26 07:10:32 -05:00
James Seibel 6015afbf4c Fix neo rendering and fabric shader rendering 2025-06-25 07:48:04 -05:00
James Seibel 0369ae63f3 fix neo fox mixin 2025-06-21 09:22:39 -05:00
James Seibel 278d5063fb up neoforge version 2025-06-21 09:21:47 -05:00
James Seibel a64e72034e Fix UI text rendering 2025-06-21 09:21:40 -05:00
James Seibel fcdb56660c fix fog renderer again 2025-06-20 07:39:50 -05:00
James Seibel 0c26261cd5 Update gradle.properties 2025-06-19 07:32:43 -05:00
James Seibel b50525fff9 Update ServerPlayerWrapper.java 2025-06-19 07:32:35 -05:00
James Seibel 92e403823b fix gui button rendering 2025-06-19 07:32:21 -05:00
James Seibel e02f56f4ef Update VersionConstants.java 2025-06-19 06:52:32 -05:00
James Seibel aa4681e044 update MC GL Wrapper 2025-06-18 17:36:46 -05:00
James Seibel 1c9130c3f1 update McObjectConverter for matricies 2025-06-18 17:36:22 -05:00
James Seibel c3597cd843 update fog mixin 2025-06-18 17:36:02 -05:00
James Seibel d4a52ac5a3 update version properties 2025-06-18 17:34:14 -05:00
James Seibel 1b9d14e7b4 Disable cave culling for medium quality and higher 2025-06-17 07:15:36 -05:00
James Seibel 0ea27b676e Optimize ClientLevelWrapper.GetWrapper()
Should speed up initial LOD loading a bit
2025-06-17 07:15:15 -05:00
James Seibel cd73608b07 Reduce stuttering with fast world gen 2025-06-14 16:17:33 -05:00
James Seibel 03fc22f611 Reduce allocations in getBlockColor by using a cached method reference
Currently there is a large number of allocations of `java.lang.invoke.invokers$Holder:linkToTargetMethod` -- this prevents that
2025-06-11 07:09:40 -05:00
James Seibel cc251e46b0 Add Api Before/After Text Create events 2025-06-09 07:50:25 -05:00
James Seibel 7aa0bfefec Fix hash collisions in FullDataPointIdMap 2025-06-06 07:43:44 -05:00
James Seibel 9bdad5e4f1 Fix 1.21.5 compiling 2025-06-06 07:36:00 -05:00
James Seibel baebb7323d Close #776 (fix Polytone client biome colors) 2025-06-05 07:53:23 -05:00
James Seibel 8a3175f345 Mark Polytone as incompatible 2025-06-04 07:49:15 -05:00
James Seibel dc58efb301 Handle nulls in ChunkLoader
Should fix WorldPainter worlds
2025-06-04 07:28:51 -05:00
James Seibel c9ac4b2ada Fix GLMC.glDeleteTextures() calls 2025-06-04 07:07:51 -05:00
s809 6e1ec476ed Check LOD timestamps in file handler threads 2025-06-03 23:41:51 +05:00
James Seibel d1aa5a524b Remove line ending from editorconfig
Done to fix some issues with some devs on linux
2025-05-17 11:47:06 -05:00
James Seibel 5c661a3a76 yaml indent 2 -> 4
for consistency
2025-05-17 11:25:37 -05:00
53 changed files with 1366 additions and 492 deletions
+1 -2
View File
@@ -5,7 +5,6 @@ root = true
[*] [*]
charset = utf-8 charset = utf-8
end_of_line = crlf
indent_size = 4 indent_size = 4
indent_style = space indent_style = space
insert_final_newline = false insert_final_newline = false
@@ -688,7 +687,7 @@ ij_markdown_wrap_text_inside_blockquotes = true
ij_toml_keep_indents_on_empty_lines = false ij_toml_keep_indents_on_empty_lines = false
[{*.yaml,*.yml}] [{*.yaml,*.yml}]
indent_size = 2 indent_size = 4
ij_yaml_align_values_properties = do_not_align ij_yaml_align_values_properties = do_not_align
ij_yaml_autoinsert_sequence_marker = true ij_yaml_autoinsert_sequence_marker = true
ij_yaml_block_mapping_on_new_line = false ij_yaml_block_mapping_on_new_line = false
+1 -1
View File
@@ -35,7 +35,7 @@ build:
stage: build stage: build
parallel: parallel:
matrix: matrix:
- MC_VER: ["1.16.5", "1.17.1", "1.18.2", "1.19.2", "1.19.4", "1.20.1", "1.20.2", "1.20.4", "1.20.6", "1.21.1", "1.21.3", "1.21.4", "1.21.5"] - MC_VER: ["1.16.5", "1.17.1", "1.18.2", "1.19.2", "1.19.4", "1.20.1", "1.20.2", "1.20.4", "1.20.6", "1.21.1", "1.21.3", "1.21.4", "1.21.5", "1.21.6", "1.21.8"]
script: script:
# this both runs the unit tests and assembles the code # this both runs the unit tests and assembles the code
- ./gradlew clean -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/; - ./gradlew clean -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
+4
View File
@@ -246,6 +246,8 @@ subprojects { p ->
// We cannot relocate this library since we call some MC classes that reference it // We cannot relocate this library since we call some MC classes that reference it
implementation("it.unimi.dsi:fastutil:${rootProject.fastutil_version}") implementation("it.unimi.dsi:fastutil:${rootProject.fastutil_version}")
//forgeShadowMe("com.github.luben:zstd-jni:1.5.7-3")
//forgeShadowMe("org.apache.commons:commons-compress:1.27.1")
// Compression // Compression
forgeShadowMe("org.lz4:lz4-java:${rootProject.lz4_version}") // LZ4 forgeShadowMe("org.lz4:lz4-java:${rootProject.lz4_version}") // LZ4
@@ -445,6 +447,8 @@ subprojects { p ->
fabric_incompatibility_list : fabric_incompatibility_list, fabric_incompatibility_list : fabric_incompatibility_list,
fabric_recommend_list : fabric_recommend_list, fabric_recommend_list : fabric_recommend_list,
neoforge_version_range : neoforge_version_range,
] ]
// replace any properties in the sub-projects with the values defined here // replace any properties in the sub-projects with the values defined here
+1 -1
View File
@@ -24,5 +24,5 @@ for d in versionProperties/*; do
if [ $? != 0 ]; then continue; fi if [ $? != 0 ]; then continue; fi
echo "==================== Moving jar ====================" echo "==================== Moving jar ===================="
mv Merged/*.jar buildAllJars/ mv build/merged/*.jar buildAllJars/
done done
+4 -1
View File
@@ -15,12 +15,15 @@ for %%f in (versionProperties\*) do (
@rem Clean out the folders, build it, and merge it @rem Clean out the folders, build it, and merge it
echo ==================== Cleaning workspace to build !version! ==================== echo ==================== Cleaning workspace to build !version! ====================
call .\gradlew.bat clean call .\gradlew.bat clean
echo ==================== Building !version! ==================== echo ==================== Building !version! ====================
call .\gradlew.bat build -PmcVer="!version!" call .\gradlew.bat build -PmcVer="!version!"
echo ==================== Merging !version! ==================== echo ==================== Merging !version! ====================
call .\gradlew.bat mergeJars -PmcVer="!version!" call .\gradlew.bat mergeJars -PmcVer="!version!"
echo ==================== Moving jar ==================== echo ==================== Moving jar ====================
move Merged\*.jar buildAllJars\ move build\merged\*.jar buildAllJars\
) )
endlocal endlocal
@@ -66,7 +66,7 @@ public abstract class AbstractModInitializer
{ {
DependencySetup.createClientBindings(); DependencySetup.createClientBindings();
LOGGER.info("Initializing " + ModInfo.READABLE_NAME + " client."); LOGGER.info("Initializing " + ModInfo.READABLE_NAME + " client, firing DhApiBeforeDhInitEvent...");
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null); ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
this.startup(); this.startup();
@@ -77,13 +77,12 @@ public abstract class AbstractModInitializer
this.initializeModCompat(); this.initializeModCompat();
LOGGER.info(ModInfo.READABLE_NAME + " client Initialized.");
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
// Client uses config for auto-updater, so it's initialized here instead of post-init stage // Client uses config for auto-updater, so it's initialized here instead of post-init stage
this.initConfig(); this.initConfig();
logModIncompatibilityWarnings(); // needs to be called after config loading logModIncompatibilityWarnings(); // needs to be called after config loading
LOGGER.info(ModInfo.READABLE_NAME + " client Initialized.");
this.subscribeClientStartedEvent(this::postInit); this.subscribeClientStartedEvent(this::postInit);
} }
@@ -91,7 +90,7 @@ public abstract class AbstractModInitializer
{ {
DependencySetup.createServerBindings(); DependencySetup.createServerBindings();
LOGGER.info("Initializing " + ModInfo.READABLE_NAME + " server."); LOGGER.info("Initializing " + ModInfo.READABLE_NAME + " server, firing DhApiBeforeDhInitEvent event...");
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null); ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
this.startup(); this.startup();
@@ -106,8 +105,7 @@ public abstract class AbstractModInitializer
this.initializeModCompat(); this.initializeModCompat();
LOGGER.info(ModInfo.READABLE_NAME + " server Initialized."); LOGGER.info(ModInfo.READABLE_NAME + " server Initialized, adding event subscribers...");
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
this.subscribeRegisterCommandsEvent(dispatcher -> { this.commandInitializer = new CommandInitializer(dispatcher); }); this.subscribeRegisterCommandsEvent(dispatcher -> { this.commandInitializer = new CommandInitializer(dispatcher); });
@@ -121,7 +119,7 @@ public abstract class AbstractModInitializer
this.checkForUpdates(); this.checkForUpdates();
LOGGER.info("Dedicated server initialized at " + server.getServerDirectory()); LOGGER.info(ModInfo.READABLE_NAME + " server Initialized at " + server.getServerDirectory());
}); });
} }
@@ -183,9 +181,12 @@ public abstract class AbstractModInitializer
private void postInit() private void postInit()
{ {
LOGGER.info("Post-Initializing Mod"); LOGGER.info("Running Delayed setup...");
this.runDelayedSetup(); this.runDelayedSetup();
LOGGER.info("Mod Post-Initialized"); LOGGER.info("Delayed setup complete, firing DhApiAfterDhInitEvent event...");
// should be fired after all delayed setup so singletons and config can be accessed
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
} }
@@ -49,7 +49,9 @@ public class McObjectConverter
@Deprecated @Deprecated
public static Mat4f Convert( public static Mat4f Convert(
#if MC_VER < MC_1_19_4 com.mojang.math.Matrix4f #if MC_VER < MC_1_19_4 com.mojang.math.Matrix4f
#else org.joml.Matrix4f #endif #elif MC_VER < MC_1_21_6 org.joml.Matrix4f
#else org.joml.Matrix4fc
#endif
mcMatrix) mcMatrix)
{ {
FloatBuffer buffer = FloatBuffer.allocate(16); FloatBuffer buffer = FloatBuffer.allocate(16);
@@ -63,7 +65,9 @@ public class McObjectConverter
/** Taken from Minecraft's com.mojang.math.Matrix4f class from 1.18.2 */ /** Taken from Minecraft's com.mojang.math.Matrix4f class from 1.18.2 */
private static void storeMatrix( private static void storeMatrix(
#if MC_VER < MC_1_19_4 com.mojang.math.Matrix4f #if MC_VER < MC_1_19_4 com.mojang.math.Matrix4f
#else org.joml.Matrix4f #endif #elif MC_VER < MC_1_21_6 org.joml.Matrix4f
#else org.joml.Matrix4fc
#endif
matrix, matrix,
FloatBuffer buffer) FloatBuffer buffer)
{ {
@@ -74,6 +74,10 @@ public class VersionConstants implements IVersionConstants
return "1.21.4"; return "1.21.4";
#elif MC_VER == MC_1_21_5 #elif MC_VER == MC_1_21_5
return "1.21.5"; return "1.21.5";
#elif MC_VER == MC_1_21_6
return "1.21.6";
#elif MC_VER == MC_1_21_8
return "1.21.8";
#else #else
ERROR MC version constant missing ERROR MC version constant missing
#endif #endif
@@ -47,6 +47,7 @@ import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
#if MC_VER >= MC_1_18_2 #if MC_VER >= MC_1_18_2
import net.minecraft.world.level.biome.Biomes; import net.minecraft.world.level.biome.Biomes;
#endif #endif
@@ -130,14 +131,6 @@ public class BiomeWrapper implements IBiomeWrapper
//LOGGER.trace("Created BiomeWrapper ["+this.serialString+"] for ["+biome+"]"); //LOGGER.trace("Created BiomeWrapper ["+this.serialString+"] for ["+biome+"]");
} }
/** should only be used to create {@link BiomeWrapper#EMPTY_WRAPPER} */
private BiomeWrapper()
{
this.biome = null;
this.serialString = EMPTY_BIOME_STRING;
this.hashCode = Objects.hash(this.serialString);
}
//=========// //=========//
@@ -285,6 +278,42 @@ public class BiomeWrapper implements IBiomeWrapper
// if no wrapper is found, default to the empty wrapper // if no wrapper is found, default to the empty wrapper
BiomeWrapper foundWrapper = EMPTY_WRAPPER; BiomeWrapper foundWrapper = EMPTY_WRAPPER;
try try
{
try
{
Level level = (Level) levelWrapper.getWrappedMcObject();
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
BiomeDeserializeResult deserializeResult = deserializeBiome(resourceLocationString, registryAccess);
if (!deserializeResult.success)
{
if (!brokenResourceLocationStrings.contains(resourceLocationString))
{
brokenResourceLocationStrings.add(resourceLocationString);
LOGGER.warn("Unable to deserialize biome from string: [" + resourceLocationString + "]");
}
return EMPTY_WRAPPER;
}
foundWrapper = (BiomeWrapper) getBiomeWrapper(deserializeResult.biome, levelWrapper);
return foundWrapper;
}
catch (Exception e)
{
throw new IOException("Failed to deserialize the string [" + finalResourceStateString + "] into a BiomeWrapper: " + e.getMessage(), e);
}
}
finally
{
WRAPPER_BY_RESOURCE_LOCATION.putIfAbsent(finalResourceStateString, foundWrapper);
}
}
public static BiomeDeserializeResult deserializeBiome(String resourceLocationString, net.minecraft.core.RegistryAccess registryAccess) throws IOException
{ {
// parse the resource location // parse the resource location
int separatorIndex = resourceLocationString.indexOf(":"); int separatorIndex = resourceLocationString.indexOf(":");
@@ -308,11 +337,6 @@ public class BiomeWrapper implements IBiomeWrapper
} }
try
{
Level level = (Level) levelWrapper.getWrappedMcObject();
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
boolean success; boolean success;
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1 #if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
Biome biome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation); Biome biome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
@@ -341,31 +365,30 @@ public class BiomeWrapper implements IBiomeWrapper
} }
#endif #endif
return new BiomeDeserializeResult(success, biome);
if (!success)
{
if (!brokenResourceLocationStrings.contains(resourceLocationString))
{
brokenResourceLocationStrings.add(resourceLocationString);
LOGGER.warn("Unable to deserialize biome from string: [" + resourceLocationString + "]");
}
return EMPTY_WRAPPER;
} }
foundWrapper = (BiomeWrapper) getBiomeWrapper(biome, levelWrapper); //================//
return foundWrapper; // helper classes //
} //================//
catch (Exception e)
public static class BiomeDeserializeResult
{ {
throw new IOException("Failed to deserialize the string [" + finalResourceStateString + "] into a BiomeWrapper: " + e.getMessage(), e); public final boolean success;
}
} #if MC_VER < MC_1_18_2
finally public final Biome biome;
#else
public final Holder<Biome> biome;
#endif
public BiomeDeserializeResult(boolean success, #if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif biome)
{ {
WRAPPER_BY_RESOURCE_LOCATION.putIfAbsent(finalResourceStateString, foundWrapper); this.success = success;
this.biome = biome;
} }
} }
} }
@@ -91,7 +91,7 @@ public class ClientBlockStateColorCache
private static final RandomSource RANDOM = RandomSource.create(); private static final RandomSource RANDOM = RandomSource.create();
#endif #endif
private final IClientLevelWrapper levelWrapper; private final IClientLevelWrapper clientLevelWrapper;
private final BlockState blockState; private final BlockState blockState;
private final LevelReader level; private final LevelReader level;
@@ -174,7 +174,7 @@ public class ClientBlockStateColorCache
public ClientBlockStateColorCache(BlockState blockState, IClientLevelWrapper samplingLevel) public ClientBlockStateColorCache(BlockState blockState, IClientLevelWrapper samplingLevel)
{ {
this.blockState = blockState; this.blockState = blockState;
this.levelWrapper = samplingLevel; this.clientLevelWrapper = samplingLevel;
this.level = (LevelReader) samplingLevel.getWrappedMcObject(); this.level = (LevelReader) samplingLevel.getWrappedMcObject();
this.resolveColors(); this.resolveColors();
} }
@@ -471,7 +471,7 @@ public class ClientBlockStateColorCache
try try
{ {
tintColor = Minecraft.getInstance().getBlockColors() tintColor = Minecraft.getInstance().getBlockColors()
.getColor(this.blockState, new TintWithoutLevelOverrider(biome, this.levelWrapper), McObjectConverter.Convert(pos), this.tintIndex); .getColor(this.blockState, new TintWithoutLevelOverrider(biome, this.clientLevelWrapper), McObjectConverter.Convert(pos), this.tintIndex);
} }
catch (UnsupportedOperationException e) catch (UnsupportedOperationException e)
{ {
@@ -19,8 +19,10 @@
package com.seibel.distanthorizons.common.wrappers.block; package com.seibel.distanthorizons.common.wrappers.block;
import com.seibel.distanthorizons.core.util.ColorUtil; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.level.*; import net.minecraft.world.level.*;
@@ -29,6 +31,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.lighting.LevelLightEngine; import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.FluidState;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -36,22 +39,64 @@ import org.jetbrains.annotations.Nullable;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
#endif #endif
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class TintWithoutLevelOverrider implements BlockAndTintGetter public class TintWithoutLevelOverrider implements BlockAndTintGetter
{ {
/** private static final Logger LOGGER = DhLoggerBuilder.getLogger();
* This will only ever be null if there was an issue with {@link IClientLevelWrapper#getPlainsBiomeWrapper()}
* but {@link Nullable} is there just in case. #if MC_VER < MC_1_18_2
*/ public static final ConcurrentMap<String, Biome> BIOME_BY_RESOURCE_STRING = new ConcurrentHashMap<>();
@Nullable
#if MC_VER >= MC_1_18_2
public final Holder<Biome> biome;
#else #else
public final Biome biome; public static final ConcurrentMap<String, Holder<Biome>> BIOME_BY_RESOURCE_STRING = new ConcurrentHashMap<>();
#endif #endif
@NotNull
private final BiomeWrapper biomeWrapper;
//=============//
// constructor //
//=============//
public TintWithoutLevelOverrider(@NotNull BiomeWrapper biomeWrapper, IClientLevelWrapper clientLevelWrapper)
{ this.biomeWrapper = biomeWrapper; }
//=========//
// methods //
//=========//
@Override
public int getBlockTint(@NotNull BlockPos blockPos, @NotNull ColorResolver colorResolver)
{
String biomeString = this.biomeWrapper.getSerialString();
if (biomeString == null
|| biomeString.isEmpty()
|| biomeString.equals(BiomeWrapper.EMPTY_BIOME_STRING))
{
// default to "plains" for empty/invalid biomes
biomeString = "minecraft:plains";
}
return colorResolver.getColor(unwrap(getClientBiome(biomeString)), blockPos.getX(), blockPos.getZ());
}
private static Biome unwrap(#if MC_VER >= MC_1_18_2 Holder<Biome> #else Biome #endif biome)
{
#if MC_VER >= MC_1_18_2
return biome.value();
#else
return biome;
#endif
}
/** /**
* Constructs the TintWithoutLevelOverrider, storing the provided Biome Holder for late-binding access.
*
* <p>Previously, this class might have immediately unwrapped the Holder like this:</p> * <p>Previously, this class might have immediately unwrapped the Holder like this:</p>
* <pre>{@code * <pre>{@code
* // Inside constructor (OLD WAY - PROBLEMATIC): * // Inside constructor (OLD WAY - PROBLEMATIC):
@@ -85,41 +130,52 @@ public class TintWithoutLevelOverrider implements BlockAndTintGetter
* whenever the biome information is needed, ensuring it always retrieves the most current {@code Biome} * whenever the biome information is needed, ensuring it always retrieves the most current {@code Biome}
* instance associated with the holder at that time.</p> * instance associated with the holder at that time.</p>
*/ */
public TintWithoutLevelOverrider(BiomeWrapper biomeWrapper, IClientLevelWrapper clientLevelWrapper) private static #if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif getClientBiome(String biomeResourceString)
{ {
#if MC_VER >= MC_1_18_2 Holder<Biome> #else Biome #endif biome = biomeWrapper.biome; // cache the client biomes so we don't have to re-parse the resource location every time
if (biome == null) // We are looking at the empty biome wrapper return BIOME_BY_RESOURCE_STRING.compute(biomeResourceString,
(resourceString, existingBiome) ->
{ {
BiomeWrapper plainsBiomeWrapper = ((BiomeWrapper) clientLevelWrapper.getPlainsBiomeWrapper()); if (existingBiome != null)
if (plainsBiomeWrapper != null)
{ {
biome = plainsBiomeWrapper.biome; return existingBiome;
}
ClientLevel clientLevel = Minecraft.getInstance().level;
if (clientLevel == null)
{
// shouldn't happen, but just in case
throw new IllegalStateException("Attempted to get client biome when no client level was loaded.");
}
BiomeWrapper.BiomeDeserializeResult result;
try
{
result = BiomeWrapper.deserializeBiome(resourceString, clientLevel.registryAccess());
}
catch (Exception e)
{
LOGGER.warn("Unable to deserialize client biome ["+resourceString+"], using fallback...");
try
{
result = BiomeWrapper.deserializeBiome("minecraft:plains", clientLevel.registryAccess());
}
catch (IOException ex)
{
// should never happen, if it does this log will explode, but just in case
LOGGER.error("Unable to deserialize fallback client biome [minecraft:plains], returning NULL.");
return null;
} }
} }
this.biome = biome; if (result.success)
{
existingBiome = result.biome;
} }
return existingBiome;
});
@Override
public int getBlockTint(@NotNull BlockPos blockPos, @NotNull ColorResolver colorResolver)
{
if (this.biome == null)
{
// hopefully unneeded debug color
return ColorUtil.CYAN;
}
return colorResolver.getColor(unwrap(biome), blockPos.getX(), blockPos.getZ());
}
private static Biome unwrap(#if MC_VER >= MC_1_18_2 Holder<Biome> #else Biome #endif biome)
{
#if MC_VER >= MC_1_18_2
return biome.value();
#else
return biome;
#endif
} }
@@ -56,20 +56,20 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.*; import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.*;
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.Translatable;
/** /*
* Based upon TinyConfig but is highly modified * Based upon TinyConfig but is highly modified
* https://github.com/Minenash/TinyConfig * https://github.com/Minenash/TinyConfig
* *
* Note: floats don't work with this system, use doubles.
*
* Credits to Motschen * Credits to Motschen
* *
* @author coolGi * @author coolGi
* @version 5-21-2022 * @version 5-21-2022
*/ */
// FLOATS DONT WORK WITH THIS
/** This file is going to be removed sometime soon, please dont hook onto anything within this file until the new UI is compleated */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class ClassicConfigGUI public class ClassicConfigGUI
{ {
@@ -178,7 +178,7 @@ public class ClassicConfigGUI
} }
else else
{ {
((ConfigEntry) info).uiSetWithoutSaving(value.intValue()); ((ConfigEntry) info).uiSetWithoutSaving(value != null ? value.intValue() : 0);
} }
} }
@@ -249,7 +249,7 @@ public class ClassicConfigGUI
protected void init() protected void init()
{ {
super.init(); super.init();
if (!reload) if (!this.reload)
{ {
ConfigBase.INSTANCE.configFileINSTANCE.loadFromFile(); ConfigBase.INSTANCE.configFileINSTANCE.loadFromFile();
} }
@@ -276,7 +276,7 @@ public class ClassicConfigGUI
(buttonWidget) -> { (buttonWidget) -> {
ChangelogScreen changelogScreen = new ChangelogScreen(this); ChangelogScreen changelogScreen = new ChangelogScreen(this);
if (changelogScreen.usable) if (changelogScreen.usable)
Objects.requireNonNull(minecraft).setScreen(changelogScreen); Objects.requireNonNull(this.minecraft).setScreen(changelogScreen);
else else
LOGGER.warn("Changelog was not able to open"); LOGGER.warn("Changelog was not able to open");
}, },
@@ -286,17 +286,17 @@ public class ClassicConfigGUI
} }
addBtn(MakeBtn(Translatable("distanthorizons.general.cancel"), this.addBtn(MakeBtn(Translatable("distanthorizons.general.cancel"),
this.width / 2 - 154, this.height - 28, this.width / 2 - 154, this.height - 28,
150, 20, 150, 20,
button -> button ->
{ {
ConfigBase.INSTANCE.configFileINSTANCE.loadFromFile(); ConfigBase.INSTANCE.configFileINSTANCE.loadFromFile();
Objects.requireNonNull(minecraft).setScreen(parent); Objects.requireNonNull(this.minecraft).setScreen(this.parent);
})); }));
doneButton = addBtn(MakeBtn(Translatable("distanthorizons.general.done"), this.width / 2 + 4, this.height - 28, 150, 20, (button) -> { this.doneButton = this.addBtn(MakeBtn(Translatable("distanthorizons.general.done"), this.width / 2 + 4, this.height - 28, 150, 20, (button) -> {
ConfigBase.INSTANCE.configFileINSTANCE.saveToFile(); ConfigBase.INSTANCE.configFileINSTANCE.saveToFile();
Objects.requireNonNull(minecraft).setScreen(parent); Objects.requireNonNull(this.minecraft).setScreen(this.parent);
})); }));
this.list = new ConfigListWidget(this.minecraft, this.width * 2, this.height, 32, 32, 25); this.list = new ConfigListWidget(this.minecraft, this.width * 2, this.height, 32, 32, 25);
@@ -312,8 +312,8 @@ public class ClassicConfigGUI
{ {
try try
{ {
if (info.getCategory().matches(category) && info.getAppearance().showInGui) if (info.getCategory().matches(this.category) && info.getAppearance().showInGui)
addMenuItem(info); this.addMenuItem(info);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -336,7 +336,7 @@ public class ClassicConfigGUI
private void addMenuItem(AbstractConfigType info) private void addMenuItem(AbstractConfigType info)
{ {
initEntry(info, this.translationPrefix); initEntry(info, this.translationPrefix);
Component name = Translatable(translationPrefix + info.getNameWCategory()); Component name = Translatable(this.translationPrefix + info.getNameWCategory());
if (ConfigEntry.class.isAssignableFrom(info.getClass())) if (ConfigEntry.class.isAssignableFrom(info.getClass()))
@@ -345,7 +345,7 @@ public class ClassicConfigGUI
((ConfigEntry) info).uiSetWithoutSaving(((ConfigEntry) info).getDefaultValue()); ((ConfigEntry) info).uiSetWithoutSaving(((ConfigEntry) info).getDefaultValue());
((EntryInfo) info.guiValue).index = 0; ((EntryInfo) info.guiValue).index = 0;
this.reload = true; this.reload = true;
Objects.requireNonNull(minecraft).setScreen(this); Objects.requireNonNull(this.minecraft).setScreen(this);
}; };
int posX = this.width - ConfigScreenConfigs.SpaceFromRightScreen - 150 - ConfigScreenConfigs.ButtonWidthSpacing - ConfigScreenConfigs.ResetButtonWidth; int posX = this.width - ConfigScreenConfigs.SpaceFromRightScreen - 150 - ConfigScreenConfigs.ButtonWidthSpacing - ConfigScreenConfigs.ResetButtonWidth;
int posZ = 0; int posZ = 0;
@@ -359,17 +359,17 @@ public class ClassicConfigGUI
Map.Entry<Button.OnPress, Function<Object, Component>> widget = (Map.Entry<Button.OnPress, Function<Object, Component>>) ((EntryInfo) info.guiValue).widget; Map.Entry<Button.OnPress, Function<Object, Component>> widget = (Map.Entry<Button.OnPress, Function<Object, Component>>) ((EntryInfo) info.guiValue).widget;
if (info.getType().isEnum()) if (info.getType().isEnum())
{ {
widget.setValue(value -> Translatable(translationPrefix + "enum." + info.getType().getSimpleName() + "." + info.get().toString())); widget.setValue(value -> Translatable(this.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); this.list.addButton(MakeBtn(widget.getValue().apply(info.get()), this.width - 150 - ConfigScreenConfigs.SpaceFromRightScreen, 0, 150, 20, widget.getKey()), resetButton, null, name);
return; return;
} }
else if (((EntryInfo) info.guiValue).widget != null) else if (((EntryInfo) info.guiValue).widget != null)
{ {
EditBox widget = new EditBox(font, this.width - 150 - ConfigScreenConfigs.SpaceFromRightScreen + 2, 0, 150 - 4, 20, null); EditBox widget = new EditBox(this.font, this.width - 150 - ConfigScreenConfigs.SpaceFromRightScreen + 2, 0, 150 - 4, 20, Translatable(""));
widget.setMaxLength(150); widget.setMaxLength(150);
widget.insertText(String.valueOf(info.get())); widget.insertText(String.valueOf(info.get()));
Predicate<String> processor = ((BiFunction<EditBox, Button, Predicate<String>>) ((EntryInfo) info.guiValue).widget).apply(widget, doneButton); Predicate<String> processor = ((BiFunction<EditBox, Button, Predicate<String>>) ((EntryInfo) info.guiValue).widget).apply(widget, this.doneButton);
widget.setFilter(processor); widget.setFilter(processor);
this.list.addButton(widget, resetButton, null, name); this.list.addButton(widget, resetButton, null, name);
return; return;
@@ -379,7 +379,7 @@ public class ClassicConfigGUI
{ {
Button widget = MakeBtn(name, this.width / 2 - 100, this.height - 28, 100 * 2, 20, (button -> { Button widget = MakeBtn(name, this.width / 2 - 100, this.height - 28, 100 * 2, 20, (button -> {
ConfigBase.INSTANCE.configFileINSTANCE.saveToFile(); ConfigBase.INSTANCE.configFileINSTANCE.saveToFile();
Objects.requireNonNull(minecraft).setScreen(ClassicConfigGUI.getScreen(this.configBase, this, ((ConfigCategory) info).getDestination())); Objects.requireNonNull(this.minecraft).setScreen(ClassicConfigGUI.getScreen(this.configBase, this, ((ConfigCategory) info).getDestination()));
})); }));
this.list.addButton(widget, null, null, null); this.list.addButton(widget, null, null, null);
return; return;
@@ -420,16 +420,34 @@ public class ClassicConfigGUI
#endif #endif
this.list.render(matrices, mouseX, mouseY, delta); // Render buttons this.list.render(matrices, mouseX, mouseY, delta); // Render buttons
DhDrawCenteredString(matrices, font, title, width / 2, 15, 0xFFFFFF); // Render title // Render title
this.DhDrawCenteredString(matrices, this.font, this.title, this.width / 2, 15,
#if MC_VER < MC_1_21_6
0xFFFFFF // RGB white
#else
0xFFFFFFFF // ARGB white
#endif);
if (this.configBase.modID.equals("distanthorizons")) if (this.configBase.modID.equals("distanthorizons"))
{ {
// Display version // Display version
DhDrawString(matrices, font, TextOrLiteral(ModInfo.VERSION), 2, height - 10, 0xAAAAAA); this.DhDrawString(matrices, this.font, TextOrLiteral(ModInfo.VERSION), 2, this.height - 10,
#if MC_VER < MC_1_21_6
0xAAAAAA // RGB white
#else
0xFFAAAAAA // ARGB white
#endif);
// If the update is pending, display this message to inform the user that it will apply when the game restarts // If the update is pending, display this message to inform the user that it will apply when the game restarts
if (SelfUpdater.deleteOldJarOnJvmShutdown) if (SelfUpdater.deleteOldJarOnJvmShutdown)
DhDrawString(matrices, font, Translatable(configBase.modID + ".updater.waitingForClose"), 4, height - 38, 0xFFFFFF); {
this.DhDrawString(matrices, this.font, Translatable(this.configBase.modID + ".updater.waitingForClose"), 4, this.height - 38,
#if MC_VER < MC_1_21_6
0xFFFFFF // RGB white
#else
0xFFFFFFFF // ARGB white
#endif);
}
} }
@@ -659,8 +677,10 @@ public class ClassicConfigGUI
if (text != null && (!text.getString().contains("spacer") || button != null)) if (text != null && (!text.getString().contains("spacer") || button != null))
#if MC_VER < MC_1_20_1 #if MC_VER < MC_1_20_1
GuiComponent.drawString(matrices, textRenderer, text, 12, y + 5, 0xFFFFFF); GuiComponent.drawString(matrices, textRenderer, text, 12, y + 5, 0xFFFFFF);
#elif MC_VER < MC_1_21_6
matrices.drawString(textRenderer, this.text, 12, y + 5, 0xFFFFFF);
#else #else
matrices.drawString(textRenderer, text, 12, y + 5, 0xFFFFFF); matrices.drawString(textRenderer, this.text, 12, y + 5, 0xFFFFFFFF);
#endif #endif
} }
@@ -52,6 +52,27 @@ public class DhScreen extends Screen
{ {
renderTooltip(guiStack, comp, x, y); renderTooltip(guiStack, comp, x, y);
} }
#elif MC_VER < MC_1_21_6
protected void DhDrawCenteredString(GuiGraphics guiStack, Font font, Component text, int x, int y, int color)
{
guiStack.drawCenteredString(font, text, x, y, color);
}
protected void DhDrawString(GuiGraphics guiStack, Font font, Component text, int x, int y, int color)
{
guiStack.drawString(font, text, x, y, color);
}
//protected void DhRenderTooltip(GuiGraphics guiStack, Font font, List<? extends net.minecraft.util.FormattedCharSequence> text, int x, int y)
//{
// guiStack.renderTooltip(font, text, x, y);
//}
protected void DhRenderComponentTooltip(GuiGraphics guiStack, Font font, List<Component> comp, int x, int y)
{
guiStack.renderComponentTooltip(font, comp, x, y);
}
protected void DhRenderTooltip(GuiGraphics guiStack, Font font, Component text, int x, int y)
{
guiStack.renderTooltip(font, text, x, y);
}
#else #else
protected void DhDrawCenteredString(GuiGraphics guiStack, Font font, Component text, int x, int y, int color) protected void DhDrawCenteredString(GuiGraphics guiStack, Font font, Component text, int x, int y, int color)
{ {
@@ -61,17 +82,20 @@ public class DhScreen extends Screen
{ {
guiStack.drawString(font, text, x, y, color); guiStack.drawString(font, text, x, y, color);
} }
protected void DhRenderTooltip(GuiGraphics guiStack, Font font, List<? extends net.minecraft.util.FormattedCharSequence> text, int x, int y) //protected void DhRenderTooltip(GuiGraphics guiStack, Font font, List<? extends net.minecraft.util.FormattedCharSequence> text, int x, int y)
{ //{
guiStack.renderTooltip(font, text, x, y); // //guiStack.renderTooltip(font, text, x, y);
} //}
protected void DhRenderComponentTooltip(GuiGraphics guiStack, Font font, List<Component> comp, int x, int y) protected void DhRenderComponentTooltip(GuiGraphics guiStack, Font font, List<Component> comp, int x, int y)
{ {
guiStack.renderComponentTooltip(font, comp, x, y); guiStack.setComponentTooltipForNextFrame(font, comp, x, y);
} }
protected void DhRenderTooltip(GuiGraphics guiStack, Font font, Component text, int x, int y) protected void DhRenderTooltip(GuiGraphics guiStack, Font font, Component text, int x, int y)
{ {
guiStack.renderTooltip(font, text, x, y); guiStack.setTooltipForNextFrame(font, text, x, y);
} }
#endif #endif
} }
@@ -39,9 +39,13 @@ import net.minecraft.client.renderer.GameRenderer;
#elif MC_VER < MC_1_20_2 #elif MC_VER < MC_1_20_2
import net.minecraft.client.gui.components.ImageButton; import net.minecraft.client.gui.components.ImageButton;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
#elif MC_VER < MC_1_21_6
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.RenderType;
#else #else
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderPipelines;
#endif #endif
/** /**
@@ -172,12 +176,18 @@ public class TexturedButtonWidget extends Button
{ {
#if MC_VER < MC_1_21_3 #if MC_VER < MC_1_21_3
matrices.blitSprite(SPRITES.get(this.active, this.isHoveredOrFocused()), this.getX(), this.getY(), this.getWidth(), this.getHeight()); matrices.blitSprite(SPRITES.get(this.active, this.isHoveredOrFocused()), this.getX(), this.getY(), this.getWidth(), this.getHeight());
#else #elif MC_VER < MC_1_21_6
matrices.blitSprite( matrices.blitSprite(
RenderType::guiTextured, RenderType::guiTextured,
SPRITES.get(this.active, this.isHoveredOrFocused()), SPRITES.get(this.active, this.isHoveredOrFocused()),
this.getX(), this.getY(), this.getX(), this.getY(),
this.getWidth(), this.getHeight()); this.getWidth(), this.getHeight());
#else
matrices.blitSprite(
RenderPipelines.GUI_TEXTURED,
SPRITES.get(this.active, this.isHoveredOrFocused()),
this.getX(), this.getY(),
this.getWidth(), this.getHeight());
#endif #endif
} }
@@ -196,7 +206,7 @@ public class TexturedButtonWidget extends Button
#if MC_VER < MC_1_21_3 #if MC_VER < MC_1_21_3
matrices.blit(this.textureResourceLocation, this.getX(), this.getY(), this.u, this.v + (this.hoveredVOffset * i), this.width, this.height, this.textureWidth, this.textureHeight); matrices.blit(this.textureResourceLocation, this.getX(), this.getY(), this.u, this.v + (this.hoveredVOffset * i), this.width, this.height, this.textureWidth, this.textureHeight);
#else #elif MC_VER < MC_1_21_6
matrices.blit( matrices.blit(
RenderType::guiTextured, RenderType::guiTextured,
this.textureResourceLocation, this.textureResourceLocation,
@@ -204,6 +214,14 @@ public class TexturedButtonWidget extends Button
this.u, this.v + (this.hoveredVOffset * i), this.u, this.v + (this.hoveredVOffset * i),
this.width, this.height, this.width, this.height,
this.textureWidth, this.textureHeight); this.textureWidth, this.textureHeight);
#else
matrices.blit(
RenderPipelines.GUI_TEXTURED,
this.textureResourceLocation,
this.getX(), this.getY(),
this.u, this.v + (this.hoveredVOffset * i),
this.width, this.height,
this.textureWidth, this.textureHeight);
#endif #endif
} }
@@ -169,8 +169,10 @@ public class UpdateModScreen extends DhScreen
{ {
#if MC_VER < MC_1_20_2 #if MC_VER < MC_1_20_2
this.renderBackground(matrices); // Render background this.renderBackground(matrices); // Render background
#else #elif MC_VER < MC_1_21_6
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
#else
// background blur is already being rendered, rendering again causes the game to crash
#endif #endif
// TODO: add the tooltips for the buttons // TODO: add the tooltips for the buttons
@@ -178,16 +180,30 @@ public class UpdateModScreen extends DhScreen
// TODO: Add tooltips // TODO: Add tooltips
// Render the text's // Render the text's
DhDrawCenteredString(matrices, this.font, Translatable(ModInfo.ID + ".updater.text1"), this.width / 2, this.height / 2 - 35, 0xFFFFFF); this.DhDrawCenteredString(matrices, this.font,
DhDrawCenteredString(matrices, this.font, Translatable(ModInfo.ID + ".updater.text1"),
Translatable(ModInfo.ID + ".updater.text2", currentVer, nextVer), this.width / 2, this.height / 2 - 35,
this.width / 2, this.height / 2 - 20, 0x52FD52); #if MC_VER < MC_1_21_6
0xFFFFFF // RGB
#else
0xFFFFFFFF // ARGB
#endif
);
this.DhDrawCenteredString(matrices, this.font,
Translatable(ModInfo.ID + ".updater.text2", this.currentVer, this.nextVer),
this.width / 2, this.height / 2 - 20,
#if MC_VER < MC_1_21_6
0x52FD52 // RGB
#else
0xFF52FD52 // ARGB
#endif
);
} }
@Override @Override
public void onClose() public void onClose()
{ {
Objects.requireNonNull(minecraft).setScreen(this.parent); // Goto the parent screen Objects.requireNonNull(this.minecraft).setScreen(this.parent); // Go to the parent screen
} }
} }
@@ -21,7 +21,7 @@ package com.seibel.distanthorizons.common.wrappers.minecraft;
#if MC_VER < MC_1_21_5 #if MC_VER < MC_1_21_5
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
#elif MC_VER == MC_1_21_5 #elif MC_VER >= MC_1_21_5
import com.mojang.blaze3d.opengl.GlStateManager; import com.mojang.blaze3d.opengl.GlStateManager;
#endif #endif
@@ -233,7 +233,7 @@ public class MinecraftGLWrapper implements IMinecraftGLWrapper
GlStateManager._activeTexture(textureId); GlStateManager._activeTexture(textureId);
} }
@Override @Override
public int getActiveTexture() { return GL32.glGetInteger(GL32.GL_ACTIVE_TEXTURE); } public int getActiveTexture() { return GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D); }
/** /**
* Always binds to {@link GL32#GL_TEXTURE_2D} * Always binds to {@link GL32#GL_TEXTURE_2D}
@@ -33,9 +33,12 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.util.ColorUtil; import com.seibel.distanthorizons.core.util.ColorUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
#if MC_VER >= MC_1_17_1 #if MC_VER < MC_1_17_1
#elif MC_VER < MC_1_21_6
import net.minecraft.client.renderer.FogRenderer; import net.minecraft.client.renderer.FogRenderer;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
#else
import net.minecraft.client.renderer.fog.FogRenderer;
#endif #endif
#if MC_VER < MC_1_19_4 #if MC_VER < MC_1_19_4
@@ -43,8 +46,6 @@ import org.joml.Matrix4f;
import org.joml.Vector3f; import org.joml.Vector3f;
#else #else
#endif #endif
#if MC_VER >= MC_1_20_2
#endif
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
@@ -73,7 +74,6 @@ import org.joml.Vector4f;
#if MC_VER >= MC_1_21_5 #if MC_VER >= MC_1_21_5
import com.mojang.blaze3d.opengl.GlTexture; import com.mojang.blaze3d.opengl.GlTexture;
import org.lwjgl.opengl.GL32;
#endif #endif
/** /**
@@ -109,6 +109,11 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
public boolean colorTextureCastFailLogged = false; public boolean colorTextureCastFailLogged = false;
public boolean depthTextureCastFailLogged = false; public boolean depthTextureCastFailLogged = false;
#if MC_VER < MC_1_21_6
#else
private static FogRenderer mcFogRenderer = null;
#endif
//=========// //=========//
@@ -125,6 +130,16 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
@Override @Override
/** Unless you really need to know if the player is blind, use {@link MinecraftRenderWrapper#isFogStateSpecial()}/{@link IMinecraftRenderWrapper#isFogStateSpecial()} instead */ /** Unless you really need to know if the player is blind, use {@link MinecraftRenderWrapper#isFogStateSpecial()}/{@link IMinecraftRenderWrapper#isFogStateSpecial()} instead */
public boolean playerHasBlindingEffect() public boolean playerHasBlindingEffect()
{
if (MC.player == null)
{
return false;
}
else if (MC.player.getActiveEffectsMap() == null)
{
return false;
}
else
{ {
return MC.player.getActiveEffectsMap().get(MobEffects.BLINDNESS) != null return MC.player.getActiveEffectsMap().get(MobEffects.BLINDNESS) != null
#if MC_VER >= MC_1_19_2 #if MC_VER >= MC_1_19_2
@@ -132,6 +147,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
#endif #endif
; ;
} }
}
@Override @Override
public Vec3d getCameraExactPosition() public Vec3d getCameraExactPosition()
@@ -163,7 +179,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
Math.max(0f, Math.min(colorValues[2], 1f)), // b Math.max(0f, Math.min(colorValues[2], 1f)), // b
Math.max(0f, Math.min(colorValues[3], 1f)) // a Math.max(0f, Math.min(colorValues[3], 1f)) // a
); );
#else #elif MC_VER < MC_1_21_6
Vector4f colorValues = FogRenderer.computeFogColor(MC.gameRenderer.getMainCamera(), partialTicks, MC.level, 1, MC.gameRenderer.getDarkenWorldAmount(partialTicks)); Vector4f colorValues = FogRenderer.computeFogColor(MC.gameRenderer.getMainCamera(), partialTicks, MC.level, 1, MC.gameRenderer.getDarkenWorldAmount(partialTicks));
return new Color( return new Color(
Math.max(0f, Math.min(colorValues.x, 1f)), // r Math.max(0f, Math.min(colorValues.x, 1f)), // r
@@ -171,6 +187,31 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
Math.max(0f, Math.min(colorValues.z, 1f)), // b Math.max(0f, Math.min(colorValues.z, 1f)), // b
Math.max(0f, Math.min(colorValues.w, 1f)) // a Math.max(0f, Math.min(colorValues.w, 1f)) // a
); );
#else
if (mcFogRenderer == null)
{
mcFogRenderer = new FogRenderer();
}
if (MC.level == null)
{
// shouldn't happen, but just in case
return Color.white;
}
boolean isFoggy =
MC.level.effects().isFoggyAt(
MC.gameRenderer.getMainCamera().getBlockPosition().getX(),
MC.gameRenderer.getMainCamera().getBlockPosition().getZ())
|| MC.gui.getBossOverlay().shouldCreateWorldFog();
Vector4f colorValues = mcFogRenderer.setupFog(MC.gameRenderer.getMainCamera(), MC.options.getEffectiveRenderDistance(), isFoggy, MC.deltaTracker, MC.gameRenderer.getDarkenWorldAmount(MC.deltaTracker.getGameTimeDeltaPartialTick(true)), MC.level);
return new Color(
Math.max(0f, Math.min(colorValues.x, 1f)), // r
Math.max(0f, Math.min(colorValues.y, 1f)), // g
Math.max(0f, Math.min(colorValues.z, 1f)), // b
Math.max(0f, Math.min(colorValues.w, 1f)) // a
);
#endif #endif
} }
// getSpecialFogColor() is the same as getFogColor() // getSpecialFogColor() is the same as getFogColor()
@@ -54,8 +54,10 @@ public class ServerPlayerWrapper implements IServerPlayerWrapper
{ {
#if MC_VER < MC_1_20_1 #if MC_VER < MC_1_20_1
level = this.getServerPlayer().getLevel(); level = this.getServerPlayer().getLevel();
#else #elif MC_VER < MC_1_21_6
level = this.getServerPlayer().serverLevel(); level = this.getServerPlayer().serverLevel();
#else
level = this.getServerPlayer().level();
#endif #endif
} }
@@ -70,7 +72,14 @@ public class ServerPlayerWrapper implements IServerPlayerWrapper
} }
@Override @Override
public int getViewDistance() { return this.getServerPlayer().server.getPlayerList().getViewDistance(); } public int getViewDistance()
{
#if MC_VER < MC_1_21_6
return this.getServerPlayer().server.getPlayerList().getViewDistance();
#else
return this.getServerPlayer().getServer().getPlayerList().getViewDistance();
#endif
}
@Override @Override
public SocketAddress getRemoteAddress() public SocketAddress getRemoteAddress()
@@ -37,6 +37,7 @@ import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
#if MC_VER <= MC_1_20_4 #if MC_VER <= MC_1_20_4
import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.ChunkStatus;
@@ -66,6 +67,10 @@ public class ClientLevelWrapper implements IClientLevelWrapper
private final ClientLevel level; private final ClientLevel level;
private final ConcurrentHashMap<BlockState, ClientBlockStateColorCache> blockCache = new ConcurrentHashMap<>(); private final ConcurrentHashMap<BlockState, ClientBlockStateColorCache> blockCache = new ConcurrentHashMap<>();
/** cached method reference to reduce GC overhead */
private final Function<BlockState, ClientBlockStateColorCache> cachedBlockColorCacheFunction = (blockState) -> this.createBlockColorCache(blockState);
private BlockStateWrapper dirtBlockWrapper; private BlockStateWrapper dirtBlockWrapper;
private BiomeWrapper plainsBiomeWrapper; private BiomeWrapper plainsBiomeWrapper;
@Deprecated // TODO circular references are bad @Deprecated // TODO circular references are bad
@@ -105,14 +110,26 @@ public class ClientLevelWrapper implements IClientLevelWrapper
} }
} }
return LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.compute(level, (newLevel, levelRef) ->
{ WeakReference<ClientLevelWrapper> levelRef = LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.get(level);
if (levelRef != null) if (levelRef != null)
{ {
ClientLevelWrapper oldLevelWrapper = levelRef.get(); ClientLevelWrapper levelWrapper = levelRef.get();
if (levelWrapper != null)
{
return levelWrapper;
}
}
return LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.compute(level, (newLevel, newLevelRef) ->
{
if (newLevelRef != null)
{
ClientLevelWrapper oldLevelWrapper = newLevelRef.get();
if (oldLevelWrapper != null) if (oldLevelWrapper != null)
{ {
return levelRef; return newLevelRef;
} }
} }
@@ -162,10 +179,13 @@ public class ClientLevelWrapper implements IClientLevelWrapper
{ {
ClientBlockStateColorCache blockColorCache = this.blockCache.computeIfAbsent( ClientBlockStateColorCache blockColorCache = this.blockCache.computeIfAbsent(
((BlockStateWrapper) blockWrapper).blockState, ((BlockStateWrapper) blockWrapper).blockState,
(block) -> new ClientBlockStateColorCache(block, this)); this.cachedBlockColorCacheFunction);
return blockColorCache.getColor((BiomeWrapper) biome, pos); return blockColorCache.getColor((BiomeWrapper) biome, pos);
} }
/** used by {@link ClientLevelWrapper#cachedBlockColorCacheFunction} */
private ClientBlockStateColorCache createBlockColorCache(BlockState block) { return new ClientBlockStateColorCache(block, this); }
@Override @Override
public int getDirtBlockColor() public int getDirtBlockColor()
@@ -162,7 +162,7 @@ public class ChunkLoader
#if MC_VER < MC_1_18_2 #if MC_VER < MC_1_18_2
if (chunkType != ChunkStatus.ChunkType.LEVELCHUNK) if (chunkType != ChunkStatus.ChunkType.LEVELCHUNK)
return null; return null;
#else #elif MC_VER < MC_1_21_6
BlendingData blendingData = readBlendingData(tagLevel); BlendingData blendingData = readBlendingData(tagLevel);
#if MC_VER < MC_1_19_2 #if MC_VER < MC_1_19_2
@@ -172,27 +172,39 @@ public class ChunkLoader
if (chunkType == #if MC_VER < MC_1_20_6 ChunkStatus.ChunkType.PROTOCHUNK #else ChunkType.PROTOCHUNK #endif && blendingData == null) if (chunkType == #if MC_VER < MC_1_20_6 ChunkStatus.ChunkType.PROTOCHUNK #else ChunkType.PROTOCHUNK #endif && blendingData == null)
return null; return null;
#endif #endif
#else
// ignore blending data, there appears to be an issue with parsing it in 1.21.6
BlendingData blendingData = null;
if (chunkType == ChunkType.PROTOCHUNK)
{
return null;
}
#endif #endif
long inhabitedTime = tagGetLong(tagLevel, "InhabitedTime"); long inhabitedTime = tagGetLong(tagLevel, "InhabitedTime");
//================== Read params for making the LevelChunk ================== //================== Read params for making the LevelChunk ==================
UpgradeData upgradeData; UpgradeData upgradeData = UpgradeData.EMPTY;
#if MC_VER < MC_1_17_1 // commented out 2025-06-04 as a test to see if the upgrade data
upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10) // is actually necessary for DH or if it can be ignored
? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA)) // (if it can't be ignored we'll need to handle null responses from tagGetCompoundTag())
: UpgradeData.EMPTY; //
#elif MC_VER < MC_1_21_5 //#if MC_VER < MC_1_17_1
upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10) //upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10)
? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA), level) // ? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA))
: UpgradeData.EMPTY; // : UpgradeData.EMPTY;
#else //#elif MC_VER < MC_1_21_5
upgradeData = tagLevel.contains(TAG_UPGRADE_DATA) //upgradeData = tagLevel.contains(TAG_UPGRADE_DATA, 10)
? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA), level) // ? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA), level)
: UpgradeData.EMPTY; // : UpgradeData.EMPTY;
#endif //#else
//upgradeData = tagLevel.contains(TAG_UPGRADE_DATA)
// ? new UpgradeData(tagGetCompoundTag(tagLevel, TAG_UPGRADE_DATA), level)
// : UpgradeData.EMPTY;
//#endif
boolean isLightOn = tagGetBoolean(tagLevel, "isLightOn"); boolean isLightOn = tagGetBoolean(tagLevel, "isLightOn");
@@ -242,7 +254,7 @@ public class ChunkLoader
// Set some states after object creation // Set some states after object creation
chunk.setLightCorrect(isLightOn); chunk.setLightCorrect(isLightOn);
readHeightmaps(chunk, chunkData); readHeightmaps(chunk, chunkData);
readPostPocessings(chunk, chunkData); //readPostPocessings(chunk, chunkData);
return chunk; return chunk;
} }
private static LevelChunkSection[] readSections(LevelAccessor level, ChunkPos chunkPos, CompoundTag chunkData) private static LevelChunkSection[] readSections(LevelAccessor level, ChunkPos chunkPos, CompoundTag chunkData)
@@ -285,7 +297,12 @@ public class ChunkLoader
for (int j = 0; j < tagSections.size(); ++j) for (int j = 0; j < tagSections.size(); ++j)
{ {
CompoundTag tagSection = tagGetCompoundTag(tagSections, j); CompoundTag tagSection = tagGetCompoundTag(tagSections, j);
int sectionYPos = tagGetByte(tagSection, "Y"); if (tagSection == null)
{
continue;
}
final int sectionYPos = tagGetByte(tagSection, "Y");
#if MC_VER < MC_1_18_2 #if MC_VER < MC_1_18_2
if (tagSection.contains("Palette", 9) && tagSection.contains("BlockStates", 12)) if (tagSection.contains("Palette", 9) && tagSection.contains("BlockStates", 12))
@@ -309,6 +326,7 @@ public class ChunkLoader
PalettedContainer<Holder<Biome>> biomeContainer; PalettedContainer<Holder<Biome>> biomeContainer;
#endif #endif
boolean containsBlockStates; boolean containsBlockStates;
#if MC_VER < MC_1_21_5 #if MC_VER < MC_1_21_5
containsBlockStates = tagSection.contains("block_states", 10); containsBlockStates = tagSection.contains("block_states", 10);
@@ -391,11 +409,15 @@ public class ChunkLoader
#else ChunkType #endif #else ChunkType #endif
readChunkType(CompoundTag tagLevel) readChunkType(CompoundTag tagLevel)
{ {
ChunkStatus chunkStatus = ChunkStatus.byName(tagGetString(tagLevel,"Status")); String statusString = tagGetString(tagLevel,"Status");
if (statusString != null)
{
ChunkStatus chunkStatus = ChunkStatus.byName(statusString);
if (chunkStatus != null) if (chunkStatus != null)
{ {
return chunkStatus.getChunkType(); return chunkStatus.getChunkType();
} }
}
#if MC_VER <= MC_1_20_4 #if MC_VER <= MC_1_20_4
return ChunkStatus.ChunkType.PROTOCHUNK; return ChunkStatus.ChunkType.PROTOCHUNK;
@@ -406,6 +428,8 @@ public class ChunkLoader
private static void readHeightmaps(LevelChunk chunk, CompoundTag chunkData) private static void readHeightmaps(LevelChunk chunk, CompoundTag chunkData)
{ {
CompoundTag tagHeightmaps = tagGetCompoundTag(chunkData, "Heightmaps"); CompoundTag tagHeightmaps = tagGetCompoundTag(chunkData, "Heightmaps");
if (tagHeightmaps != null)
{
for (Heightmap.Types type : ChunkStatus.FULL.heightmapsAfter()) for (Heightmap.Types type : ChunkStatus.FULL.heightmapsAfter())
{ {
String heightmap = type.getSerializationKey(); String heightmap = type.getSerializationKey();
@@ -425,24 +449,31 @@ public class ChunkLoader
} }
#endif #endif
} }
Heightmap.primeHeightmaps(chunk, ChunkStatus.FULL.heightmapsAfter()); Heightmap.primeHeightmaps(chunk, ChunkStatus.FULL.heightmapsAfter());
} }
private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
{
ListTag tagPostProcessings = tagGetListTag(chunkData,"PostProcessing", 9);
for (int i = 0; i < tagPostProcessings.size(); ++i)
{
ListTag listTag3 = tagGetListTag(tagPostProcessings, i);
for (int j = 0; j < listTag3.size(); ++j)
{
#if MC_VER < MC_1_21_3
chunk.addPackedPostProcess(listTag3.getShort(j), i);
#else
chunk.addPackedPostProcess(ShortList.of(tagGetShort(listTag3, j)), i);
#endif
}
}
} }
// commented out as a test as of 2025-06-04 to see if this is actually necessary for DH
// DH probably doesn't need any chunk post-processing data
//private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
//{
// ListTag tagPostProcessings = tagGetListTag(chunkData,"PostProcessing", 9);
// if (tagPostProcessings != null)
// {
// for (int i = 0; i < tagPostProcessings.size(); ++i)
// {
// ListTag listTag3 = tagGetListTag(tagPostProcessings, i);
// for (int j = 0; j < listTag3.size(); ++j)
// {
// #if MC_VER < MC_1_21_3
// chunk.addPackedPostProcess(listTag3.getShort(j), i);
// #else
// chunk.addPackedPostProcess(ShortList.of(tagGetShort(listTag3, j)), i);
// #endif
// }
// }
// }
//}
#if MC_VER >= MC_1_18_2 #if MC_VER >= MC_1_18_2
private static BlendingData readBlendingData(CompoundTag chunkData) private static BlendingData readBlendingData(CompoundTag chunkData)
{ {
@@ -466,6 +497,7 @@ public class ChunkLoader
#if MC_VER < MC_1_21_3 #if MC_VER < MC_1_21_3
blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial((message) -> logParsingWarningOnce(message)).orElse(null); blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial((message) -> logParsingWarningOnce(message)).orElse(null);
#else #else
// blending data appears to have changed as of 1.21.6 causing a class cast exception here due to it being wrapped in a Java.Optional
blendingData = BlendingData.unpack(BlendingData.Packed.CODEC.parse(blendingDataTag).resultOrPartial((message) -> logParsingWarningOnce(message)).orElse(null)); blendingData = BlendingData.unpack(BlendingData.Packed.CODEC.parse(blendingDataTag).resultOrPartial((message) -> logParsingWarningOnce(message)).orElse(null));
#endif #endif
} }
@@ -728,6 +760,7 @@ public class ChunkLoader
/** defaults to null if the tag isn't present */ /** defaults to null if the tag isn't present */
@Nullable
private static String tagGetString(CompoundTag tag, String key) private static String tagGetString(CompoundTag tag, String key)
{ {
#if MC_VER < MC_1_21_5 #if MC_VER < MC_1_21_5
@@ -738,6 +771,7 @@ public class ChunkLoader
} }
/** defaults to null if the tag isn't present */ /** defaults to null if the tag isn't present */
@Nullable
private static byte[] tagGetByteArray(CompoundTag tag, String key) private static byte[] tagGetByteArray(CompoundTag tag, String key)
{ {
#if MC_VER < MC_1_21_5 #if MC_VER < MC_1_21_5
@@ -228,6 +228,14 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
modelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix()); modelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix());
#endif #endif
//LOGGER.info("\n\n" +
// "Level Render\n" +
// "Mc MVM: \n" + modelViewMatrix.toString() + "\n" +
// "Mc Proj: \n" + projectionMatrix.toString()
//);
this.clientApi.renderLods(ClientLevelWrapper.getWrapper(renderContext.world()), this.clientApi.renderLods(ClientLevelWrapper.getWrapper(renderContext.world()),
modelViewMatrix, modelViewMatrix,
projectionMatrix, projectionMatrix,
@@ -276,6 +284,17 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
modelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix()); modelViewMatrix = McObjectConverter.Convert(renderContext.positionMatrix());
#endif #endif
#if MC_VER < MC_1_21_6
// rendered in MixinLevelRenderer
#else
ClientApi.INSTANCE.renderDeferredLodsForShaders(ClientLevelWrapper.getWrapper(renderContext.world()),
ClientApi.RENDER_STATE.mcModelViewMatrix,
ClientApi.RENDER_STATE.mcProjectionMatrix,
ClientApi.RENDER_STATE.frameTime
);
#endif
this.clientApi.renderFade( this.clientApi.renderFade(
modelViewMatrix, modelViewMatrix,
projectionMatrix, projectionMatrix,
@@ -20,6 +20,7 @@
package com.seibel.distanthorizons.fabric; package com.seibel.distanthorizons.fabric;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import com.seibel.distanthorizons.api.enums.config.EDhApiMcRenderingFadeMode;
import com.seibel.distanthorizons.common.AbstractModInitializer; import com.seibel.distanthorizons.common.AbstractModInitializer;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.config.ConfigBase; import com.seibel.distanthorizons.core.config.ConfigBase;
@@ -126,7 +127,8 @@ public class FabricMain extends AbstractModInitializer implements ClientModIniti
} }
@Override @Override
protected void subscribeClientStartedEvent(Runnable eventHandler) { ClientLifecycleEvents.CLIENT_STARTED.register((mc) -> eventHandler.run()); } protected void subscribeClientStartedEvent(Runnable eventHandler)
{ ClientLifecycleEvents.CLIENT_STARTED.register((mc) -> eventHandler.run()); }
@Override @Override
protected void subscribeServerStartingEvent(Consumer<MinecraftServer> eventHandler) protected void subscribeServerStartingEvent(Consumer<MinecraftServer> eventHandler)
@@ -22,31 +22,51 @@ package com.seibel.distanthorizons.fabric.mixins.client;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import net.minecraft.client.Minecraft;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Camera; import net.minecraft.client.Camera;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import net.minecraft.world.effect.MobEffects; import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.FluidState;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import com.mojang.blaze3d.systems.RenderSystem;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
import net.minecraft.world.level.material.FogType; import net.minecraft.world.level.material.FogType;
#else import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import com.mojang.blaze3d.systems.RenderSystem;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#elif MC_VER < MC_1_21_6
import net.minecraft.world.level.material.FogType; import net.minecraft.world.level.material.FogType;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.mojang.blaze3d.shaders.FogShape; import com.mojang.blaze3d.shaders.FogShape;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import net.minecraft.client.renderer.FogParameters; import net.minecraft.client.renderer.FogParameters;
import org.joml.Vector4f; import org.joml.Vector4f;
import com.mojang.blaze3d.systems.RenderSystem;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#else
import net.minecraft.world.level.material.FogType;
import net.minecraft.client.renderer.fog.FogRenderer;
import net.minecraft.client.renderer.fog.FogData;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
#endif #endif
@Mixin(FogRenderer.class) @Mixin(FogRenderer.class)
@@ -66,18 +86,23 @@ public class MixinFogRenderer
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
@Inject(at = @At("RETURN"), method = "setupFog") @Inject(at = @At("RETURN"), method = "setupFog")
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float g, CallbackInfo callback) private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float g, CallbackInfo callback)
#else #elif MC_VER < MC_1_21_6
@Inject(at = @At("RETURN"), method = "setupFog", cancellable = true) @Inject(at = @At("RETURN"), method = "setupFog", cancellable = true)
private static void disableSetupFog(Camera camera, FogMode fogMode, Vector4f vector4f, float f, boolean bl, float g, CallbackInfoReturnable<FogParameters> callback) private static void disableSetupFog(Camera camera, FogMode fogMode, Vector4f vector4f, float f, boolean bl, float g, CallbackInfoReturnable<FogParameters> callback)
#else
@Unique
private static void unused()
#endif #endif
{ {
boolean cameraNotInFluid = cameraNotInFluid(camera); #if MC_VER < MC_1_21_6
boolean cancelFog = cancelFog(camera, fogMode);
#elif MC_VER < MC_1_21_6
boolean cancelFog = cancelFog(camera);
#else
boolean cancelFog = cancelFog();
#endif
Entity entity = camera.getEntity(); if (cancelFog)
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
if (!isSpecialFog && cameraNotInFluid && fogMode == FogMode.FOG_TERRAIN
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
&& !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get())
{ {
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE); RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
@@ -85,10 +110,74 @@ public class MixinFogRenderer
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE); RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE); RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
#else #elif MC_VER < MC_1_21_6
callback.setReturnValue(FogParameters.NO_FOG); callback.setReturnValue(FogParameters.NO_FOG);
#else
#endif #endif
} }
}
#if MC_VER < MC_1_21_6
#else
// In MC's FogRenderer they clamp the "renderDistanceEnd" fog field to the render distance,
// which prevents us from disabling the vanilla fog.
// This mixin fires after they set the "renderDistanceEnd" so we can change it.
@WrapOperation(
method = "setupFog",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/client/renderer/fog/FogData;renderDistanceEnd:F",
opcode = org.objectweb.asm.Opcodes.PUTFIELD
)
)
private void onSetRenderDistanceEnd(FogData instance, float value, Operation<Void> original)
{
if (cancelFog())
{
instance.environmentalStart = A_REALLY_REALLY_BIG_VALUE;
instance.environmentalEnd = A_EVEN_LARGER_VALUE;
instance.renderDistanceStart = A_REALLY_REALLY_BIG_VALUE;
instance.renderDistanceEnd = A_EVEN_LARGER_VALUE;
}
// Always call the original with the modified or original value
original.call(instance, value);
}
#endif
@Unique
#if MC_VER < MC_1_21_6
private static boolean cancelFog(Camera camera, FogMode fogMode)
#else
private static boolean cancelFog()
#endif
{
#if MC_VER < MC_1_21_6
Entity entity = camera.getEntity();
#else
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
Entity entity = camera.getEntity();
#endif
boolean cameraNotInFluid = cameraNotInFluid(camera);
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
boolean cancelFog = !isSpecialFog;
cancelFog = cancelFog && cameraNotInFluid;
#if MC_VER < MC_1_21_6
cancelFog = cancelFog && (fogMode == FogMode.FOG_TERRAIN);
#endif
cancelFog = cancelFog && !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial();
cancelFog = cancelFog && !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get();
return cancelFog;
} }
@Unique @Unique
@@ -105,4 +194,6 @@ public class MixinFogRenderer
return cameraNotInFluid; return cameraNotInFluid;
} }
} }
@@ -19,51 +19,54 @@
package com.seibel.distanthorizons.fabric.mixins.client; package com.seibel.distanthorizons.fabric.mixins.client;
import com.mojang.blaze3d.vertex.PoseStack;
#if MC_VER < MC_1_19_4 #if MC_VER < MC_1_19_4
import net.minecraft.client.renderer.RenderType;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f; import com.mojang.math.Matrix4f;
import org.lwjgl.opengl.GL32; import org.lwjgl.opengl.GL32;
#else import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#elif MC_VER < MC_1_21_6
import net.minecraft.client.renderer.RenderType;
import com.mojang.blaze3d.vertex.PoseStack;
import org.joml.Matrix4f; import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#else
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
import org.joml.Matrix4fc;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
#endif #endif
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter; import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper; import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi; import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.fabric.FabricClientProxy;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.Mat4f;
import net.minecraft.client.Camera; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LightTexture;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.RenderType;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/** import org.apache.logging.log4j.Logger;
* This class is used to mix in my rendering code
* before Minecraft starts rendering blocks.
* If this wasn't done, and we used Forge's
* render last event, the LODs would render on top
* of the normal terrain.
*
* This is also the mixin for rendering the clouds
*
* @author coolGi
* @author James Seibel
* @version 12-31-2021
*/
@Mixin(LevelRenderer.class) @Mixin(LevelRenderer.class)
public class MixinLevelRenderer public class MixinLevelRenderer
{ {
@Shadow @Shadow
private ClientLevel level; private ClientLevel level;
@Unique
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
@Inject(at = @At("HEAD"), @Inject(at = @At("HEAD"),
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V", method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V",
@@ -84,51 +87,65 @@ public class MixinLevelRenderer
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V", method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
cancellable = true) cancellable = true)
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double camX, double camY, double camZ, Matrix4f projectionMatrix, CallbackInfo callback) private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double camX, double camY, double camZ, Matrix4f projectionMatrix, CallbackInfo callback)
#else #elif MC_VER < MC_1_21_6
@Inject(at = @At("HEAD"), @Inject(at = @At("HEAD"),
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;DDDLorg/joml/Matrix4f;Lorg/joml/Matrix4f;)V", method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;DDDLorg/joml/Matrix4f;Lorg/joml/Matrix4f;)V",
cancellable = true) cancellable = true)
private void renderChunkLayer(RenderType renderType, double x, double y, double z, Matrix4f projectionMatrix, Matrix4f frustumMatrix, CallbackInfo callback) private void renderChunkLayer(RenderType renderType, double x, double y, double z, Matrix4f projectionMatrix, Matrix4f frustumMatrix, CallbackInfo callback)
#else
@Inject(at = @At("HEAD"), method = "prepareChunkRenders", cancellable = true)
private void prepareChunkRenders(Matrix4fc projectionMatrix, double d, double e, double f, CallbackInfoReturnable<ChunkSectionsToRender> callback)
#endif #endif
{ {
#if MC_VER == MC_1_16_5 #if MC_VER == MC_1_16_5
// get the matrices from the OpenGL fixed pipeline // get the matrices from the OpenGL fixed pipeline
float[] mcProjMatrixRaw = new float[16]; float[] mcProjMatrixRaw = new float[16];
GL32.glGetFloatv(GL32.GL_PROJECTION_MATRIX, mcProjMatrixRaw); GL32.glGetFloatv(GL32.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw); ClientApi.RENDER_STATE.mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
mcProjectionMatrix.transpose(); ClientApi.RENDER_STATE.mcProjectionMatrix.transpose();
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose()); ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
#elif MC_VER <= MC_1_20_4 #elif MC_VER <= MC_1_20_4
// get the matrices directly from MC // get the matrices directly from MC
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose()); ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix); ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
#else #else
// MC combined the model view and projection matricies // MC combined the model view and projection matricies
Mat4f mcModelViewMatrix = McObjectConverter.Convert(projectionMatrix); ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(projectionMatrix);
Mat4f mcProjectionMatrix = new Mat4f(); ClientApi.RENDER_STATE.mcProjectionMatrix = new Mat4f();
mcProjectionMatrix.setIdentity(); ClientApi.RENDER_STATE.mcProjectionMatrix.setIdentity();
#endif #endif
// TODO move this into a common place // TODO move this into a common place
float frameTime;
#if MC_VER < MC_1_21_1 #if MC_VER < MC_1_21_1
frameTime = Minecraft.getInstance().getFrameTime(); ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().getFrameTime();
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
frameTime = Minecraft.getInstance().getTimer().getRealtimeDeltaTicks(); ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().getTimer().getRealtimeDeltaTicks();
#else #else
frameTime = Minecraft.getInstance().deltaTracker.getRealtimeDeltaTicks(); ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().deltaTracker.getRealtimeDeltaTicks();
#endif #endif
//LOGGER.info("\n\n" +
// "Level Mixin\n" +
// "Mc MVM: \n" + mcModelViewMatrix.toString() + "\n" +
// "Mc Proj: \n" + mcProjectionMatrix.toString()
//);
#if MC_VER < MC_1_21_6
if (renderType.equals(RenderType.translucent())) if (renderType.equals(RenderType.translucent()))
{ {
ClientApi.INSTANCE.renderDeferredLods(ClientLevelWrapper.getWrapper(this.level), ClientApi.INSTANCE.renderDeferredLodsForShaders(ClientLevelWrapper.getWrapper(this.level),
mcModelViewMatrix, ClientApi.RENDER_STATE.mcModelViewMatrix,
mcProjectionMatrix, ClientApi.RENDER_STATE.mcProjectionMatrix,
frameTime ClientApi.RENDER_STATE.frameTime
); );
} }
#else
// rendering handled via Fabric Api render event
#endif
// FIXME completely disables rendering when sodium is installed // FIXME completely disables rendering when sodium is installed
if (Config.Client.Advanced.Debugging.lodOnlyMode.get()) if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
@@ -137,4 +154,6 @@ public class MixinLevelRenderer
} }
} }
} }
@@ -0,0 +1,48 @@
package com.seibel.distanthorizons.fabric.mixins.server;
#if MC_VER < MC_1_21_4
import net.minecraft.world.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(Entity.class)
public class MixinLevelTicks<T>
{
// dummy mixin to make the loader happy
}
#else
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
import net.minecraft.world.ticks.LevelTicks;
import net.minecraft.world.ticks.ScheduledTick;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(LevelTicks.class) // available in 1.18.2+, but only needed in 1.21.4+
public class MixinLevelTicks<T>
{
// TODO put in a common location
private static boolean isWorldGenThread()
{ return DependencySetupDoneCheck.isDone && DependencySetupDoneCheck.getIsCurrentThreadDistantGeneratorThread.get(); }
@Inject(method = "schedule", at = @At(value = "HEAD"), cancellable = true)
private void onChunkSave(ScheduledTick<T> tick, CallbackInfo ci)
{
// In MC 1.21.4 an error check was added to log attempting to schedule ticks for unloaded chunks
// this caused a lot of unnecessary errors when generating sand (FallingBlock.class).
if (isWorldGenThread())
{
ci.cancel();
}
}
}
#endif
@@ -8,7 +8,8 @@
"server.MixinEntity", "server.MixinEntity",
"server.MixinServerPlayer", "server.MixinServerPlayer",
"server.MixinTracingExecutor", "server.MixinTracingExecutor",
"server.MixinUtilBackgroundThread" "server.MixinUtilBackgroundThread",
"server.MixinLevelTicks"
], ],
"client": [ "client": [
"client.MixinClientLevel", "client.MixinClientLevel",
@@ -118,14 +118,14 @@ public class ForgeMain extends AbstractModInitializer
@Override @Override
protected void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler) protected void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler)
{ { MinecraftForge.EVENT_BUS.addListener((RegisterCommandsEvent e) -> { eventHandler.accept(e.getDispatcher()); }); }
MinecraftForge.EVENT_BUS.addListener((RegisterCommandsEvent e) -> { eventHandler.accept(e.getDispatcher()); });
}
@Override @Override
protected void subscribeClientStartedEvent(Runnable eventHandler) protected void subscribeClientStartedEvent(Runnable eventHandler)
{ {
// FIXME What event is this? // Just run the event handler, since there are no proper ClientLifecycleEvent for the client
// to signify readiness other than FmlClientSetupEvent
eventHandler.run();
} }
@Override @Override
@@ -156,7 +156,7 @@ public class MixinLevelRenderer
} }
else if (renderType.equals(RenderType.translucent())) else if (renderType.equals(RenderType.translucent()))
{ {
ClientApi.INSTANCE.renderDeferredLods(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, frameTime); ClientApi.INSTANCE.renderDeferredLodsForShaders(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, frameTime);
} }
// render fade // render fade
+3 -3
View File
@@ -5,7 +5,7 @@ org.gradle.caching=true
# Mod Info # Mod Info
mod_name=DistantHorizons mod_name=DistantHorizons
mod_version=2.3.3-b-dev mod_version=2.3.4-b
api_version=4.0.0 api_version=4.0.0
maven_group=com.seibel.distanthorizons maven_group=com.seibel.distanthorizons
mod_readable_name=Distant Horizons mod_readable_name=Distant Horizons
@@ -18,7 +18,7 @@ mod_issues=https://gitlab.com/jeseibel/distant-horizons/-/issues
mod_discord=https://discord.gg/xAB8G4cENx mod_discord=https://discord.gg/xAB8G4cENx
# Global Plugin Versions # Global Plugin Versions
manifold_version=2024.1.37 manifold_version=2025.1.20
# 2023.1.17 can be used if there are mystery Java compiler issues # 2023.1.17 can be used if there are mystery Java compiler issues
nightconfig_version=3.6.6 nightconfig_version=3.6.6
lz4_version=1.8.0 lz4_version=1.8.0
@@ -51,7 +51,7 @@ versionStr=
# This defines what MC version Intellij will use for the preprocessor # This defines what MC version Intellij will use for the preprocessor
# and what version is used automatically by build and run commands # and what version is used automatically by build and run commands
mcVer=1.21.5 mcVer=1.21.8
# Defines the maximum amount of memory Minecraft is allowed when run in a development environment # Defines the maximum amount of memory Minecraft is allowed when run in a development environment
#minecraftMemoryJavaArg="-Xmx4G" #minecraftMemoryJavaArg="-Xmx4G"
@@ -78,13 +78,6 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final Logger LOGGER = DhLoggerBuilder.getLogger(); private static final Logger LOGGER = DhLoggerBuilder.getLogger();
// private static SimpleChannel multiversePluginChannel;
// Not the cleanest way of passing this to the LOD renderer, but it'll have to do for now
public static Mat4f currentModelViewMatrix = new Mat4f();
public static Mat4f currentProjectionMatrix = new Mat4f();
@Override @Override
@@ -244,16 +237,7 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
// rendering // // rendering //
//===========// //===========//
@SubscribeEvent #if MC_VER < MC_1_21_6
public void beforeLevelRenderEvent(RenderLevelStageEvent event)
{
if (event.getStage() == RenderLevelStageEvent.Stage.AFTER_SKY)
{
currentModelViewMatrix = McObjectConverter.Convert(event.getModelViewMatrix());
currentProjectionMatrix = McObjectConverter.Convert(event.getProjectionMatrix());
}
}
@SubscribeEvent @SubscribeEvent
public void afterLevelRenderEvent(RenderLevelStageEvent event) public void afterLevelRenderEvent(RenderLevelStageEvent event)
{ {
@@ -272,6 +256,56 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
} }
} }
} }
#else
@SubscribeEvent
public void afterLevelEntityRenderEvent(RenderLevelStageEvent.AfterEntities event)
{
ClientApi.INSTANCE.renderFade(
ClientApi.RENDER_STATE.mcModelViewMatrix,
ClientApi.RENDER_STATE.mcProjectionMatrix,
ClientApi.RENDER_STATE.frameTime,
ClientLevelWrapper.getWrapper((ClientLevel)event.getLevel())
);
}
@SubscribeEvent
public void afterLevelTranslucentRenderEvent(RenderLevelStageEvent.AfterTranslucentBlocks event)
{
ClientApi.INSTANCE.renderDeferredLodsForShaders(ClientLevelWrapper.getWrapper((ClientLevel)event.getLevel()),
ClientApi.RENDER_STATE.mcModelViewMatrix,
ClientApi.RENDER_STATE.mcProjectionMatrix,
ClientApi.RENDER_STATE.frameTime
);
}
@SubscribeEvent
public void afterLevelRenderEvent(RenderLevelStageEvent.AfterLevel event)
{
try
{
// should generally only need to be set once per game session
// allows DH to render directly to Optifine's level frame buffer,
// allowing better shader support
MinecraftRenderWrapper.INSTANCE.finalLevelFrameBufferId = GL32.glGetInteger(GL32.GL_FRAMEBUFFER_BINDING);
}
catch (Exception | Error e)
{
LOGGER.error("Unexpected error in afterLevelRenderEvent: "+e.getMessage(), e);
}
ClientApi.INSTANCE.renderFadeOpaque(
ClientApi.RENDER_STATE.mcModelViewMatrix,
ClientApi.RENDER_STATE.mcProjectionMatrix,
ClientApi.RENDER_STATE.frameTime,
ClientLevelWrapper.getWrapper((ClientLevel)event.getLevel())
);
}
#endif
@@ -282,4 +316,5 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
private static LevelAccessor GetEventLevel(LevelEvent e) { return e.getLevel(); } private static LevelAccessor GetEventLevel(LevelEvent e) { return e.getLevel(); }
} }
@@ -23,7 +23,6 @@ import com.mojang.brigadier.CommandDispatcher;
import com.seibel.distanthorizons.common.AbstractModInitializer; import com.seibel.distanthorizons.common.AbstractModInitializer;
import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen; import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
import com.seibel.distanthorizons.core.api.internal.ClientApi; import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.api.internal.ServerApi; import com.seibel.distanthorizons.core.api.internal.ServerApi;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage; import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
@@ -51,9 +50,13 @@ import java.util.function.Consumer;
#if MC_VER < MC_1_20_6 #if MC_VER < MC_1_20_6
import net.neoforged.neoforge.client.ConfigScreenHandler; import net.neoforged.neoforge.client.ConfigScreenHandler;
#elif MC_VER < MC_1_21_8
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
import org.jetbrains.annotations.NotNull;
#else #else
import net.neoforged.neoforge.client.gui.IConfigScreenFactory; import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import net.neoforged.neoforge.client.network.event.RegisterClientPayloadHandlersEvent;
#endif #endif
/** /**
@@ -72,6 +75,11 @@ public class NeoforgeMain extends AbstractModInitializer
{ {
this.onInitializeClient(); this.onInitializeClient();
eventBus.addListener(this::registerNetworkingClientServer); eventBus.addListener(this::registerNetworkingClientServer);
#if MC_VER < MC_1_21_8
#else
eventBus.addListener(this::registerClientPayloadEvent);
#endif
}); });
// handles dedicated servers // handles dedicated servers
@@ -99,6 +107,12 @@ public class NeoforgeMain extends AbstractModInitializer
public void registerNetworkingServer(RegisterPayloadHandlersEvent event) public void registerNetworkingServer(RegisterPayloadHandlersEvent event)
{ NeoforgePluginPacketSender.setPacketHandler(event, ServerApi.INSTANCE::pluginMessageReceived); } { NeoforgePluginPacketSender.setPacketHandler(event, ServerApi.INSTANCE::pluginMessageReceived); }
#if MC_VER < MC_1_21_8
#else
public void registerClientPayloadEvent(RegisterClientPayloadHandlersEvent event)
{ NeoforgePluginPacketSender.registerClientPacketHandler(event); }
#endif
@@ -141,7 +155,9 @@ public class NeoforgeMain extends AbstractModInitializer
@Override @Override
protected void subscribeClientStartedEvent(Runnable eventHandler) protected void subscribeClientStartedEvent(Runnable eventHandler)
{ {
// FIXME What event is this? // Just run the event handler, since there are no proper ClientLifecycleEvent for the client
// to signify readiness other than FmlClientSetupEvent
eventHandler.run();
} }
@Override @Override
@@ -14,10 +14,19 @@ import java.util.Optional;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
#if MC_VER < MC_1_21_8
#else
import net.neoforged.neoforge.client.network.ClientPacketDistributor;
import net.neoforged.neoforge.client.network.event.RegisterClientPayloadHandlersEvent;
#endif
public class NeoforgePluginPacketSender extends AbstractPluginPacketSender public class NeoforgePluginPacketSender extends AbstractPluginPacketSender
{ {
private static BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> packetConsumer; private static BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> packetConsumer;
public static void setPacketHandler(RegisterPayloadHandlersEvent event, Consumer<AbstractNetworkMessage> consumer) public static void setPacketHandler(RegisterPayloadHandlersEvent event, Consumer<AbstractNetworkMessage> consumer)
{ setPacketHandler(event, (player, buffer) -> consumer.accept(buffer)); } { setPacketHandler(event, (player, buffer) -> consumer.accept(buffer)); }
public static void setPacketHandler(RegisterPayloadHandlersEvent event, BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> consumer) public static void setPacketHandler(RegisterPayloadHandlersEvent event, BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> consumer)
@@ -39,9 +48,31 @@ public class NeoforgePluginPacketSender extends AbstractPluginPacketSender
}); });
} }
#if MC_VER < MC_1_21_8
#else
public static void registerClientPacketHandler(RegisterClientPayloadHandlersEvent event)
{
// as of MC 1.21.7 Neo added a separate client network register
// https://github.com/neoforged/NeoForge/pull/2272
event.register(CommonPacketPayload.TYPE, (payload, context) ->
{
if (payload.message() != null)
{
packetConsumer.accept(null, payload.message());
}
});
}
#endif
@Override @Override
public void sendToServer(AbstractNetworkMessage message) public void sendToServer(AbstractNetworkMessage message)
{ PacketDistributor.sendToServer(new CommonPacketPayload(message)); } {
#if MC_VER < MC_1_21_8
PacketDistributor.sendToServer(new CommonPacketPayload(message));
#else
ClientPacketDistributor.sendToServer(new CommonPacketPayload(message));
#endif
}
@Override @Override
public void sendToClient(ServerPlayer serverPlayer, AbstractNetworkMessage message) public void sendToClient(ServerPlayer serverPlayer, AbstractNetworkMessage message)
@@ -22,67 +22,87 @@ package com.seibel.distanthorizons.neoforge.mixins.client;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import net.minecraft.client.Minecraft;
import org.spongepowered.asm.mixin.Mixin; 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.At;
import org.spongepowered.asm.mixin.injection.Inject;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Camera; import net.minecraft.client.Camera;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import net.minecraft.world.effect.MobEffects; import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.FluidState;
org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import com.mojang.blaze3d.systems.RenderSystem;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
import net.minecraft.world.level.material.FogType; import net.minecraft.world.level.material.FogType;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import com.mojang.blaze3d.systems.RenderSystem;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#elif MC_VER < MC_1_21_6
import net.minecraft.world.level.material.FogType;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.mojang.blaze3d.shaders.FogShape;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import net.minecraft.client.renderer.FogParameters;
import org.joml.Vector4f;
import com.mojang.blaze3d.systems.RenderSystem;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#else #else
import net.minecraft.client.renderer.FogParameters;
import net.minecraft.world.level.material.FogType; import net.minecraft.world.level.material.FogType;
import org.joml.Vector4f; import net.minecraft.client.renderer.fog.FogRenderer;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import net.minecraft.client.renderer.fog.FogData;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
#endif #endif
@Mixin(FogRenderer.class) @Mixin(FogRenderer.class)
public class MixinFogRenderer public class MixinFogRenderer
{ {
// Using this instead of Float.MAX_VALUE because Sodium don't like it. // Using this instead of Float.MAX_VALUE because Sodium don't like it.
@Unique
private static final float A_REALLY_REALLY_BIG_VALUE = 420694206942069.F; private static final float A_REALLY_REALLY_BIG_VALUE = 420694206942069.F;
@Unique
private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F; private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F;
#if MC_VER == MC_1_17_1 || MC_VER == MC_1_18_2 #if MC_VER < MC_1_19_2
@Inject(at = @At("RETURN"), @Inject(at = @At("RETURN"), method = "setupFog")
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V", private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, CallbackInfo callback)
remap = false)
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback)
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
@Inject(at = @At("RETURN"), @Inject(at = @At("RETURN"), method = "setupFog")
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V", private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float g, CallbackInfo callback)
remap = true) #elif MC_VER < MC_1_21_6
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback) @Inject(at = @At("RETURN"), method = "setupFog", cancellable = true)
private static void disableSetupFog(Camera camera, FogMode fogMode, Vector4f vector4f, float f, boolean bl, float g, CallbackInfoReturnable<FogParameters> callback)
#else #else
@Inject(at = @At("RETURN"), @Unique
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;Lorg/joml/Vector4f;FZF)Lnet/minecraft/client/renderer/FogParameters;", private static void unused()
remap = true, cancellable = true)
private static void disableSetupFog(Camera camera, FogMode fogMode, Vector4f vector4f, float f, boolean bl, float partTick, CallbackInfoReturnable<FogParameters> callback)
#endif #endif
{ {
boolean cameraNotInFluid = cameraNotInFluid(camera); #if MC_VER < MC_1_21_6
boolean cancelFog = cancelFog(camera, fogMode);
#elif MC_VER < MC_1_21_6
boolean cancelFog = cancelFog(camera);
#else
boolean cancelFog = cancelFog();
#endif
Entity entity = camera.getEntity(); if (cancelFog)
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
if (!isSpecialFog && cameraNotInFluid && fogMode == FogMode.FOG_TERRAIN
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
&& !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get())
{ {
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE); RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
@@ -90,12 +110,77 @@ public class MixinFogRenderer
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE); RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE); RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
#else #elif MC_VER < MC_1_21_6
callback.setReturnValue(FogParameters.NO_FOG); callback.setReturnValue(FogParameters.NO_FOG);
#else
#endif #endif
} }
} }
#if MC_VER < MC_1_21_6
#else
// In MC's FogRenderer they clamp the "renderDistanceEnd" fog field to the render distance,
// which prevents us from disabling the vanilla fog.
// This mixin fires after they set the "renderDistanceEnd" so we can change it.
@WrapOperation(
method = "setupFog",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/client/renderer/fog/FogData;renderDistanceEnd:F",
opcode = org.objectweb.asm.Opcodes.PUTFIELD
)
)
private void onSetRenderDistanceEnd(FogData instance, float value, Operation<Void> original)
{
if (cancelFog())
{
instance.environmentalStart = A_REALLY_REALLY_BIG_VALUE;
instance.environmentalEnd = A_EVEN_LARGER_VALUE;
instance.renderDistanceStart = A_REALLY_REALLY_BIG_VALUE;
instance.renderDistanceEnd = A_EVEN_LARGER_VALUE;
}
// Always call the original with the modified or original value
original.call(instance, value);
}
#endif
@Unique
#if MC_VER < MC_1_21_6
private static boolean cancelFog(Camera camera, FogMode fogMode)
#else
private static boolean cancelFog()
#endif
{
#if MC_VER < MC_1_21_6
Entity entity = camera.getEntity();
#else
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
Entity entity = camera.getEntity();
#endif
boolean cameraNotInFluid = cameraNotInFluid(camera);
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
boolean cancelFog = !isSpecialFog;
cancelFog = cancelFog && cameraNotInFluid;
#if MC_VER < MC_1_21_6
cancelFog = cancelFog && (fogMode == FogMode.FOG_TERRAIN);
#endif
cancelFog = cancelFog && !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial();
cancelFog = cancelFog && !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get();
return cancelFog;
}
@Unique
private static boolean cameraNotInFluid(Camera camera) private static boolean cameraNotInFluid(Camera camera)
{ {
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
@@ -110,4 +195,5 @@ public class MixinFogRenderer
} }
} }
@@ -19,39 +19,53 @@
package com.seibel.distanthorizons.neoforge.mixins.client; package com.seibel.distanthorizons.neoforge.mixins.client;
import com.mojang.blaze3d.systems.RenderSystem; #if MC_VER < MC_1_21_6
import com.mojang.blaze3d.vertex.PoseStack;
#if MC_VER < MC_1_19_4
import com.mojang.math.Matrix4f;
#else
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.neoforge.NeoforgeClientProxy;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LightTexture;
import org.joml.Matrix4f;
#endif
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
import org.joml.Matrix4f;
#else
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
import net.minecraft.client.Camera;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.LevelRenderer;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.joml.Vector4f;
import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
#endif
import org.apache.logging.log4j.Logger;
import com.seibel.distanthorizons.neoforge.NeoforgeClientProxy;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.coreapi.ModInfo;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique; 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.Inject;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#if MC_VER < MC_1_17_1
import org.lwjgl.opengl.GL15;
#endif
/** /**
* This class is used to mix in DH's rendering code * This class is used to mix in DH's rendering code
* before Minecraft starts rendering blocks. * before Minecraft starts rendering blocks.
@@ -70,73 +84,66 @@ public class MixinLevelRenderer
#endif #endif
private ClientLevel level; private ClientLevel level;
@Unique
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
#if MC_VER < MC_1_17_1
@Inject(at = @At("HEAD"),
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V", #if MC_VER < MC_1_21_6
cancellable = true) @Inject(at = @At("HEAD"), method = "renderSectionLayer", cancellable = true)
private void renderChunkLayer(RenderType renderType, PoseStack matrixStackIn, double xIn, double yIn, double zIn, CallbackInfo callback) private void renderChunkLayer(RenderType renderType, double x, double y, double z, Matrix4f modelViewMatrix, Matrix4f projectionMatrix, CallbackInfo callback)
#elif MC_VER < MC_1_19_4
@Inject(at = @At("HEAD"),
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V",
cancellable = true)
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
#elif MC_VER < MC_1_20_2
@Inject(at = @At("HEAD"),
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
cancellable = true)
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
#elif MC_VER < MC_1_20_6
@Inject(at = @At("HEAD"),
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLorg/joml/Matrix4f;)V",
cancellable = true)
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double camX, double camY, double camZ, Matrix4f projectionMatrix, CallbackInfo callback)
#else #else
@Inject(at = @At("HEAD"), @Inject(at = @At("HEAD"), method = "renderLevel", cancellable = true)
method = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;DDDLorg/joml/Matrix4f;Lorg/joml/Matrix4f;)V", private void onRenderLevel(GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker, boolean renderBlockOutline, Camera camera, Matrix4f positionMatrix, Matrix4f projectionMatrix, GpuBufferSlice gpuBufferSlice, Vector4f skyColor, boolean thinFog, CallbackInfo callback)
cancellable = true)
private void renderChunkLayer(RenderType renderType, double x, double y, double z, Matrix4f projectionMatrix, Matrix4f frustumMatrix, CallbackInfo callback)
#endif #endif
{ {
#if MC_VER == MC_1_16_5 #if MC_VER < MC_1_21_6
// get the matrices from the OpenGL fixed pipeline // MC combined the model view and projection matricies
float[] mcProjMatrixRaw = new float[16]; ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrix);
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw); ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
mcProjectionMatrix.transpose();
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
#elif MC_VER <= MC_1_20_4
// get the matrices directly from MC
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
#else #else
// get the matrices from neoForge's render event. ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
// We can't call the renderer there because we don't have access to the level that's being rendered
Mat4f mcModelViewMatrix = NeoforgeClientProxy.currentModelViewMatrix;
Mat4f mcProjectionMatrix = NeoforgeClientProxy.currentProjectionMatrix;
#endif #endif
//LOGGER.info("\n\n" +
// "Level Mixin\n" +
// "Mc MVM: \n" + ClientApi.RENDER_STATE.mcModelViewMatrix.toString() + "\n" +
// "Mc Proj: \n" + ClientApi.RENDER_STATE.mcProjectionMatrix.toString()
//);
float frameTime;
#if MC_VER < MC_1_21_1 #if MC_VER < MC_1_21_1
frameTime = Minecraft.getInstance().getFrameTime(); ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().getFrameTime();
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
frameTime = Minecraft.getInstance().getTimer().getRealtimeDeltaTicks(); ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().getTimer().getRealtimeDeltaTicks();
#else #else
frameTime = Minecraft.getInstance().deltaTracker.getRealtimeDeltaTicks(); ClientApi.RENDER_STATE.frameTime = Minecraft.getInstance().deltaTracker.getRealtimeDeltaTicks();
#endif #endif
#if MC_VER < MC_1_21_6
// only crash during development
if (ModInfo.IS_DEV_BUILD)
{
ClientApi.RENDER_STATE.canRenderOrThrow();
}
// render LODs // render LODs
if (renderType.equals(RenderType.solid())) if (renderType.equals(RenderType.solid()))
{ {
ClientApi.INSTANCE.renderLods(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, frameTime); ClientApi.INSTANCE.renderLods(ClientLevelWrapper.getWrapper(this.level),
ClientApi.RENDER_STATE.mcModelViewMatrix,
ClientApi.RENDER_STATE.mcProjectionMatrix,
ClientApi.RENDER_STATE.frameTime);
} }
else if (renderType.equals(RenderType.translucent())) else if (renderType.equals(RenderType.translucent()))
{ {
ClientApi.INSTANCE.renderDeferredLods(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, frameTime); ClientApi.INSTANCE.renderDeferredLodsForShaders(ClientLevelWrapper.getWrapper(this.level),
ClientApi.RENDER_STATE.mcModelViewMatrix,
ClientApi.RENDER_STATE.mcProjectionMatrix,
ClientApi.RENDER_STATE.frameTime);
} }
// render fade // render fade
@@ -146,21 +153,22 @@ public class MixinLevelRenderer
if (renderType.equals(RenderType.cutout())) if (renderType.equals(RenderType.cutout()))
{ {
ClientApi.INSTANCE.renderFadeOpaque( ClientApi.INSTANCE.renderFadeOpaque(
mcModelViewMatrix, ClientApi.RENDER_STATE.mcModelViewMatrix,
mcProjectionMatrix, ClientApi.RENDER_STATE.mcProjectionMatrix,
frameTime, ClientApi.RENDER_STATE.frameTime,
ClientLevelWrapper.getWrapper(this.level) ClientLevelWrapper.getWrapper(this.level)
); );
} }
else if (renderType.equals(RenderType.tripwire())) else if (renderType.equals(RenderType.tripwire()))
{ {
ClientApi.INSTANCE.renderFade( ClientApi.INSTANCE.renderFade(
mcModelViewMatrix, ClientApi.RENDER_STATE.mcModelViewMatrix,
mcProjectionMatrix, ClientApi.RENDER_STATE.mcProjectionMatrix,
frameTime, ClientApi.RENDER_STATE.frameTime,
ClientLevelWrapper.getWrapper(this.level) ClientLevelWrapper.getWrapper(this.level)
); );
} }
#endif
if (Config.Client.Advanced.Debugging.lodOnlyMode.get()) if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
{ {
@@ -169,4 +177,30 @@ public class MixinLevelRenderer
} }
#if MC_VER < MC_1_21_6
// formerly handled in renderChunkLayer()
#else
@Inject(at = @At("HEAD"), method = "prepareChunkRenders", cancellable = true)
private void renderChunkLayer(Matrix4fc modelViewMatrix, double d, double e, double f, CallbackInfoReturnable<ChunkSectionsToRender> callback)
{
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrix);
// only crash during development
if (ModInfo.IS_DEV_BUILD)
{
ClientApi.RENDER_STATE.canRenderOrThrow();
}
ClientApi.INSTANCE.renderLods(ClientLevelWrapper.getWrapper(this.level),
ClientApi.RENDER_STATE.mcModelViewMatrix,
ClientApi.RENDER_STATE.mcProjectionMatrix,
ClientApi.RENDER_STATE.frameTime);
}
#endif
} }
@@ -0,0 +1,46 @@
package com.seibel.distanthorizons.neoforge.mixins.server;
#if MC_VER < MC_1_21_4
import net.minecraft.world.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(Entity.class)
public class MixinLevelTicks<T>
{
// dummy mixin to make the loader happy
}
#else
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
import net.minecraft.world.ticks.LevelTicks;
import net.minecraft.world.ticks.ScheduledTick;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(LevelTicks.class) // available in 1.18.2+, but only needed in 1.21.4+
public class MixinLevelTicks<T>
{
// TODO put in a common location
private static boolean isWorldGenThread()
{ return DependencySetupDoneCheck.isDone && DependencySetupDoneCheck.getIsCurrentThreadDistantGeneratorThread.get(); }
@Inject(method = "schedule", at = @At(value = "HEAD"), cancellable = true)
private void onChunkSave(ScheduledTick<T> tick, CallbackInfo ci)
{
// In MC 1.21.4 an error check was added to log attempting to schedule ticks for unloaded chunks
// this caused a lot of unnecessary errors when generating sand (FallingBlock.class).
if (isWorldGenThread())
{
ci.cancel();
}
}
}
#endif
@@ -8,7 +8,8 @@
"server.MixinServerPlayer", "server.MixinServerPlayer",
"server.MixinTFChunkGenerator", "server.MixinTFChunkGenerator",
"server.MixinTracingExecutor", "server.MixinTracingExecutor",
"server.MixinUtilBackgroundThread" "server.MixinUtilBackgroundThread",
"server.MixinLevelTicks"
], ],
"client": [ "client": [
"client.MixinClientPacketListener", "client.MixinClientPacketListener",
@@ -3,6 +3,8 @@ loaderVersion = "*" # // mandatory. Allow all forge versions as we are definding
license = "LGPL" license = "LGPL"
issueTrackerURL = "${issues}" issueTrackerURL = "${issues}"
# https://docs.neoforged.net/docs/gettingstarted/modfiles/#neoforgemodstoml
[[mods]] #//mandatory [[mods]] #//mandatory
modId = "distanthorizons" #//mandatory modId = "distanthorizons" #//mandatory
@@ -33,3 +35,10 @@ issueTrackerURL = "${issues}"
versionRange = "${compatible_forgemc_versions}" # Where we set what version of mc it is avalible for versionRange = "${compatible_forgemc_versions}" # Where we set what version of mc it is avalible for
ordering = "NONE" ordering = "NONE"
side = "BOTH" side = "BOTH"
[[dependencies.distanthorizons]]
modId = "neoforge"
type = "required"
versionRange = "${neoforge_version_range}"
ordering = "NONE"
side = "BOTH"
+4
View File
@@ -24,6 +24,7 @@ fabric_api_version=0.42.0+1.16
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "*" } fabric_incompatibility_list={ "iris": "*" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -43,6 +44,9 @@ fabric_api_version=0.42.0+1.16
# Forge loader # Forge loader
forge_version=36.2.39 forge_version=36.2.39
# Neo not used but the variable still needs to be defined to make gradle happy
neoforge_version_range=[*,)
# Forge mod versions # Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version=4044290 terraforged_version=4044290
+4
View File
@@ -24,6 +24,7 @@ fabric_api_version=0.46.1+1.17
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "*" } fabric_incompatibility_list={ "iris": "*" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -42,6 +43,9 @@ fabric_api_version=0.46.1+1.17
# Forge loader # Forge loader
forge_version=37.1.1 forge_version=37.1.1
# Neo not used but the variable still needs to be defined to make gradle happy
neoforge_version_range=[*,)
# Forge mod versions # Forge mod versions
starlight_version_forge=3457784 starlight_version_forge=3457784
terraforged_version= terraforged_version=
+4
View File
@@ -25,6 +25,7 @@ fabric_api_version=0.76.0+1.18.2
immersive_portals_version=v1.4.11-1.18 immersive_portals_version=v1.4.11-1.18
canvas_version=mc118:1.0.2616 canvas_version=mc118:1.0.2616
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "*" } fabric_incompatibility_list={ "iris": "*" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -51,6 +52,9 @@ quilted_api_version=1.0.0-beta.28+0.67.0-1.18.2
# Forge loader # Forge loader
forge_version=40.2.10 forge_version=40.2.10
# Neo not used but the variable still needs to be defined to make gradle happy
neoforge_version_range=[*,)
# Forge mod versions # Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+4
View File
@@ -24,6 +24,7 @@ fabric_api_version=0.76.1+1.19.2
immersive_portals_version= immersive_portals_version=
canvas_version=mc119-1.0.2480 canvas_version=mc119-1.0.2480
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "*" } fabric_incompatibility_list={ "iris": "*" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -42,6 +43,9 @@ fabric_api_version=0.76.1+1.19.2
# Forge loader # Forge loader
forge_version=43.3.2 forge_version=43.3.2
# Neo not used but the variable still needs to be defined to make gradle happy
neoforge_version_range=[*,)
# Forge mod versions # Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+4
View File
@@ -23,6 +23,7 @@ fabric_api_version=0.87.1+1.19.4
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "*" } fabric_incompatibility_list={ "iris": "*" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -41,6 +42,9 @@ fabric_api_version=0.87.1+1.19.4
# Forge loader # Forge loader
forge_version=45.2.4 forge_version=45.2.4
# Neo not used but the variable still needs to be defined to make gradle happy
neoforge_version_range=[*,)
# Forge mod versions # Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+4
View File
@@ -23,6 +23,7 @@ fabric_api_version=0.90.4+1.20.1
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "<=1.7.4" } fabric_incompatibility_list={ "iris": "<=1.7.4" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -41,6 +42,9 @@ fabric_api_version=0.90.4+1.20.1
# Forge loader # Forge loader
forge_version=47.2.1 forge_version=47.2.1
# Neo not used but the variable still needs to be defined to make gradle happy
neoforge_version_range=[*,)
# Forge mod versions # Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+4
View File
@@ -23,6 +23,7 @@ fabric_api_version=0.90.4+1.20.2
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "<=1.7.4" } fabric_incompatibility_list={ "iris": "<=1.7.4" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -41,6 +42,9 @@ fabric_api_version=0.90.4+1.20.2
# Forge loader # Forge loader
forge_version=48.0.13 forge_version=48.0.13
# Neo not used but the variable still needs to be defined to make gradle happy
neoforge_version_range=[*,)
# Forge mod versions # Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+4 -1
View File
@@ -24,6 +24,7 @@ fabric_api_version=0.91.2+1.20.4
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "<=1.7.4" } fabric_incompatibility_list={ "iris": "<=1.7.4" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -42,7 +43,9 @@ fabric_api_version=0.91.2+1.20.4
# (Neo)Forge loader # (Neo)Forge loader
forge_version=49.1.13 forge_version=49.1.13
neoforge_version=20.4.233 neoforge_version=20.4.246
neoforge_version_range=[*,)
# (Neo)Forge mod versions # (Neo)Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+4 -1
View File
@@ -24,6 +24,7 @@ fabric_api_version=0.97.8+1.20.6
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "<=1.7.4" } fabric_incompatibility_list={ "iris": "<=1.7.4" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -42,7 +43,9 @@ fabric_api_version=0.97.8+1.20.6
# (Neo)Forge loader # (Neo)Forge loader
forge_version=50.0.19 forge_version=50.0.19
neoforge_version=20.6.70-beta neoforge_version=20.6.136
neoforge_version_range=[*,)
# (Neo)Forge mod versions # (Neo)Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+4 -1
View File
@@ -24,6 +24,7 @@ fabric_api_version=0.115.0+1.21.1
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API
fabric_incompatibility_list={ "iris": "<=1.7.4" } fabric_incompatibility_list={ "iris": "<=1.7.4" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -42,7 +43,9 @@ fabric_api_version=0.115.0+1.21.1
# (Neo)Forge loader # (Neo)Forge loader
forge_version= forge_version=
neoforge_version=21.1.92 neoforge_version=21.1.192
neoforge_version_range=[*,)
# (Neo)Forge mod versions # (Neo)Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+3 -1
View File
@@ -43,7 +43,9 @@ fabric_api_version=0.110.0+1.21.3
# (Neo)Forge loader # (Neo)Forge loader
forge_version= forge_version=
neoforge_version=21.3.11-beta neoforge_version=21.3.86
neoforge_version_range=[*,)
# (Neo)Forge mod versions # (Neo)Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+4 -1
View File
@@ -42,7 +42,10 @@ fabric_api_version=0.110.5+1.21.4
# (Neo)Forge loader # (Neo)Forge loader
forge_version= forge_version=
neoforge_version=21.4.3-beta neoforge_version=21.4.147
# version range may not be necessary, but having compiled DH for an older version caused issues with shaders
neoforge_version_range=[21.4.147,)
# (Neo)Forge mod versions # (Neo)Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+5 -3
View File
@@ -1,4 +1,4 @@
# 1.21.4 version # 1.21.5 version
java_version=21 java_version=21
minecraft_version=1.21.5 minecraft_version=1.21.5
parchment_version=1.21:2024.07.28 parchment_version=1.21:2024.07.28
@@ -23,7 +23,7 @@ fabric_api_version=0.119.5+1.21.5
immersive_portals_version= immersive_portals_version=
canvas_version= canvas_version=
# some versions of 1.8.11 nightly builds may not work, but the ones after 2025-03-30 should # Iris - some versions of 1.8.11 nightly builds may not work, but the ones after 2025-03-30 should
fabric_incompatibility_list={ "iris": "<=1.8.10" } fabric_incompatibility_list={ "iris": "<=1.8.10" }
fabric_recommend_list={} fabric_recommend_list={}
@@ -42,7 +42,9 @@ fabric_api_version=0.119.5+1.21.5
# (Neo)Forge loader # (Neo)Forge loader
forge_version= forge_version=
neoforge_version=21.5.0-beta neoforge_version=21.5.87
neoforge_version_range=[*,)
# (Neo)Forge mod versions # (Neo)Forge mod versions
starlight_version_forge= starlight_version_forge=
terraforged_version= terraforged_version=
+58
View File
@@ -0,0 +1,58 @@
# 1.21.6 version
java_version=21
minecraft_version=1.21.6
parchment_version=1.21:2024.07.28
compatible_minecraft_versions=["1.21.6"]
accessWidenerVersion=1_21_4
builds_for=fabric,neoforge
# forge is broken due to gradle/build script issues
# Netty
netty_version=4.1.97.Final
# Fabric loader
fabric_loader_version=0.16.13
fabric_api_version=0.127.0+1.21.6
modmenu_version=15.0.0-beta.2
starlight_version_fabric=
phosphor_version_fabric=
lithium_version=
sodium_version=mc1.21.6-0.6.13-fabric
iris_version=1.9.0+1.21.6-fabric
bclib_version=
immersive_portals_version=
canvas_version=
fabric_incompatibility_list={ }
fabric_recommend_list={}
# Fabric 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=0
enable_phosphor=0
enable_sodium=1
enable_lithium=0
enable_iris=1
enable_bclib=0
enable_immersive_portals=0
enable_canvas=0
# (Neo)Forge loader
forge_version=
neoforge_version=21.6.20-beta
# around 6.19 neo changed how their render API works, failing to meet this causes the game to crash
neoforge_version_range=[21.6.19-beta,)
# (Neo)Forge mod versions
starlight_version_forge=
terraforged_version=
# (Neo)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=0
enable_terrafirmacraft=0
+58
View File
@@ -0,0 +1,58 @@
# 1.21.7 version
java_version=21
minecraft_version=1.21.8
parchment_version=1.21:2024.07.28
compatible_minecraft_versions=["1.21.8"]
accessWidenerVersion=1_21_4
builds_for=fabric,neoforge
# forge is broken due to gradle/build script issues
# Netty
netty_version=4.1.97.Final
# Fabric loader
fabric_loader_version=0.16.13
fabric_api_version=0.129.0+1.21.8
modmenu_version=15.0.0-beta.3
starlight_version_fabric=
phosphor_version_fabric=
lithium_version=
sodium_version=mc1.21.6-0.6.13-fabric
iris_version=1.9.1+1.21.7-fabric
bclib_version=
immersive_portals_version=
canvas_version=
fabric_incompatibility_list={ }
fabric_recommend_list={}
# Fabric 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=0
enable_phosphor=0
enable_sodium=1
enable_lithium=0
enable_iris=1
enable_bclib=0
enable_immersive_portals=0
enable_canvas=0
# (Neo)Forge loader
forge_version=
neoforge_version=21.8.2-beta
# around 6.19 neo changed how their render API works, failing to meet this causes the game to crash
neoforge_version_range=[*,)
# (Neo)Forge mod versions
starlight_version_forge=
terraforged_version=
# (Neo)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=0
enable_terrafirmacraft=0