diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/chunk/ChunkWrapper.java b/common/src/main/java/com/seibel/lod/common/wrappers/chunk/ChunkWrapper.java index 403a4d18f..d88f09c17 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/chunk/ChunkWrapper.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/chunk/ChunkWrapper.java @@ -10,6 +10,7 @@ import com.seibel.lod.common.wrappers.block.BlockShapeWrapper; import com.seibel.lod.common.wrappers.world.BiomeWrapper; import net.minecraft.core.BlockPos; +import net.minecraft.core.QuartPos; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.LightLayer; import net.minecraft.world.level.block.Block; @@ -31,24 +32,21 @@ public class ChunkWrapper implements IChunkWrapper { private ChunkAccess chunk; private BlockAndTintGetter lightSource; - private final int CHUNK_SECTION_SHIFT = 4; - private final int CHUNK_SECTION_MASK = 0b1111; - private final int CHUNK_SIZE_SHIFT = 4; - private final int CHUNK_SIZE_MASK = 0b1111; @Override public int getHeight(){ - return chunk.getMaxBuildHeight(); + return chunk.getHeight(); } @Override - public boolean isPositionInWater(int x, int y, int z) + public int getMinBuildHeight() { - BlockState blockState = chunk.getSections()[y >> CHUNK_SECTION_SHIFT].getBlockState(x & CHUNK_SIZE_MASK, y & CHUNK_SECTION_MASK, z & CHUNK_SIZE_MASK); - - //This type of block could be in water - return ((blockState.getBlock() instanceof LiquidBlock))// && !(blockState.getBlock() instanceof IWaterLoggable)) - || blockState.getOptionalValue(BlockStateProperties.WATERLOGGED).isPresent() && blockState.getOptionalValue(BlockStateProperties.WATERLOGGED).get(); + return chunk.getMinBuildHeight(); + } + @Override + public int getMaxBuildHeight() + { + return chunk.getMaxBuildHeight(); } @Override @@ -60,22 +58,23 @@ public class ChunkWrapper implements IChunkWrapper @Override public IBiomeWrapper getBiome(int x, int y, int z) { - return BiomeWrapper.getBiomeWrapper(chunk.getBiomes().getNoiseBiome((x & CHUNK_SIZE_MASK) >> 2, y >> 2, (z & CHUNK_SIZE_MASK) >> 2)); + return BiomeWrapper.getBiomeWrapper(chunk.getBiomes().getNoiseBiome( + QuartPos.fromBlock(x), QuartPos.fromBlock(y), QuartPos.fromBlock(z))); } @Override public IBlockColorWrapper getBlockColorWrapper(int x, int y, int z) { - Block block = chunk.getSections()[y >> CHUNK_SECTION_SHIFT].getBlockState(x & CHUNK_SIZE_MASK, y & CHUNK_SECTION_MASK, z & CHUNK_SIZE_MASK).getBlock(); + BlockState blockState = chunk.getBlockState(new BlockPos(x,y,z)); + Block block = blockState.getBlock(); return BlockColorWrapper.getBlockColorWrapper(block); } @Override public IBlockShapeWrapper getBlockShapeWrapper(int x, int y, int z) { - LevelChunkSection section = chunk.getSections()[y >> CHUNK_SECTION_SHIFT]; - if (section == null) return null; - Block block = section.getBlockState(x & CHUNK_SIZE_MASK, y & CHUNK_SECTION_MASK, z & CHUNK_SIZE_MASK).getBlock(); + BlockState blockState = chunk.getBlockState(new BlockPos(x,y,z)); + Block block = blockState.getBlock(); return BlockShapeWrapper.getBlockShapeWrapper(block, this, x, y, z); } @@ -117,7 +116,7 @@ public class ChunkWrapper implements IChunkWrapper @Override public int getMaxY(int x, int z) { - return chunk.getHeight(Heightmap.Types.MOTION_BLOCKING, x, z); + return chunk.getHeight(Heightmap.Types.MOTION_BLOCKING, Math.floorMod(x, 16), Math.floorMod(z, 16)); } @Override @@ -149,11 +148,9 @@ public class ChunkWrapper implements IChunkWrapper public boolean isWaterLogged(int x, int y, int z) { - LevelChunkSection section = chunk.getSections()[y >> CHUNK_SECTION_SHIFT]; - if (section == null) return false; - BlockState blockState = section.getBlockState(x & CHUNK_SIZE_MASK, y & CHUNK_SECTION_MASK, z & CHUNK_SIZE_MASK); + BlockState blockState = chunk.getBlockState(new BlockPos(x,y,z)); - //This type of block is always in water + //This type of block is always in water return (!(blockState.getBlock() instanceof LiquidBlockContainer) && (blockState.getBlock() instanceof SimpleWaterloggedBlock)) && (blockState.hasProperty(BlockStateProperties.WATERLOGGED) && blockState.getValue(BlockStateProperties.WATERLOGGED)); } diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/minecraft/MinecraftRenderWrapper.java b/common/src/main/java/com/seibel/lod/common/wrappers/minecraft/MinecraftRenderWrapper.java index f388b540a..c846e3b1e 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/minecraft/MinecraftRenderWrapper.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/minecraft/MinecraftRenderWrapper.java @@ -10,6 +10,10 @@ import com.seibel.lod.common.wrappers.misc.LightMapWrapper; import com.seibel.lod.core.api.ModAccessorApi; import com.seibel.lod.core.util.LodUtil; +import com.seibel.lod.core.util.SingletonHandler; +import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; +import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftWrapper; +import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minecraft.client.renderer.LightTexture; @@ -101,7 +105,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper float[] colorValues = RenderSystem.getShaderFogColor(); return new Color(colorValues[0], colorValues[1], colorValues[2], colorValues[3]); } - // getUnderWaterFogColor() is the same as getFogColor() + // getSpecialFogColor() is the same as getFogColor() @Override public Color getSkyColor() { @@ -148,6 +152,13 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper if (sodium != null) { return sodium.getNormalRenderedChunks(); } + IOptifineAccessor optifine = ModAccessorApi.get(IOptifineAccessor.class); + if (optifine != null) { + HashSet pos = optifine.getNormalRenderedChunks(); + if (pos==null) pos = getMaximumRenderedChunks(); + return pos; + } + LevelRenderer levelRenderer = MC.levelRenderer; ObjectArrayList chunks = levelRenderer.renderChunks; return (chunks.stream().map((chunk) -> { @@ -157,6 +168,31 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper }).collect(Collectors.toCollection(HashSet::new))); } + @Override + public HashSet getMaximumRenderedChunks() + { + //TODO: Make this a circle + IMinecraftWrapper mcWrapper = SingletonHandler.get(IMinecraftWrapper.class); + IWrapperFactory factory = SingletonHandler.get(IWrapperFactory.class); + + int chunkRenderDist = this.getRenderDistance(); + + AbstractChunkPosWrapper centerChunkPos = mcWrapper.getPlayerChunkPos(); + int startChunkX = centerChunkPos.getX() - chunkRenderDist; + int startChunkZ = centerChunkPos.getZ() - chunkRenderDist; + + // add every position within render distance + HashSet renderedPos = new HashSet(); + for (int chunkX = 0; chunkX < (chunkRenderDist * 2+1); chunkX++) + { + for(int chunkZ = 0; chunkZ < (chunkRenderDist * 2+1); chunkZ++) + { + renderedPos.add(factory.createChunkPos(startChunkX + chunkX, startChunkZ + chunkZ)); + } + } + + return renderedPos; + } @@ -260,8 +296,8 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper } @Override - public boolean isFogStateInUnderWater() { - return GAME_RENDERER.getMainCamera().getFluidInCamera() == FogType.WATER; + public boolean isFogStateSpecial() { + return GAME_RENDERER.getMainCamera().getFluidInCamera() != FogType.NONE; } @Override diff --git a/common/src/main/resources/lod.accesswidener b/common/src/main/resources/lod.accesswidener index e42275ccd..740a414b3 100644 --- a/common/src/main/resources/lod.accesswidener +++ b/common/src/main/resources/lod.accesswidener @@ -26,6 +26,10 @@ accessible field net/minecraft/world/level/lighting/LevelLightEngine skyEngine L accessible method net/minecraft/world/level/levelgen/Heightmap setHeight (III)V accessible field net/minecraft/world/level/biome/Biome generationSettings Lnet/minecraft/world/level/biome/BiomeGenerationSettings; +# lod generation from save file +accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop; +accessible method net/minecraft/server/level/ChunkMap readChunk (Lnet/minecraft/world/level/ChunkPos;)Lnet/minecraft/nbt/CompoundTag; + # grabbing textures accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite animatedTexture Lnet/minecraft/client/renderer/texture/TextureAtlasSprite$AnimatedTexture; accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite width I diff --git a/core b/core index 546d60f1f..14e72c68c 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 546d60f1fc17cb175df10aee3742fa4a2d06a550 +Subproject commit 14e72c68cbef363734b7dcbd18118d38d0ccee54 diff --git a/fabric/src/main/java/com/seibel/lod/fabric/Main.java b/fabric/src/main/java/com/seibel/lod/fabric/Main.java index 5d1c395db..80bc07851 100644 --- a/fabric/src/main/java/com/seibel/lod/fabric/Main.java +++ b/fabric/src/main/java/com/seibel/lod/fabric/Main.java @@ -25,8 +25,10 @@ import com.seibel.lod.core.api.ClientApi; import com.seibel.lod.core.api.ModAccessorApi; import com.seibel.lod.core.util.SingletonHandler; import com.seibel.lod.core.wrapperInterfaces.modAccessor.IModChecker; +import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor; import com.seibel.lod.core.wrapperInterfaces.modAccessor.ISodiumAccessor; import com.seibel.lod.fabric.wrappers.modAccessor.ModChecker; +import com.seibel.lod.fabric.wrappers.modAccessor.OptifineAccessor; import com.seibel.lod.fabric.wrappers.modAccessor.SodiumAccessor; import com.seibel.lod.fabric.wrappers.DependencySetup; @@ -70,6 +72,9 @@ public class Main implements ClientModInitializer if (SingletonHandler.get(IModChecker.class).isModLoaded("sodium")) { ModAccessorApi.bind(ISodiumAccessor.class, new SodiumAccessor()); } + if (SingletonHandler.get(IModChecker.class).isModLoaded("optifine")) { + ModAccessorApi.bind(IOptifineAccessor.class, new OptifineAccessor()); + } } public static void initServer() { diff --git a/fabric/src/main/java/com/seibel/lod/fabric/wrappers/modAccessor/OptifineAccessor.java b/fabric/src/main/java/com/seibel/lod/fabric/wrappers/modAccessor/OptifineAccessor.java new file mode 100644 index 000000000..8a6bbe55f --- /dev/null +++ b/fabric/src/main/java/com/seibel/lod/fabric/wrappers/modAccessor/OptifineAccessor.java @@ -0,0 +1,24 @@ +package com.seibel.lod.fabric.wrappers.modAccessor; + +import java.util.HashSet; + +import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper; +import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor; + +public class OptifineAccessor implements IOptifineAccessor +{ + + @Override + public String getModName() + { + return "Optifine-Fabric-1.18.X"; + } + + @Override + public HashSet getNormalRenderedChunks() + { + // TODO: Impl proper methods here + return null; + } + +} diff --git a/forge/src/main/java/com/seibel/lod/forge/ForgeMain.java b/forge/src/main/java/com/seibel/lod/forge/ForgeMain.java index 3b5a26f45..c43f15feb 100644 --- a/forge/src/main/java/com/seibel/lod/forge/ForgeMain.java +++ b/forge/src/main/java/com/seibel/lod/forge/ForgeMain.java @@ -24,11 +24,16 @@ import com.seibel.lod.common.forge.LodForgeMethodCaller; import com.seibel.lod.common.wrappers.config.ConfigGui; import com.seibel.lod.common.wrappers.minecraft.MinecraftWrapper; import com.seibel.lod.core.ModInfo; +import com.seibel.lod.core.api.ClientApi; +import com.seibel.lod.core.api.ModAccessorApi; +import com.seibel.lod.core.handlers.ReflectionHandler; import com.seibel.lod.core.util.SingletonHandler; import com.seibel.lod.core.wrapperInterfaces.modAccessor.IModChecker; +import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor; import com.seibel.lod.forge.wrappers.ForgeDependencySetup; import com.seibel.lod.forge.wrappers.modAccessor.ModChecker; +import com.seibel.lod.forge.wrappers.modAccessor.OptifineAccessor; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.core.Direction; import net.minecraft.world.level.block.Block; @@ -65,7 +70,12 @@ public class ForgeMain implements LodForgeMethodCaller LodCommonMain.initConfig(); LodCommonMain.startup(this, !FMLLoader.getDist().isClient()); ForgeDependencySetup.createInitialBindings(); + ClientApi.LOGGER.info("Distant Horizons initializing..."); SingletonHandler.bind(IModChecker.class, ModChecker.INSTANCE); + + if (ReflectionHandler.instance.optifinePresent()) { + ModAccessorApi.bind(IOptifineAccessor.class, new OptifineAccessor()); + } } diff --git a/forge/src/main/java/com/seibel/lod/forge/wrappers/modAccessor/OptifineAccessor.java b/forge/src/main/java/com/seibel/lod/forge/wrappers/modAccessor/OptifineAccessor.java new file mode 100644 index 000000000..c595c682b --- /dev/null +++ b/forge/src/main/java/com/seibel/lod/forge/wrappers/modAccessor/OptifineAccessor.java @@ -0,0 +1,24 @@ +package com.seibel.lod.forge.wrappers.modAccessor; + +import java.util.HashSet; + +import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper; +import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor; + +public class OptifineAccessor implements IOptifineAccessor +{ + + @Override + public String getModName() + { + return "Optifine-Forge-1.18.X"; + } + + @Override + public HashSet getNormalRenderedChunks() + { + // TODO: Impl proper methods here + return null; + } + +} diff --git a/gradle.properties b/gradle.properties index a2cd3fb74..fb9694f33 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,6 +18,6 @@ fabric_api_version=0.37.1+1.17 # immersive_portals_version = 0.14-1.17 # Forge loader -forge_version=37.1.0 +forge_version=37.1.1 # Forge mods ## currentlly no mods ##