Compare commits
69 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d360402bc3 | |||
| 6c56d09b18 | |||
| 2716059840 | |||
| a60887e9a7 | |||
| 1b6c5a451a | |||
| 4e91911e58 | |||
| bfae194919 | |||
| e562b2fdca | |||
| 47fa6d7d8b | |||
| 053d1333ca | |||
| 961c4190ad | |||
| 2f2ac0859c | |||
| b59781b064 | |||
| 39cc5bb8aa | |||
| abdbc73865 | |||
| 596f9f834a | |||
| 8f2aaf4ef4 | |||
| 2320740a4a | |||
| 4f0dc07995 | |||
| 336a9a94c8 | |||
| 1158496d9d | |||
| 84479ed48c | |||
| 0c71ca96c6 | |||
| 43dff26063 | |||
| 3cba883ba2 | |||
| 2d2e7524ae | |||
| e8ff7abaea | |||
| 008ad52bbc | |||
| d0b44a1ffc | |||
| 4ffe430686 | |||
| 19ca97c6c1 | |||
| 3334394bfd | |||
| 180e7cd814 | |||
| 84cf4505f2 | |||
| 1d74eea3ef | |||
| 6ee2e6be25 | |||
| b5c47d67cb | |||
| ead59d0817 | |||
| 1c9229c8f1 | |||
| 968a14c6a5 | |||
| 5608db9c56 | |||
| 81b6a25805 | |||
| 276d90b3e6 | |||
| 851c7439d5 | |||
| c902357a8f | |||
| 63170078f5 | |||
| d0dd1f125b | |||
| 32950d793e | |||
| 54e9bad907 | |||
| bb4ac770bd | |||
| 16afada6e9 | |||
| 7d0785a5fa | |||
| 6a67df462b | |||
| 0c45c76ff8 | |||
| bcb442e38d | |||
| 977ae471ea | |||
| b1701ab0d0 | |||
| c048d5cb56 | |||
| 2702f742d6 | |||
| 7add025c8a | |||
| 9dc220feb2 | |||
| 79955252c9 | |||
| bf13cc48a3 | |||
| cf454c80d7 | |||
| e6404cd882 | |||
| 52e64dc403 | |||
| 7c858afc5d | |||
| a44a5d7465 | |||
| f2d373b779 |
+39
-8
@@ -5,6 +5,9 @@ import org.apache.tools.zip.ZipEntry
|
|||||||
import javax.annotation.Nonnull
|
import javax.annotation.Nonnull
|
||||||
import org.apache.tools.zip.ZipOutputStream
|
import org.apache.tools.zip.ZipOutputStream
|
||||||
|
|
||||||
|
import java.util.function.Function
|
||||||
|
import java.util.function.Predicate
|
||||||
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id "java"
|
id "java"
|
||||||
@@ -73,12 +76,23 @@ writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex)
|
|||||||
rootProject.versionStr = rootProject.mod_version + "-" + rootProject.minecraft_version // + "-" + new Date().format("yyyy_MM_dd_HH_mm")
|
rootProject.versionStr = rootProject.mod_version + "-" + rootProject.minecraft_version // + "-" + new Date().format("yyyy_MM_dd_HH_mm")
|
||||||
|
|
||||||
class NativeTransformer implements Transformer {
|
class NativeTransformer implements Transformer {
|
||||||
|
private Predicate<String> fileMatcher
|
||||||
|
private Function<String, String> filePathMapper
|
||||||
|
|
||||||
private final HashMap<String, String> replacements = new HashMap()
|
private final HashMap<String, String> replacements = new HashMap()
|
||||||
private final HashMap<String, byte[]> rewrittenFiles = new HashMap()
|
private final HashMap<String, byte[]> rewrittenFiles = new HashMap()
|
||||||
private var nativeRelocator
|
private var nativeRelocator
|
||||||
|
|
||||||
public File rootDir
|
public File rootDir
|
||||||
|
|
||||||
|
void matchFiles(Predicate<String> matcher) {
|
||||||
|
fileMatcher = matcher
|
||||||
|
}
|
||||||
|
|
||||||
|
void mapPaths(Function<String, String> mapper) {
|
||||||
|
filePathMapper = mapper
|
||||||
|
}
|
||||||
|
|
||||||
void relocateNative(String target, String replacement) {
|
void relocateNative(String target, String replacement) {
|
||||||
if (replacement.length() > target.length()) {
|
if (replacement.length() > target.length()) {
|
||||||
throw new GradleException("Length of value \"${replacement}\" exceeds the length of \"${target}\": ${replacement.length()} > ${target.length()}")
|
throw new GradleException("Length of value \"${replacement}\" exceeds the length of \"${target}\": ${replacement.length()} > ${target.length()}")
|
||||||
@@ -89,9 +103,7 @@ class NativeTransformer implements Transformer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean canTransformResource(@Nonnull FileTreeElement element) {
|
boolean canTransformResource(@Nonnull FileTreeElement element) {
|
||||||
return replacements.keySet().stream().anyMatch {
|
return fileMatcher.test(element.name)
|
||||||
element.name.startsWith(it as String)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -103,11 +115,9 @@ class NativeTransformer implements Transformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Map.Entry<String, String> pathReplacement = replacements.entrySet().stream().filter {
|
String path = filePathMapper != null
|
||||||
context.path.startsWith(it.key as String)
|
? filePathMapper.apply(context.path)
|
||||||
}.findFirst().orElseThrow()
|
: context.path
|
||||||
|
|
||||||
String path = context.path.replace(pathReplacement.key as String, pathReplacement.value as String)
|
|
||||||
content = nativeRelocator.processBinary(path, content, replacements)
|
content = nativeRelocator.processBinary(path, content, replacements)
|
||||||
|
|
||||||
rewrittenFiles.put(path, content)
|
rewrittenFiles.put(path, content)
|
||||||
@@ -351,10 +361,31 @@ subprojects { p ->
|
|||||||
|
|
||||||
transform(NativeTransformer) {
|
transform(NativeTransformer) {
|
||||||
rootDir = project.rootDir
|
rootDir = project.rootDir
|
||||||
|
|
||||||
|
matchFiles { it.startsWith("org/sqlite") }
|
||||||
|
mapPaths { it.replace("org/sqlite", "dh_sqlite") }
|
||||||
|
|
||||||
relocateNative "org/sqlite", "dh_sqlite"
|
relocateNative "org/sqlite", "dh_sqlite"
|
||||||
relocateNative "org_sqlite", "dh_1sqlite"
|
relocateNative "org_sqlite", "dh_1sqlite"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ZStd
|
||||||
|
// librariesLocation isn't used because it's too long for replacing paths in native libraries
|
||||||
|
// Allowing strings larger than the original string would require shifting the entire binary's contents
|
||||||
|
relocate "com.github.luben", "dhcomgithubluben"
|
||||||
|
relocate "libzstd-jni", "libzstd-jni_dh"
|
||||||
|
relocate "zstd-jni", "zstd-jni_dh"
|
||||||
|
|
||||||
|
transform(NativeTransformer) {
|
||||||
|
rootDir = project.rootDir
|
||||||
|
|
||||||
|
matchFiles { it.contains("libzstd-jni") && !it.contains("aix/ppc64") }
|
||||||
|
mapPaths { it.replace("libzstd-jni", "libzstd-jni_dh") }
|
||||||
|
|
||||||
|
relocateNative "com/github/luben", "dhcomgithubluben"
|
||||||
|
relocateNative "com_github_luben", "dhcomgithubluben"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// JOML
|
// JOML
|
||||||
if (project.hasProperty("embed_joml") && embed_joml == "true")
|
if (project.hasProperty("embed_joml") && embed_joml == "true")
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import com.seibel.distanthorizons.core.config.ConfigHandler;
|
|||||||
import com.seibel.distanthorizons.core.config.eventHandlers.presets.ThreadPresetConfigEventHandler;
|
import com.seibel.distanthorizons.core.config.eventHandlers.presets.ThreadPresetConfigEventHandler;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
|
import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
|
||||||
import com.seibel.distanthorizons.core.jar.ModJarInfo;
|
import com.seibel.distanthorizons.core.jar.ModJarInfo;
|
||||||
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
@@ -26,7 +27,6 @@ import net.minecraft.server.MinecraftServer;
|
|||||||
import net.minecraft.server.dedicated.DedicatedServer;
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandles;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@@ -166,6 +166,10 @@ public abstract class AbstractModInitializer
|
|||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
ModAccessorInjector.INSTANCE.bind((Class<? extends IModAccessor>) accessorClass, accessorConstructor.get());
|
ModAccessorInjector.INSTANCE.bind((Class<? extends IModAccessor>) accessorClass, accessorConstructor.get());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOGGER.debug("Skipping mod compatibility accessor for: ["+modId+"]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initConfig()
|
private void initConfig()
|
||||||
@@ -236,8 +240,7 @@ public abstract class AbstractModInitializer
|
|||||||
if (showChatWarnings)
|
if (showChatWarnings)
|
||||||
{
|
{
|
||||||
String message =
|
String message =
|
||||||
// orange text
|
MinecraftTextFormat.ORANGE + "Distant Horizons: Alex's Cave detected." + MinecraftTextFormat.CLEAR_FORMATTING +
|
||||||
"\u00A76" + "Distant Horizons: Alex's Cave detected." + "\u00A7r\n" +
|
|
||||||
"You may have to change Alex's config for DH to render. ";
|
"You may have to change Alex's config for DH to render. ";
|
||||||
ClientApi.INSTANCE.showChatMessageNextFrame(message);
|
ClientApi.INSTANCE.showChatMessageNextFrame(message);
|
||||||
}
|
}
|
||||||
@@ -259,8 +262,7 @@ public abstract class AbstractModInitializer
|
|||||||
if (showChatWarnings)
|
if (showChatWarnings)
|
||||||
{
|
{
|
||||||
String message =
|
String message =
|
||||||
// orange text
|
MinecraftTextFormat.ORANGE + "Distant Horizons: WWOO detected." + MinecraftTextFormat.CLEAR_FORMATTING + "\n" +
|
||||||
"\u00A76" + "Distant Horizons: WWOO detected." + "\u00A7r\n" +
|
|
||||||
wwooWarning;
|
wwooWarning;
|
||||||
ClientApi.INSTANCE.showChatMessageNextFrame(message);
|
ClientApi.INSTANCE.showChatMessageNextFrame(message);
|
||||||
}
|
}
|
||||||
@@ -290,8 +292,7 @@ public abstract class AbstractModInitializer
|
|||||||
if (showChatWarnings)
|
if (showChatWarnings)
|
||||||
{
|
{
|
||||||
String message =
|
String message =
|
||||||
// orange text
|
MinecraftTextFormat.ORANGE + "Distant Horizons: Chunky detected." + MinecraftTextFormat.CLEAR_FORMATTING + "\n" +
|
||||||
"\u00A76" + "Distant Horizons: Chunky detected." + "\u00A7r\n" +
|
|
||||||
chunkyWarning;
|
chunkyWarning;
|
||||||
ClientApi.INSTANCE.showChatMessageNextFrame(message);
|
ClientApi.INSTANCE.showChatMessageNextFrame(message);
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-3
@@ -41,6 +41,7 @@ import java.io.IOException;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -49,12 +50,14 @@ import net.minecraft.core.Registry;
|
|||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.EmptyBlockGetter;
|
import net.minecraft.world.level.EmptyBlockGetter;
|
||||||
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
||||||
|
import net.minecraft.tags.TagKey;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.world.level.EmptyBlockGetter;
|
import net.minecraft.world.level.EmptyBlockGetter;
|
||||||
#else
|
#else
|
||||||
|
import net.minecraft.tags.TagKey;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
@@ -88,6 +91,15 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
public static final String DIRT_RESOURCE_LOCATION_STRING = "minecraft:dirt";
|
public static final String DIRT_RESOURCE_LOCATION_STRING = "minecraft:dirt";
|
||||||
public static final String WATER_RESOURCE_LOCATION_STRING = "minecraft:water";
|
public static final String WATER_RESOURCE_LOCATION_STRING = "minecraft:water";
|
||||||
|
|
||||||
|
/** Used to handle older MC versions that don't have an simple way of getting the block's tags */
|
||||||
|
public static final List<String> OLD_BEACON_BASE_BLOCK_NAME_LIST = Arrays.asList(
|
||||||
|
"iron_block",
|
||||||
|
"gold_block",
|
||||||
|
"diamond_block",
|
||||||
|
"emerald_block",
|
||||||
|
"netherite_block"
|
||||||
|
);
|
||||||
|
|
||||||
public static HashSet<IBlockStateWrapper> rendererIgnoredBlocks = null;
|
public static HashSet<IBlockStateWrapper> rendererIgnoredBlocks = null;
|
||||||
public static HashSet<IBlockStateWrapper> rendererIgnoredCaveBlocks = null;
|
public static HashSet<IBlockStateWrapper> rendererIgnoredCaveBlocks = null;
|
||||||
|
|
||||||
@@ -176,11 +188,14 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
String lowercaseSerial = this.serialString.toLowerCase();
|
String lowercaseSerial = this.serialString.toLowerCase();
|
||||||
|
|
||||||
|
|
||||||
// beacon blocks
|
|
||||||
|
// beacon base blocks
|
||||||
|
#if MC_VER <= MC_1_18_2
|
||||||
|
// Older MC versions are harder to get block tags, so just use a static list to determine beacon blocks
|
||||||
boolean isBeaconBaseBlock = false;
|
boolean isBeaconBaseBlock = false;
|
||||||
for (int i = 0; i < LodUtil.BEACON_BASE_BLOCK_NAME_LIST.size(); i++)
|
for (int i = 0; i < OLD_BEACON_BASE_BLOCK_NAME_LIST.size(); i++)
|
||||||
{
|
{
|
||||||
String baseBlockName = LodUtil.BEACON_BASE_BLOCK_NAME_LIST.get(i);
|
String baseBlockName = OLD_BEACON_BASE_BLOCK_NAME_LIST.get(i);
|
||||||
if (lowercaseSerial.contains(baseBlockName))
|
if (lowercaseSerial.contains(baseBlockName))
|
||||||
{
|
{
|
||||||
isBeaconBaseBlock = true;
|
isBeaconBaseBlock = true;
|
||||||
@@ -188,8 +203,23 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.isBeaconBaseBlock = isBeaconBaseBlock;
|
this.isBeaconBaseBlock = isBeaconBaseBlock;
|
||||||
|
#else
|
||||||
|
if (blockState != null)
|
||||||
|
{
|
||||||
|
// check if this block has any tags
|
||||||
|
Stream<TagKey<Block>> tags = blockState.getTags();
|
||||||
|
this.isBeaconBaseBlock = tags.anyMatch((TagKey<Block> tag) -> tag.location().getPath().toLowerCase().contains("beacon_base_blocks"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.isBeaconBaseBlock = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// beacon block
|
||||||
this.isBeaconBlock = lowercaseSerial.contains("minecraft:beacon");
|
this.isBeaconBlock = lowercaseSerial.contains("minecraft:beacon");
|
||||||
|
|
||||||
|
|
||||||
// beacon tint color
|
// beacon tint color
|
||||||
Color beaconTintColor = null;
|
Color beaconTintColor = null;
|
||||||
if (this.blockState != null
|
if (this.blockState != null
|
||||||
@@ -225,6 +255,12 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
// bedrock is a special case fully opaque block that does allow beacons through
|
// bedrock is a special case fully opaque block that does allow beacons through
|
||||||
allowsBeaconBeamPassage = true;
|
allowsBeaconBeamPassage = true;
|
||||||
}
|
}
|
||||||
|
else if (lowercaseSerial.contains("minecraft:tinted_glass"))
|
||||||
|
{
|
||||||
|
// tinted glass is a special case where it isn't fully opaque,
|
||||||
|
// but should block beacons
|
||||||
|
allowsBeaconBeamPassage = false;
|
||||||
|
}
|
||||||
else if (propagatesSkyLightDown || !canOcclude)
|
else if (propagatesSkyLightDown || !canOcclude)
|
||||||
{
|
{
|
||||||
// stairs, cake, fences, etc.
|
// stairs, cake, fences, etc.
|
||||||
|
|||||||
+44
-14
@@ -30,10 +30,7 @@ import net.minecraft.client.Minecraft;
|
|||||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.*;
|
||||||
import net.minecraft.world.level.block.FlowerBlock;
|
|
||||||
import net.minecraft.world.level.block.LeavesBlock;
|
|
||||||
import net.minecraft.world.level.block.RotatedPillarBlock;
|
|
||||||
#if MC_VER >= MC_1_19_2
|
#if MC_VER >= MC_1_19_2
|
||||||
import net.minecraft.util.RandomSource;
|
import net.minecraft.util.RandomSource;
|
||||||
#else
|
#else
|
||||||
@@ -41,6 +38,7 @@ import java.util.Random;
|
|||||||
#endif
|
#endif
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
import net.minecraft.world.level.block.state.properties.SlabType;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -64,6 +62,8 @@ public class ClientBlockStateColorCache
|
|||||||
{
|
{
|
||||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
private static final Minecraft MC = Minecraft.getInstance();
|
||||||
|
|
||||||
private static final HashSet<BlockState> BLOCK_STATES_THAT_NEED_LEVEL = new HashSet<>();
|
private static final HashSet<BlockState> BLOCK_STATES_THAT_NEED_LEVEL = new HashSet<>();
|
||||||
private static final HashSet<BlockState> BROKEN_BLOCK_STATES = new HashSet<>();
|
private static final HashSet<BlockState> BROKEN_BLOCK_STATES = new HashSet<>();
|
||||||
|
|
||||||
@@ -79,7 +79,16 @@ public class ClientBlockStateColorCache
|
|||||||
|
|
||||||
|
|
||||||
/** This is the order each direction on a block is processed when attempting to get the texture/color */
|
/** This is the order each direction on a block is processed when attempting to get the texture/color */
|
||||||
private static final Direction[] COLOR_RESOLUTION_DIRECTION_ORDER = { Direction.UP, Direction.NORTH, Direction.EAST, Direction.WEST, Direction.SOUTH, Direction.DOWN };
|
private static final @Nullable Direction[] COLOR_RESOLUTION_DIRECTION_ORDER =
|
||||||
|
{
|
||||||
|
Direction.UP,
|
||||||
|
null, // null represents "unculled" faces, IE the top of farmland
|
||||||
|
Direction.NORTH,
|
||||||
|
Direction.EAST,
|
||||||
|
Direction.WEST,
|
||||||
|
Direction.SOUTH,
|
||||||
|
Direction.DOWN
|
||||||
|
};
|
||||||
|
|
||||||
private static final int FLOWER_COLOR_SCALE = 5;
|
private static final int FLOWER_COLOR_SCALE = 5;
|
||||||
|
|
||||||
@@ -281,14 +290,23 @@ public class ClientBlockStateColorCache
|
|||||||
@Nullable
|
@Nullable
|
||||||
private List<BakedQuad> getQuadsForDirection(@Nullable Direction direction)
|
private List<BakedQuad> getQuadsForDirection(@Nullable Direction direction)
|
||||||
{
|
{
|
||||||
List<BakedQuad> quads = null;
|
BlockState effectiveBlockState = this.blockState;
|
||||||
|
|
||||||
|
// if this block is a slab, use it's double variant so we can get the top face,
|
||||||
|
// otherwise the color will use the side, which isn't as accurate
|
||||||
|
if (this.blockState.getBlock() instanceof SlabBlock)
|
||||||
|
{
|
||||||
|
effectiveBlockState = this.blockState.setValue( SlabBlock.TYPE, SlabType.DOUBLE );
|
||||||
|
}
|
||||||
|
|
||||||
|
List<BakedQuad> quads;
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_5
|
#if MC_VER < MC_1_21_5
|
||||||
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
quads = MC.getModelManager().getBlockModelShaper().
|
||||||
getBlockModel(this.blockState).getQuads(this.blockState, direction, RANDOM);
|
getBlockModel(effectiveBlockState).getQuads(effectiveBlockState, direction, RANDOM);
|
||||||
#else
|
#else
|
||||||
List<BlockModelPart> blockModelPartList = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
List<BlockModelPart> blockModelPartList = MC.getModelManager().getBlockModelShaper().
|
||||||
getBlockModel(this.blockState).collectParts(RANDOM);
|
getBlockModel(effectiveBlockState).collectParts(RANDOM);
|
||||||
|
|
||||||
quads = new ArrayList<>();
|
quads = new ArrayList<>();
|
||||||
if (blockModelPartList != null)
|
if (blockModelPartList != null)
|
||||||
@@ -558,10 +576,22 @@ public class ClientBlockStateColorCache
|
|||||||
|
|
||||||
static EColorMode getColorMode(Block block)
|
static EColorMode getColorMode(Block block)
|
||||||
{
|
{
|
||||||
if (block instanceof LeavesBlock) return Leaves;
|
if (block instanceof LeavesBlock)
|
||||||
if (block instanceof FlowerBlock) return Flower;
|
{
|
||||||
if (block.toString().contains("glass")) return Glass;
|
return Leaves;
|
||||||
if (block.toString().equals("Block{chiselsandbits:chiseled}")) return Chisel;
|
}
|
||||||
|
if (block instanceof FlowerBlock)
|
||||||
|
{
|
||||||
|
return Flower;
|
||||||
|
}
|
||||||
|
if (block.toString().contains("glass"))
|
||||||
|
{
|
||||||
|
return Glass;
|
||||||
|
}
|
||||||
|
if (block.toString().equals("Block{chiselsandbits:chiseled}"))
|
||||||
|
{
|
||||||
|
return Chisel;
|
||||||
|
}
|
||||||
return Default;
|
return Default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -51,10 +51,10 @@ public class TintGetterOverride extends AbstractDhTintGetter
|
|||||||
|
|
||||||
public TintGetterOverride() { }
|
public TintGetterOverride() { }
|
||||||
|
|
||||||
public void update(LevelReader parent, BiomeWrapper biomeWrapper, BlockStateWrapper blockStateWrapper, FullDataSourceV2 fullDataSource, IClientLevelWrapper clientLevelWrapper)
|
public void update(BiomeWrapper biomeWrapper, BlockStateWrapper blockStateWrapper, FullDataSourceV2 fullDataSource, IClientLevelWrapper clientLevelWrapper)
|
||||||
{
|
{
|
||||||
super.update(biomeWrapper, blockStateWrapper, fullDataSource, clientLevelWrapper);
|
super.update(biomeWrapper, blockStateWrapper, fullDataSource, clientLevelWrapper);
|
||||||
this.parent = parent;
|
this.parent = (LevelReader)this.clientLevelWrapper.getWrappedMcObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+18
-21
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.seibel.distanthorizons.common.wrappers.chunk;
|
package com.seibel.distanthorizons.common.wrappers.chunk;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.api.DhApi;
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.misc.MutableBlockPosWrapper;
|
import com.seibel.distanthorizons.common.wrappers.misc.MutableBlockPosWrapper;
|
||||||
@@ -80,6 +81,8 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
private static final ThreadLocal<BlockPos.MutableBlockPos> MUTABLE_BLOCK_POS_REF = ThreadLocal.withInitial(() -> new BlockPos.MutableBlockPos());
|
private static final ThreadLocal<BlockPos.MutableBlockPos> MUTABLE_BLOCK_POS_REF = ThreadLocal.withInitial(() -> new BlockPos.MutableBlockPos());
|
||||||
private static final ThreadLocal<MutableBlockPosWrapper> MUTABLE_BLOCK_POS_WRAPPER_REF = ThreadLocal.withInitial(() -> new MutableBlockPosWrapper());
|
private static final ThreadLocal<MutableBlockPosWrapper> MUTABLE_BLOCK_POS_WRAPPER_REF = ThreadLocal.withInitial(() -> new MutableBlockPosWrapper());
|
||||||
|
|
||||||
|
private static boolean heightmapThreadWarningLogged = false;
|
||||||
|
|
||||||
|
|
||||||
private final ChunkAccess chunk;
|
private final ChunkAccess chunk;
|
||||||
private final DhChunkPos chunkPos;
|
private final DhChunkPos chunkPos;
|
||||||
@@ -107,21 +110,20 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
// constructor //
|
// constructor //
|
||||||
//=============//
|
//=============//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note: this constructor should be very
|
||||||
|
* fast since it will be called frequently on the MC
|
||||||
|
* server thread and a slow method will cause server lag.
|
||||||
|
*/
|
||||||
public ChunkWrapper(ChunkAccess chunk, ILevelWrapper wrappedLevel)
|
public ChunkWrapper(ChunkAccess chunk, ILevelWrapper wrappedLevel)
|
||||||
{
|
|
||||||
this(chunk, wrappedLevel, true);
|
|
||||||
}
|
|
||||||
public ChunkWrapper(ChunkAccess chunk, ILevelWrapper wrappedLevel, boolean recreateHeightmaps)
|
|
||||||
{
|
{
|
||||||
this.chunk = chunk;
|
this.chunk = chunk;
|
||||||
this.wrappedLevel = wrappedLevel;
|
this.wrappedLevel = wrappedLevel;
|
||||||
this.chunkPos = new DhChunkPos(chunk.getPos().x, chunk.getPos().z);
|
this.chunkPos = new DhChunkPos(chunk.getPos().x, chunk.getPos().z);
|
||||||
|
}
|
||||||
|
|
||||||
if (recreateHeightmaps)
|
@Override
|
||||||
{
|
public ChunkWrapper copy() { return new ChunkWrapper(this.chunk, this.wrappedLevel); }
|
||||||
this.createDhHeightMaps();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -242,11 +244,15 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
}
|
}
|
||||||
private int getChunkSectionMinHeight(int index) { return (index * 16) + this.getInclusiveMinBuildHeight(); }
|
private int getChunkSectionMinHeight(int index) { return (index * 16) + this.getInclusiveMinBuildHeight(); }
|
||||||
|
|
||||||
|
@Override
|
||||||
public void createDhHeightMaps()
|
public void createDhHeightMaps()
|
||||||
{
|
{
|
||||||
// re-calculate the min/max heights for consistency (during world gen these may be wrong)
|
if (heightmapThreadWarningLogged
|
||||||
this.minNonEmptyHeight = Integer.MIN_VALUE;
|
&& !DhApi.isDhThread())
|
||||||
this.maxNonEmptyHeight = Integer.MAX_VALUE;
|
{
|
||||||
|
LOGGER.warn("ChunkWrapper Height maps created on non-DH thread ["+Thread.currentThread().getName()+"]. This may cause stuttering.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.solidHeightMap = new int[LodUtil.CHUNK_WIDTH][LodUtil.CHUNK_WIDTH];
|
this.solidHeightMap = new int[LodUtil.CHUNK_WIDTH][LodUtil.CHUNK_WIDTH];
|
||||||
@@ -614,15 +620,6 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//===============//
|
|
||||||
// other methods //
|
|
||||||
//===============//
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isStillValid() { return this.wrappedLevel.tryGetChunk(this.chunkPos) == this; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
//================//
|
||||||
// base overrides //
|
// base overrides //
|
||||||
//================//
|
//================//
|
||||||
|
|||||||
+31
-5
@@ -13,6 +13,7 @@ import java.util.regex.Pattern;
|
|||||||
|
|
||||||
import com.seibel.distanthorizons.api.enums.config.DisallowSelectingViaConfigGui;
|
import com.seibel.distanthorizons.api.enums.config.DisallowSelectingViaConfigGui;
|
||||||
import com.seibel.distanthorizons.common.wrappers.gui.config.ConfigGuiInfo;
|
import com.seibel.distanthorizons.common.wrappers.gui.config.ConfigGuiInfo;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.config.ConfigHandler;
|
import com.seibel.distanthorizons.core.config.ConfigHandler;
|
||||||
import com.seibel.distanthorizons.core.config.types.*;
|
import com.seibel.distanthorizons.core.config.types.*;
|
||||||
@@ -26,6 +27,7 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
|||||||
import com.seibel.distanthorizons.core.util.AnnotationUtil;
|
import com.seibel.distanthorizons.core.util.AnnotationUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.config.IConfigGui;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.config.IConfigGui;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.config.ILangWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.config.ILangWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
@@ -59,6 +61,9 @@ import net.minecraft.resources.ResourceLocation;
|
|||||||
import net.minecraft.resources.Identifier;
|
import net.minecraft.resources.Identifier;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import com.mojang.blaze3d.platform.InputConstants;
|
||||||
|
|
||||||
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;
|
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.Translatable;
|
||||||
|
|
||||||
@@ -84,6 +89,8 @@ public class ClassicConfigGUI
|
|||||||
|
|
||||||
public static final ConfigCoreInterface CONFIG_CORE_INTERFACE = new ConfigCoreInterface();
|
public static final ConfigCoreInterface CONFIG_CORE_INTERFACE = new ConfigCoreInterface();
|
||||||
|
|
||||||
|
private static final MinecraftClientWrapper MC_CLIENT = MinecraftClientWrapper.INSTANCE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
//==============//
|
||||||
@@ -423,9 +430,17 @@ public class ClassicConfigGUI
|
|||||||
int startingIndex = enumList.indexOf(enumConfigEntry.get());
|
int startingIndex = enumList.indexOf(enumConfigEntry.get());
|
||||||
Enum<?> enumValue = enumList.get(startingIndex);
|
Enum<?> enumValue = enumList.get(startingIndex);
|
||||||
|
|
||||||
// search for the next enum that is selectable
|
boolean shiftPressed =
|
||||||
int index = startingIndex + 1;
|
InputConstants.isKeyDown(MC_CLIENT.getGlfwWindowId(), GLFW.GLFW_KEY_LEFT_SHIFT)
|
||||||
|
|| InputConstants.isKeyDown(MC_CLIENT.getGlfwWindowId(), GLFW.GLFW_KEY_RIGHT_SHIFT);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// move forward or backwards depending on if the shift key is pressed
|
||||||
|
int index = shiftPressed ? startingIndex-1 : startingIndex+1;
|
||||||
index = (index >= enumList.size()) ? 0 : index;
|
index = (index >= enumList.size()) ? 0 : index;
|
||||||
|
|
||||||
|
// walk through the enums to find the next selectable one
|
||||||
while (index != startingIndex)
|
while (index != startingIndex)
|
||||||
{
|
{
|
||||||
enumValue = enumList.get(index);
|
enumValue = enumList.get(index);
|
||||||
@@ -436,13 +451,24 @@ public class ClassicConfigGUI
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
// move forward or backwards depending on if the shift key is pressed
|
||||||
index = (index >= enumList.size()) ? 0 : index;
|
index = shiftPressed ? index-1 : index+1;
|
||||||
|
|
||||||
|
// wrap around to the other side of the array when necessary
|
||||||
|
if (index >= enumList.size())
|
||||||
|
{
|
||||||
|
index = 0;
|
||||||
}
|
}
|
||||||
|
else if (index < 0)
|
||||||
|
{
|
||||||
|
index = enumList.size() - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (index == startingIndex)
|
if (index == startingIndex)
|
||||||
{
|
{
|
||||||
// none of the enums should be selectable, this is a programmer error
|
// one of the enums should be selectable, this is a programmer error
|
||||||
enumValue = enumList.get(startingIndex);
|
enumValue = enumList.get(startingIndex);
|
||||||
LOGGER.warn("Enum [" + enumValue.getClass() + "] doesn't contain any values that should be selectable via the UI, sticking to the currently selected value [" + enumValue + "].");
|
LOGGER.warn("Enum [" + enumValue.getClass() + "] doesn't contain any values that should be selectable via the UI, sticking to the currently selected value [" + enumValue + "].");
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-8
@@ -21,6 +21,7 @@ package com.seibel.distanthorizons.common.wrappers.minecraft;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.Window;
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
||||||
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||||
@@ -203,19 +204,13 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GLProxy.hasInstance())
|
|
||||||
{
|
|
||||||
// rendering setup hasn't finished
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
player.sendMessage(new TextComponent(string), getPlayer().getUUID());
|
player.sendMessage(new TextComponent(string), getPlayer().getUUID());
|
||||||
#elif MC_VER < MC_1_21_9
|
#elif MC_VER < MC_1_21_9
|
||||||
player.displayClientMessage(net.minecraft.network.chat.Component.translatable(string), /*isOverlay*/false);
|
player.displayClientMessage(net.minecraft.network.chat.Component.translatable(string), /*isOverlay*/false);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
GLProxy.getInstance().queueRunningOnRenderThread(() ->
|
GLProxy.queueRunningOnRenderThread(() ->
|
||||||
{
|
{
|
||||||
player.displayClientMessage(net.minecraft.network.chat.Component.translatable(string), /*isOverlay*/false);
|
player.displayClientMessage(net.minecraft.network.chat.Component.translatable(string), /*isOverlay*/false);
|
||||||
});
|
});
|
||||||
@@ -268,6 +263,24 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
// misc //
|
// misc //
|
||||||
//======//
|
//======//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* no override and not included in {@link IMinecraftClientWrapper}
|
||||||
|
* since this would only be used in common/client, not core.
|
||||||
|
*/
|
||||||
|
public
|
||||||
|
#if MC_VER < MC_1_21_9 long
|
||||||
|
#else Window
|
||||||
|
#endif
|
||||||
|
getGlfwWindowId()
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
long glfwWindowId = MINECRAFT.getWindow().getWindow();
|
||||||
|
return glfwWindowId;
|
||||||
|
#else
|
||||||
|
return MINECRAFT.getWindow();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IProfilerWrapper getProfiler()
|
public IProfilerWrapper getProfiler()
|
||||||
{
|
{
|
||||||
@@ -293,7 +306,7 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
@Override
|
@Override
|
||||||
public void crashMinecraft(String errorMessage, Throwable exception)
|
public void crashMinecraft(String errorMessage, Throwable exception)
|
||||||
{
|
{
|
||||||
LOGGER.error(ModInfo.READABLE_NAME + " had the following error: [" + errorMessage + "]. Crashing Minecraft...", exception);
|
LOGGER.fatal(ModInfo.READABLE_NAME + " had the following error: [" + errorMessage + "]. Crashing Minecraft...", exception);
|
||||||
CrashReport report = new CrashReport(errorMessage, exception);
|
CrashReport report = new CrashReport(errorMessage, exception);
|
||||||
#if MC_VER < MC_1_20_4
|
#if MC_VER < MC_1_20_4
|
||||||
Minecraft.crash(report);
|
Minecraft.crash(report);
|
||||||
|
|||||||
+60
-21
@@ -77,6 +77,8 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
private final Function<BlockState, ClientBlockStateColorCache> createCachedBlockColorCacheFunc = (blockState) -> new ClientBlockStateColorCache(blockState, this);
|
private final Function<BlockState, ClientBlockStateColorCache> createCachedBlockColorCacheFunc = (blockState) -> new ClientBlockStateColorCache(blockState, this);
|
||||||
|
|
||||||
|
|
||||||
|
private boolean cloudColorFailLogged = false;
|
||||||
|
|
||||||
private BlockStateWrapper dirtBlockWrapper;
|
private BlockStateWrapper dirtBlockWrapper;
|
||||||
private IDhLevel dhLevel;
|
private IDhLevel dhLevel;
|
||||||
|
|
||||||
@@ -259,7 +261,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
#if MC_VER <= MC_1_21_10
|
#if MC_VER <= MC_1_21_10
|
||||||
return this.level.dimension().location().toString();
|
return this.level.dimension().location().toString();
|
||||||
#else
|
#else
|
||||||
return this.level.dimension().identifier().getPath();
|
return this.level.dimension().identifier().toString();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,23 +297,6 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IChunkWrapper tryGetChunk(DhChunkPos pos)
|
|
||||||
{
|
|
||||||
if (!this.level.hasChunk(pos.getX(), pos.getZ()))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ChunkAccess chunk = this.level.getChunk(pos.getX(), pos.getZ(), ChunkStatus.EMPTY, false);
|
|
||||||
if (chunk == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ChunkWrapper(chunk, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientLevel getWrappedMcObject() { return this.level; }
|
public ClientLevel getWrappedMcObject() { return this.level; }
|
||||||
|
|
||||||
@@ -360,14 +345,68 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
|||||||
public Color getCloudColor(float tickDelta)
|
public Color getCloudColor(float tickDelta)
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
Vec3 colorVec3 = this.level.getCloudColor(tickDelta);
|
Vec3 colorVec3 = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
colorVec3 = this.level.getCloudColor(tickDelta);
|
||||||
return new Color((float)colorVec3.x, (float)colorVec3.y, (float)colorVec3.z);
|
return new Color((float)colorVec3.x, (float)colorVec3.y, (float)colorVec3.z);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// extra logging is due to some mods returning weird values, this way we can track down the issue better
|
||||||
|
if (!this.cloudColorFailLogged)
|
||||||
|
{
|
||||||
|
this.cloudColorFailLogged = true;
|
||||||
|
|
||||||
|
String colorString = "NULL";
|
||||||
|
if (colorVec3 != null)
|
||||||
|
{
|
||||||
|
colorString = "r["+(float)colorVec3.x+"] g["+(float)colorVec3.y+"] b["+(float)colorVec3.z+"]";
|
||||||
|
}
|
||||||
|
LOGGER.warn("Failed to get cloud color for ["+this.getDhIdentifier()+"]. vec3 ["+colorString+"], error: ["+e.getMessage()+"].", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// default to white if there's an issue
|
||||||
|
return Color.WHITE;
|
||||||
|
}
|
||||||
#elif MC_VER <= MC_1_21_10
|
#elif MC_VER <= MC_1_21_10
|
||||||
int argbColor = this.level.getCloudColor(tickDelta);
|
int argbColor = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
argbColor = this.level.getCloudColor(tickDelta);
|
||||||
return ColorUtil.toColorObjARGB(argbColor);
|
return ColorUtil.toColorObjARGB(argbColor);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// extra logging is due to some mods returning weird values, this way we can track down the issue better
|
||||||
|
if (!this.cloudColorFailLogged)
|
||||||
|
{
|
||||||
|
this.cloudColorFailLogged = true;
|
||||||
|
LOGGER.warn("Failed to get cloud color for ["+this.getDhIdentifier()+"]. Int ["+argbColor+"], col ["+ColorUtil.toString(argbColor)+"], error: ["+e.getMessage()+"].", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// default to white if there's an issue
|
||||||
|
return Color.WHITE;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
int argbColor = this.level.environmentAttributes().getValue(EnvironmentAttributes.CLOUD_COLOR, BlockPos.ZERO);
|
int argbColor = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
argbColor = this.level.environmentAttributes().getValue(EnvironmentAttributes.CLOUD_COLOR, BlockPos.ZERO);
|
||||||
return new Color(ColorUtil.getRed(argbColor), ColorUtil.getGreen(argbColor), ColorUtil.getBlue(argbColor), 255 /* ignore alpha since DH clouds don't render correctly with transparency */);
|
return new Color(ColorUtil.getRed(argbColor), ColorUtil.getGreen(argbColor), ColorUtil.getBlue(argbColor), 255 /* ignore alpha since DH clouds don't render correctly with transparency */);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// extra logging is due to some mods returning weird values, this way we can track down the issue better
|
||||||
|
if (!this.cloudColorFailLogged)
|
||||||
|
{
|
||||||
|
this.cloudColorFailLogged = true;
|
||||||
|
LOGGER.warn("Failed to get cloud color for ["+this.getDhIdentifier()+"]. Int ["+argbColor+"], col ["+ColorUtil.toString(argbColor)+"], error: ["+e.getMessage()+"].", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// default to white if there's an issue
|
||||||
|
return Color.WHITE;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-18
@@ -187,7 +187,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
#if MC_VER <= MC_1_21_10
|
#if MC_VER <= MC_1_21_10
|
||||||
return this.level.dimension().location().toString();
|
return this.level.dimension().location().toString();
|
||||||
#else
|
#else
|
||||||
return this.level.dimension().identifier().getPath();
|
return this.level.dimension().identifier().toString();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,23 +223,6 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IChunkWrapper tryGetChunk(DhChunkPos pos)
|
|
||||||
{
|
|
||||||
if (!this.level.hasChunk(pos.getX(), pos.getZ()))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ChunkAccess chunk = this.level.getChunk(pos.getX(), pos.getZ(), ChunkStatus.FULL, false);
|
|
||||||
if (chunk == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ChunkWrapper(chunk, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerLevel getWrappedMcObject() { return this.level; }
|
public ServerLevel getWrappedMcObject() { return this.level; }
|
||||||
|
|
||||||
|
|||||||
+39
-4
@@ -28,6 +28,7 @@ import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.chunkFileHandling.ChunkFileReader;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.chunkFileHandling.ChunkFileReader;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.*;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.*;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.params.GlobalWorldGenParams;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.params.GlobalWorldGenParams;
|
||||||
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
import com.seibel.distanthorizons.core.generation.DhLightingEngine;
|
import com.seibel.distanthorizons.core.generation.DhLightingEngine;
|
||||||
import com.seibel.distanthorizons.core.level.IDhServerLevel;
|
import com.seibel.distanthorizons.core.level.IDhServerLevel;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
@@ -37,6 +38,7 @@ import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
|||||||
import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO;
|
import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO;
|
||||||
import com.seibel.distanthorizons.core.util.ExceptionUtil;
|
import com.seibel.distanthorizons.core.util.ExceptionUtil;
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
|
import com.seibel.distanthorizons.core.util.TimerUtil;
|
||||||
import com.seibel.distanthorizons.core.util.gridList.ArrayGridList;
|
import com.seibel.distanthorizons.core.util.gridList.ArrayGridList;
|
||||||
import com.seibel.distanthorizons.core.util.objects.UncheckedInterruptedException;
|
import com.seibel.distanthorizons.core.util.objects.UncheckedInterruptedException;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
||||||
@@ -100,6 +102,15 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
|
|||||||
public static final long EXCEPTION_TIMER_RESET_TIME = TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS);
|
public static final long EXCEPTION_TIMER_RESET_TIME = TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS);
|
||||||
public static final int EXCEPTION_COUNTER_TRIGGER = 20;
|
public static final int EXCEPTION_COUNTER_TRIGGER = 20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to revert the ignore logic in {@link SharedApi} so
|
||||||
|
* that a given chunk pos can be handled again.
|
||||||
|
* A timer is used so we don't have to inject into MC's code and it works sell enough
|
||||||
|
* most of the time.
|
||||||
|
* If a chunk does get through due the timeout not being long enough that isn't the end of the world.
|
||||||
|
*/
|
||||||
|
private static final int MS_TO_IGNORE_CHUNK_AFTER_COMPLETION = 5_000;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private final IDhServerLevel dhServerLevel;
|
private final IDhServerLevel dhServerLevel;
|
||||||
@@ -107,6 +118,8 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
|
|||||||
public final InternalServerGenerator internalServerGenerator;
|
public final InternalServerGenerator internalServerGenerator;
|
||||||
public final ChunkFileReader chunkFileReader;
|
public final ChunkFileReader chunkFileReader;
|
||||||
|
|
||||||
|
private final Timer chunkSaveIgnoreTimer = TimerUtil.CreateTimer("ChunkSaveIgnoreTimer");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public final LinkedBlockingQueue<GenerationEvent> generationEventQueue = new LinkedBlockingQueue<>();
|
public final LinkedBlockingQueue<GenerationEvent> generationEventQueue = new LinkedBlockingQueue<>();
|
||||||
@@ -435,10 +448,9 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============================//
|
//=========================//
|
||||||
// process existing chunks //
|
// process existing chunks //
|
||||||
//
|
//=========================//
|
||||||
//=============================//
|
|
||||||
|
|
||||||
ArrayGridList<ChunkWrapper> chunkWrapperList = new ArrayGridList<>(regionChunks.gridSize);
|
ArrayGridList<ChunkWrapper> chunkWrapperList = new ArrayGridList<>(regionChunks.gridSize);
|
||||||
regionChunks.forEachPos((relX, relZ) ->
|
regionChunks.forEachPos((relX, relZ) ->
|
||||||
@@ -454,8 +466,8 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
|
|||||||
}
|
}
|
||||||
else if (chunk != null)
|
else if (chunk != null)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, this.dhServerLevel.getLevelWrapper());
|
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, this.dhServerLevel.getLevelWrapper());
|
||||||
|
chunkWrapper.createDhHeightMaps();
|
||||||
chunkWrapperList.set(relX, relZ, chunkWrapper);
|
chunkWrapperList.set(relX, relZ, chunkWrapper);
|
||||||
|
|
||||||
// try setting the wrapper's lighting
|
// try setting the wrapper's lighting
|
||||||
@@ -575,6 +587,11 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
|
|||||||
ProtoChunk protoChunk = ((ProtoChunk) chunk);
|
ProtoChunk protoChunk = ((ProtoChunk) chunk);
|
||||||
protoChunk.setLightEngine(region.getLightEngine());
|
protoChunk.setLightEngine(region.getLightEngine());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// usually ignoring the chunk's position is unnecessary,
|
||||||
|
// but this improves performance if a chunk update event does sneak through
|
||||||
|
SharedApi.CHUNK_UPDATE_QUEUE_MANAGER.addPosToIgnore(chunkWrapper.getChunkPos());
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -684,6 +701,24 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
|
|||||||
this.dhServerLevel.updateBeaconBeamsForChunkPos(centerChunkWrapper.getChunkPos(), activeBeamList);
|
this.dhServerLevel.updateBeaconBeamsForChunkPos(centerChunkWrapper.getChunkPos(), activeBeamList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < iChunkWrapperList.size(); i++)
|
||||||
|
{
|
||||||
|
ChunkWrapper chunkWrapper = (ChunkWrapper) iChunkWrapperList.get(i);
|
||||||
|
if (chunkWrapper == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// give MC a few seconds to save the chunk before
|
||||||
|
// we can process update events there again
|
||||||
|
this.chunkSaveIgnoreTimer.schedule(new TimerTask()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run() { SharedApi.CHUNK_UPDATE_QUEUE_MANAGER.removePosToIgnore(chunkWrapper.getChunkPos()); }
|
||||||
|
}, MS_TO_IGNORE_CHUNK_AFTER_COMPLETION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, int border) { return new ArrayGridList<>(total, border, total.gridSize - border); }
|
private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, int border) { return new ArrayGridList<>(total, border, total.gridSize - border); }
|
||||||
|
|||||||
+4
-3
@@ -7,6 +7,7 @@ import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
|||||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||||
|
import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
|
||||||
import com.seibel.distanthorizons.core.generation.DhLightingEngine;
|
import com.seibel.distanthorizons.core.generation.DhLightingEngine;
|
||||||
import com.seibel.distanthorizons.core.level.IDhServerLevel;
|
import com.seibel.distanthorizons.core.level.IDhServerLevel;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
@@ -51,7 +52,7 @@ public class InternalServerGenerator
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to revert the ignore logic in {@link SharedApi} so
|
* Used to revert the ignore logic in {@link SharedApi} so
|
||||||
* that given chunk pos can be handled again.
|
* that a given chunk pos can be handled again.
|
||||||
* A timer is used so we don't have to inject into MC's code and it works sell enough
|
* A timer is used so we don't have to inject into MC's code and it works sell enough
|
||||||
* most of the time.
|
* most of the time.
|
||||||
* If a chunk does get through due the timeout not being long enough that isn't the end of the world.
|
* If a chunk does get through due the timeout not being long enough that isn't the end of the world.
|
||||||
@@ -156,6 +157,7 @@ public class InternalServerGenerator
|
|||||||
if (chunk != null)
|
if (chunk != null)
|
||||||
{
|
{
|
||||||
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, this.dhServerLevel.getLevelWrapper());
|
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, this.dhServerLevel.getLevelWrapper());
|
||||||
|
chunkWrapper.createDhHeightMaps();
|
||||||
chunkWrappers.add(chunkWrapper);
|
chunkWrappers.add(chunkWrapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,8 +219,7 @@ public class InternalServerGenerator
|
|||||||
if (Config.Common.Logging.Warning.showSlowWorldGenSettingWarnings.get())
|
if (Config.Common.Logging.Warning.showSlowWorldGenSettingWarnings.get())
|
||||||
{
|
{
|
||||||
String message =
|
String message =
|
||||||
// orange text
|
MinecraftTextFormat.ORANGE + "Distant Horizons: slow world gen." + MinecraftTextFormat.CLEAR_FORMATTING + "\n" +
|
||||||
"\u00A76" + "Distant Horizons: slow world gen." + "\u00A7r\n" +
|
|
||||||
c2meWarning;
|
c2meWarning;
|
||||||
ClientApi.INSTANCE.showChatMessageNextFrame(message);
|
ClientApi.INSTANCE.showChatMessageNextFrame(message);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -222,7 +222,8 @@ public class ChunkCompoundTagParser
|
|||||||
boolean hasHeightmapData = readHeightmaps(chunk, chunkData);
|
boolean hasHeightmapData = readHeightmaps(chunk, chunkData);
|
||||||
|
|
||||||
// chunk wrapper so we can pass along extra data more easily
|
// chunk wrapper so we can pass along extra data more easily
|
||||||
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, dhServerLevel.getServerLevelWrapper(), !hasHeightmapData);
|
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, dhServerLevel.getServerLevelWrapper());
|
||||||
|
chunkWrapper.createDhHeightMaps();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -293,7 +293,7 @@ public class ChunkFileReader implements AutoCloseable
|
|||||||
public ChunkWrapper CreateProtoChunkWrapper(ServerLevel level, ChunkPos chunkPos)
|
public ChunkWrapper CreateProtoChunkWrapper(ServerLevel level, ChunkPos chunkPos)
|
||||||
{
|
{
|
||||||
ProtoChunk chunk = CreateProtoChunk(level, chunkPos);
|
ProtoChunk chunk = CreateProtoChunk(level, chunkPos);
|
||||||
return new ChunkWrapper(chunk, this.params.dhServerLevel.getLevelWrapper(), false);
|
return new ChunkWrapper(chunk, this.params.dhServerLevel.getLevelWrapper());
|
||||||
}
|
}
|
||||||
public static ProtoChunk CreateProtoChunk(ServerLevel level, ChunkPos chunkPos)
|
public static ProtoChunk CreateProtoChunk(ServerLevel level, ChunkPos chunkPos)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/
|
|||||||
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
|
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
|
||||||
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
|
||||||
|
|
||||||
|
# getting existing chunks outside the main thread
|
||||||
|
accessible method net/minecraft/server/level/ChunkMap getVisibleChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
|
||||||
|
|
||||||
# lod generation from save file
|
# lod generation from save file
|
||||||
accessible field net/minecraft/world/level/chunk/storage/SimpleRegionStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
accessible field net/minecraft/world/level/chunk/storage/SimpleRegionStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
|
||||||
accessible field net/minecraft/world/level/chunk/storage/IOWorker storage Lnet/minecraft/world/level/chunk/storage/RegionFileStorage;
|
accessible field net/minecraft/world/level/chunk/storage/IOWorker storage Lnet/minecraft/world/level/chunk/storage/RegionFileStorage;
|
||||||
|
|||||||
+1
-1
Submodule coreSubProjects updated: a2c61ed278...2a4bfef7a6
@@ -22,8 +22,10 @@ package com.seibel.distanthorizons.fabric;
|
|||||||
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
import com.seibel.distanthorizons.common.AbstractModInitializer;
|
||||||
import com.seibel.distanthorizons.common.AbstractPluginPacketSender;
|
import com.seibel.distanthorizons.common.AbstractPluginPacketSender;
|
||||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||||
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.core.logging.DhLogger;
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
@@ -64,11 +66,13 @@ import java.util.concurrent.AbstractExecutorService;
|
|||||||
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
|
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.InputConstants;
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.phys.HitResult;
|
import net.minecraft.world.phys.HitResult;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,13 +86,12 @@ import org.lwjgl.glfw.GLFW;
|
|||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
||||||
{
|
{
|
||||||
private final ClientApi clientApi = ClientApi.INSTANCE;
|
|
||||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
|
||||||
private static final AbstractPluginPacketSender PACKET_SENDER = (AbstractPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
|
|
||||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
// TODO we shouldn't be filtering keys on the Forge/Fabric side, only in ClientApi
|
private static final MinecraftClientWrapper MC = MinecraftClientWrapper.INSTANCE;
|
||||||
private static final int[] KEY_TO_CHECK_FOR = { GLFW.GLFW_KEY_F6, GLFW.GLFW_KEY_F8, GLFW.GLFW_KEY_P};
|
private static final AbstractPluginPacketSender PACKET_SENDER = (AbstractPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
|
||||||
|
|
||||||
|
private static final ClientApi clientApi = ClientApi.INSTANCE;
|
||||||
|
|
||||||
HashSet<Integer> previouslyPressKeyCodes = new HashSet<>();
|
HashSet<Integer> previouslyPressKeyCodes = new HashSet<>();
|
||||||
|
|
||||||
@@ -113,14 +116,6 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
|
||||||
// tick events //
|
|
||||||
//=============//
|
|
||||||
|
|
||||||
ClientTickEvents.START_CLIENT_TICK.register((client) -> { ClientApi.INSTANCE.clientTickEvent(); });
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
//==============//
|
||||||
// chunk events //
|
// chunk events //
|
||||||
//==============//
|
//==============//
|
||||||
@@ -344,23 +339,13 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
{
|
{
|
||||||
HashSet<Integer> currentKeyDown = new HashSet<>();
|
HashSet<Integer> currentKeyDown = new HashSet<>();
|
||||||
|
|
||||||
// Note: Minecraft's InputConstants is same as GLFW Key values
|
// Note: Minecraft's InputConstants are the same as GLFW Key values
|
||||||
//TODO: Use mixin to hook directly into the GLFW Keyboard event in minecraft KeyboardHandler
|
for (int keyCode = GLFW.GLFW_KEY_0; keyCode <= GLFW.GLFW_KEY_LAST; keyCode++)
|
||||||
// Check all keys we need
|
|
||||||
for (int keyCode = GLFW.GLFW_KEY_A; keyCode <= GLFW.GLFW_KEY_Z; keyCode++)
|
|
||||||
{
|
{
|
||||||
//if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), keyCode))
|
if (InputConstants.isKeyDown(MC.getGlfwWindowId(), keyCode))
|
||||||
//{
|
{
|
||||||
// currentKeyDown.add(keyCode);
|
currentKeyDown.add(keyCode);
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int keyCode : KEY_TO_CHECK_FOR)
|
|
||||||
{
|
|
||||||
//if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), keyCode))
|
|
||||||
//{
|
|
||||||
// currentKeyDown.add(keyCode);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diff and trigger events
|
// Diff and trigger events
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import com.seibel.distanthorizons.core.config.Config;
|
|||||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.util.NativeDialogUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.*;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.*;
|
||||||
@@ -38,7 +39,6 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
|||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import org.lwjgl.util.tinyfd.TinyFileDialogs;
|
|
||||||
|
|
||||||
#if MC_VER >= MC_1_19_2
|
#if MC_VER >= MC_1_19_2
|
||||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||||
@@ -103,7 +103,7 @@ public class FabricMain extends AbstractModInitializer implements ClientModIniti
|
|||||||
String indiumMissingMessage = ModInfo.READABLE_NAME + " needs Indium to work with Sodium.\nPlease download Indium from https://modrinth.com/mod/indium";
|
String indiumMissingMessage = ModInfo.READABLE_NAME + " needs Indium to work with Sodium.\nPlease download Indium from https://modrinth.com/mod/indium";
|
||||||
LOGGER.fatal(indiumMissingMessage);
|
LOGGER.fatal(indiumMissingMessage);
|
||||||
|
|
||||||
TinyFileDialogs.tinyfd_messageBox(ModInfo.READABLE_NAME, indiumMissingMessage, "ok", "error", false);
|
NativeDialogUtil.showDialog(ModInfo.READABLE_NAME, indiumMissingMessage, "ok", "error");
|
||||||
|
|
||||||
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||||
String errorMessage = "loading Distant Horizons. Distant Horizons requires Indium in order to run with Sodium.";
|
String errorMessage = "loading Distant Horizons. Distant Horizons requires Indium in order to run with Sodium.";
|
||||||
|
|||||||
@@ -107,21 +107,6 @@ public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
|
||||||
// tick events //
|
|
||||||
//=============//
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public void clientTickEvent(TickEvent.ClientTickEvent event)
|
|
||||||
{
|
|
||||||
if (event.phase == TickEvent.Phase.START)
|
|
||||||
{
|
|
||||||
ClientApi.INSTANCE.clientTickEvent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
//==============//
|
||||||
// world events //
|
// world events //
|
||||||
//==============//
|
//==============//
|
||||||
|
|||||||
@@ -22,17 +22,16 @@ package com.seibel.distanthorizons.forge;
|
|||||||
import com.mojang.brigadier.CommandDispatcher;
|
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.config.Config;
|
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.forge.wrappers.modAccessor.ModChecker;
|
import com.seibel.distanthorizons.forge.wrappers.modAccessor.ModChecker;
|
||||||
import com.seibel.distanthorizons.forge.wrappers.modAccessor.OptifineAccessor;
|
import com.seibel.distanthorizons.forge.wrappers.modAccessor.OptifineAccessor;
|
||||||
|
import com.seibel.distanthorizons.forge.wrappers.modAccessor.OculusAccessor;
|
||||||
|
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
@@ -104,6 +103,7 @@ public class ForgeMain extends AbstractModInitializer
|
|||||||
protected void initializeModCompat()
|
protected void initializeModCompat()
|
||||||
{
|
{
|
||||||
this.tryCreateModCompatAccessor("optifine", IOptifineAccessor.class, OptifineAccessor::new);
|
this.tryCreateModCompatAccessor("optifine", IOptifineAccessor.class, OptifineAccessor::new);
|
||||||
|
this.tryCreateModCompatAccessor("oculus", IIrisAccessor.class, OculusAccessor::new);
|
||||||
|
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY,
|
ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY,
|
||||||
|
|||||||
+4
-2
@@ -67,9 +67,11 @@ public class MixinFogRenderer
|
|||||||
|
|
||||||
Entity entity = camera.getEntity();
|
Entity entity = camera.getEntity();
|
||||||
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
|
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
|
||||||
if (!isSpecialFog && cameraNotInFluid && fogMode == FogMode.FOG_TERRAIN
|
if (!isSpecialFog
|
||||||
|
&& cameraNotInFluid
|
||||||
|
&& fogMode == FogMode.FOG_TERRAIN
|
||||||
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
|
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
|
||||||
&& Config.Client.Advanced.Graphics.Fog.disableVanillaFog.get())
|
&& !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);
|
||||||
|
|||||||
+2
@@ -57,6 +57,7 @@ public class MixinOptionsScreen extends Screen
|
|||||||
private void lodconfig$init(CallbackInfo ci)
|
private void lodconfig$init(CallbackInfo ci)
|
||||||
{
|
{
|
||||||
if (Config.Client.showDhOptionsButtonInMinecraftUi.get())
|
if (Config.Client.showDhOptionsButtonInMinecraftUi.get())
|
||||||
|
{
|
||||||
this. #if MC_VER < MC_1_17_1 addButton #else addRenderableWidget #endif
|
this. #if MC_VER < MC_1_17_1 addButton #else addRenderableWidget #endif
|
||||||
(new TexturedButtonWidget(
|
(new TexturedButtonWidget(
|
||||||
// Where the button is on the screen
|
// Where the button is on the screen
|
||||||
@@ -77,5 +78,6 @@ public class MixinOptionsScreen extends Screen
|
|||||||
Component.translatable(ModInfo.ID + ".title")));
|
Component.translatable(ModInfo.ID + ".title")));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+57
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020 James Seibel
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.seibel.distanthorizons.forge.wrappers.modAccessor;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
|
||||||
|
|
||||||
|
public class OculusAccessor implements IIrisAccessor
|
||||||
|
{
|
||||||
|
protected static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
|
||||||
|
public OculusAccessor()
|
||||||
|
{
|
||||||
|
LOGGER.warn("Partial Oculus support enabled. Some DH features may be disabled or behave strangely, use Iris instead if possible.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModName()
|
||||||
|
{
|
||||||
|
return "oculus";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isShaderPackInUse()
|
||||||
|
{
|
||||||
|
// assume shaders are always active
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRenderingShadowPass()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -12,14 +12,13 @@ issueTrackerURL = "${issues}"
|
|||||||
#//updateJSONURL="https://change.me.example.invalid/updates.json" # A URL to query for updates for this mod. See the JSON update specification https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/
|
#//updateJSONURL="https://change.me.example.invalid/updates.json" # A URL to query for updates for this mod. See the JSON update specification https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/
|
||||||
displayURL = "${homepage}"
|
displayURL = "${homepage}"
|
||||||
description = "${description}" #//mandatory. The description text for the mod
|
description = "${description}" #//mandatory. The description text for the mod
|
||||||
logoFile = "assets/distanthorizons/logo.png"
|
logoFile = "dh_forge_logo.png" #// can't contain a file path due to an old forge limitation https://github.com/MinecraftForge/MinecraftForge/issues/7348
|
||||||
catalogueImageIcon = "assets/distanthorizons/icon.png"
|
catalogueImageIcon = "dh_forge_icon.png" #// can't contain a file path due to an old forge limitation https://github.com/MinecraftForge/MinecraftForge/issues/7348
|
||||||
credits = "Massive thanks to all the developers for their hard work to bring Distant Horizons to where it is today. - James"
|
credits = "Massive thanks to all the developers for their hard work to bring Distant Horizons to where it is today. - James"
|
||||||
#// if not set defaults to "false"
|
#// if not set defaults to "false"
|
||||||
clientSideOnly = "true"
|
clientSideOnly = "true"
|
||||||
#// if not set side defaults to "BOTH"
|
#// if not set side defaults to "BOTH"
|
||||||
#// TODO change to "BOTH" when we add server support
|
side = "BOTH"
|
||||||
side = "CLIENT"
|
|
||||||
#// Allow any version to be present (or not) on the server
|
#// Allow any version to be present (or not) on the server
|
||||||
acceptableRemoteVersions = "*"
|
acceptableRemoteVersions = "*"
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -5,8 +5,8 @@ org.gradle.caching=true
|
|||||||
|
|
||||||
# Mod Info
|
# Mod Info
|
||||||
mod_name=DistantHorizons
|
mod_name=DistantHorizons
|
||||||
mod_version=2.4.0-b
|
mod_version=2.4.6-b-dev
|
||||||
api_version=5.0.0
|
api_version=5.1.0
|
||||||
maven_group=com.seibel.distanthorizons
|
maven_group=com.seibel.distanthorizons
|
||||||
mod_readable_name=Distant Horizons
|
mod_readable_name=Distant Horizons
|
||||||
mod_description=This mod generates and renders simplified terrain beyond the normal view distance at a low performance cost. Allowing you to see much farther without turning your game into a slideshow.
|
mod_description=This mod generates and renders simplified terrain beyond the normal view distance at a low performance cost. Allowing you to see much farther without turning your game into a slideshow.
|
||||||
@@ -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=2025.1.27
|
manifold_version=2025.1.28
|
||||||
# 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
|
||||||
|
|||||||
@@ -73,29 +73,6 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
|
||||||
// tick events //
|
|
||||||
//=============//
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_20_6
|
|
||||||
@SubscribeEvent
|
|
||||||
public void clientTickEvent(TickEvent.ClientTickEvent event)
|
|
||||||
{
|
|
||||||
if (event.phase == TickEvent.Phase.START)
|
|
||||||
{
|
|
||||||
ClientApi.INSTANCE.clientTickEvent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
@SubscribeEvent
|
|
||||||
public void clientTickEvent(ClientTickEvent.Pre event)
|
|
||||||
{
|
|
||||||
ClientApi.INSTANCE.clientTickEvent();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
//==============//
|
||||||
// world events //
|
// world events //
|
||||||
//==============//
|
//==============//
|
||||||
|
|||||||
+3
-3
@@ -33,9 +33,9 @@ public class IrisAccessor implements IIrisAccessor
|
|||||||
{
|
{
|
||||||
public IrisAccessor()
|
public IrisAccessor()
|
||||||
{
|
{
|
||||||
#if MC_VER == MC_1_21_11
|
//#if MC_VER == MC_1_21_11
|
||||||
throw new UnsupportedOperationException("Iris isn't supported on this version of DH. When this version of DH was created Iris wasn't available for Neoforge yet.");
|
//throw new UnsupportedOperationException("Iris isn't supported on this version of DH. When this version of DH was created Iris wasn't available for Neoforge yet.");
|
||||||
#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,15 +12,29 @@ How to add a library's natives:
|
|||||||
Example:
|
Example:
|
||||||
|
|
||||||
```groovy
|
```groovy
|
||||||
|
// Relocate the namespace (Java side)
|
||||||
relocate "org.sqlite", "dh_sqlite", {
|
relocate "org.sqlite", "dh_sqlite", {
|
||||||
|
// (Specific to SQLite's relocation)
|
||||||
|
// Make sure that native paths are not changed before steps below
|
||||||
exclude "org/sqlite/native/**"
|
exclude "org/sqlite/native/**"
|
||||||
}
|
}
|
||||||
|
// Shadow also replaces strings inside the Java code
|
||||||
|
// See the library's source code to find strings used to call into the native code
|
||||||
|
// This also includes native library paths, if you use mapPaths {} below they will likely need adjustment as well
|
||||||
|
relocate "jdbc:sqlite", "jdbc:dh_sqlite"
|
||||||
|
|
||||||
transform(NativeTransformer) {
|
transform(NativeTransformer) {
|
||||||
// NativeTransformer configuration
|
// NativeTransformer configuration
|
||||||
rootDir = project.rootDir
|
rootDir = project.rootDir
|
||||||
|
|
||||||
|
// Match native libraries
|
||||||
|
matchFiles { it.startsWith("org/sqlite") }
|
||||||
|
// Replace paths with ones that won't overlap with other mods
|
||||||
|
// Libraries are the ones choosing the path to use for natives; check the source code to see which paths are acceptable.
|
||||||
|
mapPaths { it.replace("org/sqlite", "dh_sqlite") }
|
||||||
|
|
||||||
// Replace native strings, e.g. used in calls back to Java
|
// Replace native strings, e.g. used in calls back to Java
|
||||||
|
// They must be of the same length or shorter!
|
||||||
relocateNative "org/sqlite", "dh_sqlite"
|
relocateNative "org/sqlite", "dh_sqlite"
|
||||||
// Rename native methods used when calling from Java
|
// Rename native methods used when calling from Java
|
||||||
relocateNative "org_sqlite", "dh_1sqlite"
|
relocateNative "org_sqlite", "dh_1sqlite"
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -10,8 +10,8 @@ builds_for=fabric,forge
|
|||||||
netty_version=4.1.82.Final
|
netty_version=4.1.82.Final
|
||||||
|
|
||||||
# Fabric loader
|
# Fabric loader
|
||||||
fabric_loader_version=0.15.6
|
fabric_loader_version=0.16.10
|
||||||
fabric_api_version=0.90.4+1.20.1
|
fabric_api_version=0.92.6+1.20.1
|
||||||
# Fabric mod versions
|
# Fabric mod versions
|
||||||
modmenu_version=7.2.2
|
modmenu_version=7.2.2
|
||||||
starlight_version_fabric=
|
starlight_version_fabric=
|
||||||
|
|||||||
Reference in New Issue
Block a user