Compare commits
60 Commits
2.4.1b
...
dynamicFade
| Author | SHA1 | Date | |
|---|---|---|---|
| 7f11f9bc9c | |||
| 9972363846 | |||
| 4f171234c4 | |||
| 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 |
+5
-8
@@ -372,18 +372,15 @@ subprojects { p ->
|
|||||||
// ZStd
|
// ZStd
|
||||||
// librariesLocation isn't used because it's too long for replacing paths in native libraries
|
// 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
|
// Allowing strings larger than the original string would require shifting the entire binary's contents
|
||||||
relocate "com.github.luben", "dhcomgithubluben", {
|
relocate "com.github.luben", "dhcomgithubluben"
|
||||||
exclude "aix.ppc64/**"
|
relocate "libzstd-jni", "libzstd-jni_dh"
|
||||||
exclude "darwin/**"
|
relocate "zstd-jni", "zstd-jni_dh"
|
||||||
exclude "freebsd/**"
|
|
||||||
exclude "linux/**"
|
|
||||||
exclude "win/**"
|
|
||||||
}
|
|
||||||
|
|
||||||
transform(NativeTransformer) {
|
transform(NativeTransformer) {
|
||||||
rootDir = project.rootDir
|
rootDir = project.rootDir
|
||||||
|
|
||||||
matchFiles { it.contains("libzstd-jni") && !it.contains("ppc64") }
|
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"
|
||||||
relocateNative "com_github_luben", "dhcomgithubluben"
|
relocateNative "com_github_luben", "dhcomgithubluben"
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
@@ -240,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);
|
||||||
}
|
}
|
||||||
@@ -263,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);
|
||||||
}
|
}
|
||||||
@@ -294,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,22 +110,21 @@ 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)
|
|
||||||
{
|
|
||||||
this.createDhHeightMaps();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChunkWrapper copy() { return new ChunkWrapper(this.chunk, this.wrappedLevel); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=========//
|
//=========//
|
||||||
@@ -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 //
|
||||||
//================//
|
//================//
|
||||||
|
|||||||
+63
-37
@@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
//==============//
|
||||||
@@ -175,36 +182,36 @@ public class ClassicConfigGUI
|
|||||||
&& !ModInfo.IS_DEV_BUILD)
|
&& !ModInfo.IS_DEV_BUILD)
|
||||||
{
|
{
|
||||||
this.addBtn(new TexturedButtonWidget(
|
this.addBtn(new TexturedButtonWidget(
|
||||||
// Where the button is on the screen
|
// Where the button is on the screen
|
||||||
this.width - 28, this.height - 28,
|
this.width - 28, this.height - 28,
|
||||||
// Width and height of the button
|
// Width and height of the button
|
||||||
20, 20,
|
20, 20,
|
||||||
// texture UV Offset
|
// texture UV Offset
|
||||||
0, 0,
|
0, 0,
|
||||||
// Some texture stuff
|
// Some texture stuff
|
||||||
0,
|
0,
|
||||||
#if MC_VER < MC_1_21_1
|
#if MC_VER < MC_1_21_1
|
||||||
new ResourceLocation(ModInfo.ID, "textures/gui/changelog.png"),
|
new ResourceLocation(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
#elif MC_VER <= MC_1_21_10
|
#elif MC_VER <= MC_1_21_10
|
||||||
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "textures/gui/changelog.png"),
|
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
#else
|
#else
|
||||||
Identifier.fromNamespaceAndPath(ModInfo.ID, "textures/gui/changelog.png"),
|
Identifier.fromNamespaceAndPath(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
#endif
|
#endif
|
||||||
20, 20,
|
20, 20,
|
||||||
// Create the button and tell it where to go
|
// Create the button and tell it where to go
|
||||||
(buttonWidget) -> {
|
(buttonWidget) -> {
|
||||||
ChangelogScreen changelogScreen = new ChangelogScreen(this);
|
ChangelogScreen changelogScreen = new ChangelogScreen(this);
|
||||||
if (changelogScreen.usable)
|
if (changelogScreen.usable)
|
||||||
{
|
{
|
||||||
Objects.requireNonNull(this.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");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Add a title to the button
|
// Add a title to the button
|
||||||
Translatable(ModInfo.ID + ".updater.title")
|
Translatable(ModInfo.ID + ".updater.title")
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,17 +422,25 @@ public class ClassicConfigGUI
|
|||||||
final ConfigGuiInfo configGuiInfo = ((ConfigGuiInfo) enumConfigEntry.guiValue);
|
final ConfigGuiInfo configGuiInfo = ((ConfigGuiInfo) enumConfigEntry.guiValue);
|
||||||
|
|
||||||
Function<Object, Component> getEnumTranslatableFunc = (value) -> Translatable(TRANSLATION_PREFIX + "enum." + enumClass.getSimpleName() + "." + enumConfigEntry.get().toString());
|
Function<Object, Component> getEnumTranslatableFunc = (value) -> Translatable(TRANSLATION_PREFIX + "enum." + enumClass.getSimpleName() + "." + enumConfigEntry.get().toString());
|
||||||
configGuiInfo.buttonOptionMap =
|
configGuiInfo.buttonOptionMap =
|
||||||
new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(
|
new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(
|
||||||
(button) ->
|
(button) ->
|
||||||
{
|
{
|
||||||
// get the currently selected enum and enum index
|
// get the currently selected enum and enum index
|
||||||
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 + "].");
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-20
@@ -120,26 +120,26 @@ public class UpdateModScreen extends DhScreen
|
|||||||
if (!ModInfo.IS_DEV_BUILD)
|
if (!ModInfo.IS_DEV_BUILD)
|
||||||
{
|
{
|
||||||
this.addBtn(new TexturedButtonWidget(
|
this.addBtn(new TexturedButtonWidget(
|
||||||
// Where the button is on the screen
|
// Where the button is on the screen
|
||||||
this.width / 2 - 97, this.height / 2 + 8,
|
this.width / 2 - 97, this.height / 2 + 8,
|
||||||
// Width and height of the button
|
// Width and height of the button
|
||||||
20, 20,
|
20, 20,
|
||||||
// Offset
|
// Offset
|
||||||
0, 0,
|
0, 0,
|
||||||
// Some textuary stuff
|
// Some textuary stuff
|
||||||
0,
|
0,
|
||||||
#if MC_VER < MC_1_21_1
|
#if MC_VER < MC_1_21_1
|
||||||
new ResourceLocation(ModInfo.ID, "textures/gui/changelog.png"),
|
new ResourceLocation(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
#elif MC_VER <= MC_1_21_10
|
#elif MC_VER <= MC_1_21_10
|
||||||
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "textures/gui/changelog.png"),
|
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
#else
|
#else
|
||||||
Identifier.fromNamespaceAndPath(ModInfo.ID, "textures/gui/changelog.png"),
|
Identifier.fromNamespaceAndPath(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
#endif
|
#endif
|
||||||
20, 20,
|
20, 20,
|
||||||
// Create the button and tell it where to go
|
// Create the button and tell it where to go
|
||||||
(buttonWidget) -> Objects.requireNonNull(this.minecraft).setScreen(new ChangelogScreen(this, this.newVersionID)),
|
(buttonWidget) -> Objects.requireNonNull(this.minecraft).setScreen(new ChangelogScreen(this, this.newVersionID)),
|
||||||
// Add a title to the button
|
// Add a title to the button
|
||||||
Translatable(ModInfo.ID + ".updater.title")
|
Translatable(ModInfo.ID + ".updater.title")
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+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);
|
||||||
|
|||||||
+4
-4
@@ -362,7 +362,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
if (glTexture == null)
|
if (glTexture == null)
|
||||||
{
|
{
|
||||||
// shouldn't happen, but just in case
|
// shouldn't happen, but just in case
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return glTexture.glId();
|
return glTexture.glId();
|
||||||
@@ -376,7 +376,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
this.depthTextureCastFailLogged = true;
|
this.depthTextureCastFailLogged = true;
|
||||||
LOGGER.error("Unable to cast render Target depth texture to GlTexture. MC or a rendering mod may have changed the object type.", e);
|
LOGGER.error("Unable to cast render Target depth texture to GlTexture. MC or a rendering mod may have changed the object type.", e);
|
||||||
}
|
}
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -392,7 +392,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
if (glTexture == null)
|
if (glTexture == null)
|
||||||
{
|
{
|
||||||
// shouldn't happen, but just in case
|
// shouldn't happen, but just in case
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return glTexture.glId();
|
return glTexture.glId();
|
||||||
@@ -405,7 +405,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
this.colorTextureCastFailLogged = true;
|
this.colorTextureCastFailLogged = true;
|
||||||
LOGGER.error("Unable to cast render Target color texture to GlTexture. MC or a rendering mod may have changed the object type.", e);
|
LOGGER.error("Unable to cast render Target color texture to GlTexture. MC or a rendering mod may have changed the object type.", e);
|
||||||
}
|
}
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+63
-24
@@ -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;
|
||||||
return new Color((float)colorVec3.x, (float)colorVec3.y, (float)colorVec3.z);
|
try
|
||||||
|
{
|
||||||
|
colorVec3 = this.level.getCloudColor(tickDelta);
|
||||||
|
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;
|
||||||
return ColorUtil.toColorObjARGB(argbColor);
|
try
|
||||||
|
{
|
||||||
|
argbColor = this.level.getCloudColor(tickDelta);
|
||||||
|
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;
|
||||||
return new Color(ColorUtil.getRed(argbColor), ColorUtil.getGreen(argbColor), ColorUtil.getBlue(argbColor), 255 /* ignore alpha since DH clouds don't render correctly with transparency */);
|
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 */);
|
||||||
|
}
|
||||||
|
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: 6feb7f1b42...4a3c24f39e
@@ -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<>();
|
||||||
|
|
||||||
@@ -336,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.";
|
||||||
|
|||||||
+18
-18
@@ -137,24 +137,24 @@ public class MixinOptionsScreen extends Screen
|
|||||||
if (this.optionsButton == null)
|
if (this.optionsButton == null)
|
||||||
{
|
{
|
||||||
this.optionsButton
|
this.optionsButton
|
||||||
= new TexturedButtonWidget(
|
= new TexturedButtonWidget(
|
||||||
// Where the button is on the screen
|
// Where the button is on the screen
|
||||||
this.width / 2 - 180, this.height / 6 - 12,
|
this.width / 2 - 180, this.height / 6 - 12,
|
||||||
// Width and height of the button
|
// Width and height of the button
|
||||||
20, 20,
|
20, 20,
|
||||||
// texture UV Offset
|
// texture UV Offset
|
||||||
0, 0,
|
0, 0,
|
||||||
// Some textuary stuff
|
// Some textuary stuff
|
||||||
20, ICON_TEXTURE, 20, 40,
|
20, ICON_TEXTURE, 20, 40,
|
||||||
// Create the button and tell it where to go
|
// Create the button and tell it where to go
|
||||||
// For now it goes to the client option by default
|
// For now it goes to the client option by default
|
||||||
(buttonWidget) -> Objects.requireNonNull(this.minecraft).setScreen(GetConfigScreen.getScreen(this)),
|
(buttonWidget) -> Objects.requireNonNull(this.minecraft).setScreen(GetConfigScreen.getScreen(this)),
|
||||||
// Add a title to the button
|
// Add a title to the button
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
new TranslatableComponent(ModInfo.ID + ".title"));
|
new TranslatableComponent(ModInfo.ID + ".title"));
|
||||||
#else
|
#else
|
||||||
Component.translatable(ModInfo.ID + ".title"));
|
Component.translatable(ModInfo.ID + ".title"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.optionsButton;
|
return this.optionsButton;
|
||||||
|
|||||||
+5
-3
@@ -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
|
||||||
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
|
&& cameraNotInFluid
|
||||||
&& Config.Client.Advanced.Graphics.Fog.disableVanillaFog.get())
|
&& 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);
|
||||||
|
|||||||
+20
-18
@@ -57,25 +57,27 @@ 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
|
||||||
this.width / 2 - 180, this.height / 6 - 12,
|
this.width / 2 - 180, this.height / 6 - 12,
|
||||||
// Width and height of the button
|
// Width and height of the button
|
||||||
20, 20,
|
20, 20,
|
||||||
// Offset
|
// Offset
|
||||||
0, 0,
|
0, 0,
|
||||||
// Some textuary stuff
|
// Some textuary stuff
|
||||||
20, ICON_TEXTURE, 20, 40,
|
20, ICON_TEXTURE, 20, 40,
|
||||||
// Create the button and tell it where to go
|
// Create the button and tell it where to go
|
||||||
// For now it goes to the client option by default
|
// For now it goes to the client option by default
|
||||||
(buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(GetConfigScreen.getScreen(this)),
|
(buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(GetConfigScreen.getScreen(this)),
|
||||||
// Add a title to the button
|
// Add a title to the button
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
new TranslatableComponent(ModInfo.ID + ".title")));
|
new TranslatableComponent(ModInfo.ID + ".title")));
|
||||||
#else
|
#else
|
||||||
Component.translatable(ModInfo.ID + ".title")));
|
Component.translatable(ModInfo.ID + ".title")));
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 = "*"
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"pack": {
|
|
||||||
"pack_format": 7,
|
|
||||||
"supported_formats": {
|
|
||||||
"min_inclusive": 7,
|
|
||||||
"max_inclusive": 90000
|
|
||||||
},
|
|
||||||
"description": "Distant Horizons"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+3
-3
@@ -5,8 +5,8 @@ org.gradle.caching=true
|
|||||||
|
|
||||||
# Mod Info
|
# Mod Info
|
||||||
mod_name=DistantHorizons
|
mod_name=DistantHorizons
|
||||||
mod_version=2.4.1-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
|
||||||
|
|||||||
+2
-2
@@ -45,7 +45,7 @@ public class NeoforgeMinecraftRenderWrapper extends MinecraftRenderWrapper
|
|||||||
this.depthTextureCastFailLogged = true;
|
this.depthTextureCastFailLogged = true;
|
||||||
LOGGER.error("Unable to cast render Target depth texture to GlTexture. MC or a rendering mod may have changed the object type.", e);
|
LOGGER.error("Unable to cast render Target depth texture to GlTexture. MC or a rendering mod may have changed the object type.", e);
|
||||||
}
|
}
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ public class NeoforgeMinecraftRenderWrapper extends MinecraftRenderWrapper
|
|||||||
this.colorTextureCastFailLogged = true;
|
this.colorTextureCastFailLogged = true;
|
||||||
LOGGER.error("Unable to cast render Target color texture to ValidationGpuTexture or GlTexture. MC, Neoforge, or a rendering mod may have changed the object type.", e);
|
LOGGER.error("Unable to cast render Target color texture to ValidationGpuTexture or GlTexture. MC, Neoforge, or a rendering mod may have changed the object type.", e);
|
||||||
}
|
}
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"pack": {
|
|
||||||
"pack_format": 7,
|
|
||||||
"supported_formats": {
|
|
||||||
"min_inclusive": 7,
|
|
||||||
"max_inclusive": 90000
|
|
||||||
},
|
|
||||||
"description": "Distant Horizons"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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"
|
||||||
|
|||||||
BIN
Binary file not shown.
BIN
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