Reapply "Merge branch 'main' of https://gitlab.com/jeseibel/distant-horizons into serverside"
This reverts commit a2d5e8cdb3.
This commit is contained in:
+1
-1
@@ -26,7 +26,7 @@ import java.util.function.Consumer;
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
|
||||
+30
-5
@@ -55,9 +55,6 @@ import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* This handles creating abstract wrapper objects.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2022-12-5
|
||||
*/
|
||||
public class WrapperFactory implements IWrapperFactory
|
||||
{
|
||||
@@ -82,6 +79,27 @@ public class WrapperFactory implements IWrapperFactory
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDhApiBiomeWrapper getBiomeWrapper(String resourceLocationString, IDhApiLevelWrapper levelWrapper) throws IOException, ClassCastException
|
||||
{
|
||||
if (!(levelWrapper instanceof ILevelWrapper))
|
||||
{
|
||||
throw new ClassCastException("levelWrapper must be returned by DH and of type ["+ILevelWrapper.class.getName()+"].");
|
||||
}
|
||||
|
||||
return BiomeWrapper.deserialize(resourceLocationString, (ILevelWrapper)levelWrapper);
|
||||
}
|
||||
@Override
|
||||
public IDhApiBlockStateWrapper getDefaultBlockStateWrapper(String resourceLocationString, IDhApiLevelWrapper levelWrapper) throws IOException, ClassCastException
|
||||
{
|
||||
if (!(levelWrapper instanceof ILevelWrapper))
|
||||
{
|
||||
throw new ClassCastException("Invalid ["+IDhApiLevelWrapper.class.getSimpleName()+"] value given. Level wrapper object must be one given by the DH API (it can't be a custom implementation), specifically of type ["+ILevelWrapper.class.getName()+"].");
|
||||
}
|
||||
|
||||
return BlockStateWrapper.deserialize(resourceLocationString, (ILevelWrapper)levelWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBiomeWrapper deserializeBiomeWrapper(String str, ILevelWrapper levelWrapper) throws IOException { return BiomeWrapper.deserialize(str, levelWrapper); }
|
||||
@Override
|
||||
@@ -104,6 +122,13 @@ public class WrapperFactory implements IWrapperFactory
|
||||
|
||||
@Override
|
||||
public HashSet<IBlockStateWrapper> getRendererIgnoredBlocks(ILevelWrapper levelWrapper) { return BlockStateWrapper.getRendererIgnoredBlocks(levelWrapper); }
|
||||
@Override
|
||||
public HashSet<IBlockStateWrapper> getRendererIgnoredCaveBlocks(ILevelWrapper levelWrapper) { return BlockStateWrapper.getRendererIgnoredCaveBlocks(levelWrapper); }
|
||||
|
||||
@Override
|
||||
public void resetRendererIgnoredCaveBlocks() { BlockStateWrapper.clearRendererIgnoredCaveBlocks(); }
|
||||
@Override
|
||||
public void resetRendererIgnoredBlocksSet() { BlockStateWrapper.clearRendererIgnoredBlocks(); }
|
||||
|
||||
|
||||
/**
|
||||
@@ -212,7 +237,7 @@ public class WrapperFactory implements IWrapperFactory
|
||||
// confirm the API level wrapper is also a Core wrapper
|
||||
if (!(levelWrapper instanceof ILevelWrapper))
|
||||
{
|
||||
throw new ClassCastException("Unable to cast... only DH provided IDhApiLevelWrapper's can be used."); // TODO
|
||||
throw new ClassCastException("Invalid ["+IDhApiLevelWrapper.class.getSimpleName()+"] value given. Level wrapper object must be one given by the DH API (it can't be a custom implementation), specifically of type ["+ILevelWrapper.class.getName()+"].");
|
||||
}
|
||||
ILevelWrapper coreLevelWrapper = (ILevelWrapper) levelWrapper;
|
||||
|
||||
@@ -271,7 +296,7 @@ public class WrapperFactory implements IWrapperFactory
|
||||
// confirm the API level wrapper is also a Core wrapper
|
||||
if (!(levelWrapper instanceof ILevelWrapper))
|
||||
{
|
||||
throw new ClassCastException("Unable to cast... only DH provided IDhApiLevelWrapper's can be used."); // TODO
|
||||
throw new ClassCastException("Invalid ["+IDhApiLevelWrapper.class.getSimpleName()+"] value given. Level wrapper object must be one given by the DH API (it can't be a custom implementation), specifically of type ["+ILevelWrapper.class.getName()+"].");
|
||||
}
|
||||
ILevelWrapper coreLevelWrapper = (ILevelWrapper) levelWrapper;
|
||||
|
||||
|
||||
+162
-44
@@ -19,7 +19,12 @@
|
||||
|
||||
package com.seibel.distanthorizons.common.wrappers.block;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
@@ -31,8 +36,10 @@ import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
@@ -71,9 +78,8 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
|
||||
public static final String DIRT_RESOURCE_LOCATION_STRING = "minecraft:dirt";
|
||||
|
||||
// TODO: Make this changeable through the config
|
||||
public static final String[] RENDERER_IGNORED_BLOCKS_RESOURCE_LOCATIONS = { AIR_STRING, "minecraft:barrier", "minecraft:structure_void", "minecraft:light", "minecraft:tripwire" };
|
||||
public static HashSet<IBlockStateWrapper> rendererIgnoredBlocks = null;
|
||||
public static HashSet<IBlockStateWrapper> rendererIgnoredCaveBlocks = null;
|
||||
|
||||
/** keep track of broken blocks so we don't log every time */
|
||||
private static final HashSet<ResourceLocation> BrokenResourceLocations = new HashSet<>();
|
||||
@@ -88,11 +94,16 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
private final int hashCode;
|
||||
/**
|
||||
* Cached opacity value, -1 if not populated. <br>
|
||||
* Should be between {@link IBlockStateWrapper#FULLY_OPAQUE} and {@link IBlockStateWrapper#FULLY_OPAQUE}
|
||||
* Should be between {@link LodUtil#BLOCK_FULLY_OPAQUE} and {@link LodUtil#BLOCK_FULLY_OPAQUE}
|
||||
*/
|
||||
private int opacity = -1;
|
||||
/** used by the Iris shader mod to determine how each LOD should be rendered */
|
||||
private byte irisBlockMaterialId = 0;
|
||||
private byte blockMaterialId = 0;
|
||||
|
||||
private final boolean isBeaconBlock;
|
||||
private final boolean isBeaconBaseBlock;
|
||||
private final boolean isGlassBlock;
|
||||
private final Color mapColor;
|
||||
|
||||
|
||||
|
||||
@@ -125,16 +136,46 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
this.blockState = blockState;
|
||||
this.serialString = this.serialize(levelWrapper);
|
||||
this.hashCode = Objects.hash(this.serialString);
|
||||
this.irisBlockMaterialId = this.calculateIrisBlockMaterialId();
|
||||
this.blockMaterialId = this.calculateEDhApiBlockMaterialId().index;
|
||||
|
||||
//LOGGER.trace("Created BlockStateWrapper ["+this.serialString+"] for ["+blockState+"] with material ID ["+this.irisBlockMaterialId+"]");
|
||||
String lowercaseSerial = this.serialString.toLowerCase();
|
||||
boolean isBeaconBaseBlock = false;
|
||||
for (int i = 0; i < LodUtil.BEACON_BASE_BLOCK_NAME_LIST.size(); i++)
|
||||
{
|
||||
String baseBlockName = LodUtil.BEACON_BASE_BLOCK_NAME_LIST.get(i);
|
||||
if (lowercaseSerial.contains(baseBlockName))
|
||||
{
|
||||
isBeaconBaseBlock = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.isBeaconBaseBlock = isBeaconBaseBlock;
|
||||
this.isBeaconBlock = lowercaseSerial.contains("minecraft:beacon");
|
||||
this.isGlassBlock = lowercaseSerial.contains("glass");
|
||||
|
||||
int mcColor = 0;
|
||||
if (this.blockState != null)
|
||||
{
|
||||
#if MC_VER < MC_1_20_1
|
||||
mcColor = this.blockState.getMaterial().getColor().col;
|
||||
#else
|
||||
mcColor = this.blockState.getMapColor(EmptyBlockGetter.INSTANCE, BlockPos.ZERO).col;
|
||||
#endif
|
||||
this.mapColor = ColorUtil.toColorObjRGB(mcColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.mapColor = new Color(0,0,0,0);
|
||||
}
|
||||
|
||||
//LOGGER.trace("Created BlockStateWrapper ["+this.serialString+"] for ["+blockState+"] with material ID ["+this.EDhApiBlockMaterialId+"]");
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper methods //
|
||||
//================//
|
||||
//====================//
|
||||
// LodBuilder methods //
|
||||
//====================//
|
||||
|
||||
/**
|
||||
* Requires a {@link ILevelWrapper} since {@link BlockStateWrapper#deserialize(String,ILevelWrapper)} also requires one.
|
||||
@@ -148,37 +189,104 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
return rendererIgnoredBlocks;
|
||||
}
|
||||
|
||||
HashSet<String> baseIgnoredBlock = new HashSet<>();
|
||||
baseIgnoredBlock.add(AIR_STRING);
|
||||
rendererIgnoredBlocks = getBlockWrappers(Config.Client.Advanced.LodBuilding.ignoredRenderBlockCsv, baseIgnoredBlock, levelWrapper);
|
||||
return rendererIgnoredBlocks;
|
||||
}
|
||||
/**
|
||||
* Requires a {@link ILevelWrapper} since {@link BlockStateWrapper#deserialize(String,ILevelWrapper)} also requires one.
|
||||
* This way the method won't accidentally be called before the deserialization can be completed.
|
||||
*/
|
||||
public static HashSet<IBlockStateWrapper> getRendererIgnoredCaveBlocks(ILevelWrapper levelWrapper)
|
||||
{
|
||||
// use the cached version if possible
|
||||
if (rendererIgnoredCaveBlocks != null)
|
||||
{
|
||||
return rendererIgnoredCaveBlocks;
|
||||
}
|
||||
|
||||
HashSet<String> baseIgnoredBlock = new HashSet<>();
|
||||
baseIgnoredBlock.add(AIR_STRING);
|
||||
rendererIgnoredCaveBlocks = getBlockWrappers(Config.Client.Advanced.LodBuilding.ignoredRenderCaveBlockCsv, baseIgnoredBlock, levelWrapper);
|
||||
return rendererIgnoredCaveBlocks;
|
||||
}
|
||||
|
||||
public static void clearRendererIgnoredBlocks() { rendererIgnoredBlocks = null; }
|
||||
public static void clearRendererIgnoredCaveBlocks() { rendererIgnoredCaveBlocks = null; }
|
||||
|
||||
|
||||
|
||||
// lod builder helpers //
|
||||
|
||||
private static HashSet<IBlockStateWrapper> getBlockWrappers(ConfigEntry<String> config, HashSet<String> baseResourceLocations, ILevelWrapper levelWrapper)
|
||||
{
|
||||
// get the base blocks
|
||||
HashSet<String> blockStringList = new HashSet<>();
|
||||
if (baseResourceLocations != null)
|
||||
{
|
||||
blockStringList.addAll(baseResourceLocations);
|
||||
}
|
||||
|
||||
// get the config blocks
|
||||
String ignoreBlockCsv = config.get();
|
||||
if (ignoreBlockCsv != null)
|
||||
{
|
||||
blockStringList.addAll(List.of(ignoreBlockCsv.split(",")));
|
||||
}
|
||||
|
||||
return getBlockWrappers(blockStringList, levelWrapper);
|
||||
}
|
||||
private static HashSet<IBlockStateWrapper> getBlockWrappers(HashSet<String> blockResourceLocationSet, ILevelWrapper levelWrapper)
|
||||
{
|
||||
// deserialize each of the given resource locations
|
||||
HashSet<IBlockStateWrapper> blockStateWrappers = new HashSet<>();
|
||||
for (String blockResourceLocation : RENDERER_IGNORED_BLOCKS_RESOURCE_LOCATIONS)
|
||||
for (String blockResourceLocation : blockResourceLocationSet)
|
||||
{
|
||||
try
|
||||
{
|
||||
BlockStateWrapper DefaultBlockStateToIgnore = (BlockStateWrapper) deserialize(blockResourceLocation, levelWrapper);
|
||||
blockStateWrappers.add(DefaultBlockStateToIgnore);
|
||||
|
||||
if (DefaultBlockStateToIgnore == AIR)
|
||||
if (blockResourceLocation == null)
|
||||
{
|
||||
// shouldn't happen, but just in case
|
||||
continue;
|
||||
}
|
||||
String cleanedResourceLocation = blockResourceLocation.trim();
|
||||
if (cleanedResourceLocation.length() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// add all possible blockstates (to account for light blocks with different light values and such)
|
||||
List<BlockState> blockStatesToIgnore = DefaultBlockStateToIgnore.blockState.getBlock().getStateDefinition().getPossibleStates();
|
||||
for (BlockState blockState : blockStatesToIgnore)
|
||||
|
||||
BlockStateWrapper defaultBlockStateToIgnore = (BlockStateWrapper) deserialize(cleanedResourceLocation, levelWrapper);
|
||||
blockStateWrappers.add(defaultBlockStateToIgnore);
|
||||
|
||||
if (defaultBlockStateToIgnore != AIR)
|
||||
{
|
||||
BlockStateWrapper newBlockToIgnore = BlockStateWrapper.fromBlockState(blockState, levelWrapper);
|
||||
blockStateWrappers.add(newBlockToIgnore);
|
||||
// add all possible blockstates (to account for light blocks with different light values and such)
|
||||
List<BlockState> blockStatesToIgnore = defaultBlockStateToIgnore.blockState.getBlock().getStateDefinition().getPossibleStates();
|
||||
for (BlockState blockState : blockStatesToIgnore)
|
||||
{
|
||||
BlockStateWrapper newBlockToIgnore = BlockStateWrapper.fromBlockState(blockState, levelWrapper);
|
||||
blockStateWrappers.add(newBlockToIgnore);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// air is a special case so it must be handled separately
|
||||
blockStateWrappers.add(AIR);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOGGER.warn("Unable to deserialize rendererIgnoredBlock with the resource location: ["+blockResourceLocation+"]. Error: "+e.getMessage(), e);
|
||||
LOGGER.warn("Unable to deserialize block with the resource location: ["+blockResourceLocation+"]. Error: "+e.getMessage(), e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warn("Unexpected error deserializing block with the resource location: ["+blockResourceLocation+"]. Error: "+e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
rendererIgnoredBlocks = blockStateWrappers;
|
||||
return rendererIgnoredBlocks;
|
||||
return blockStateWrappers;
|
||||
}
|
||||
|
||||
|
||||
@@ -201,23 +309,23 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
int opacity;
|
||||
if (this.isAir())
|
||||
{
|
||||
opacity = FULLY_TRANSPARENT;
|
||||
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT;
|
||||
}
|
||||
else if (this.isLiquid() && !this.blockState.canOcclude())
|
||||
{
|
||||
// probably not a waterlogged block (which should block light entirely)
|
||||
|
||||
// +1 to indicate that the block is translucent (in between transparent and opaque)
|
||||
opacity = FULLY_TRANSPARENT + 1;
|
||||
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT + 1;
|
||||
}
|
||||
else if (this.blockState.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO))
|
||||
{
|
||||
opacity = FULLY_TRANSPARENT;
|
||||
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// default for all other blocks
|
||||
opacity = FULLY_OPAQUE;
|
||||
opacity = LodUtil.BLOCK_FULLY_OPAQUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -286,7 +394,17 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getIrisBlockMaterialId() { return this.irisBlockMaterialId; }
|
||||
public boolean isBeaconBlock() { return this.isBeaconBlock; }
|
||||
@Override
|
||||
public boolean isBeaconBaseBlock() { return this.isBeaconBaseBlock; }
|
||||
@Override
|
||||
public boolean isGlassBlock() { return this.isGlassBlock; }
|
||||
|
||||
@Override
|
||||
public Color getMapColor() { return this.mapColor; }
|
||||
|
||||
@Override
|
||||
public byte getMaterialId() { return this.blockMaterialId; }
|
||||
|
||||
@Override
|
||||
public String toString() { return this.getSerialString(); }
|
||||
@@ -509,11 +627,11 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
// Iris methods //
|
||||
//==============//
|
||||
|
||||
private byte calculateIrisBlockMaterialId()
|
||||
private EDhApiBlockMaterial calculateEDhApiBlockMaterialId()
|
||||
{
|
||||
if (this.blockState == null)
|
||||
{
|
||||
return IrisBlockMaterial.AIR;
|
||||
return EDhApiBlockMaterial.AIR;
|
||||
}
|
||||
|
||||
|
||||
@@ -526,15 +644,15 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
|| serialString.contains("mushroom")
|
||||
)
|
||||
{
|
||||
return IrisBlockMaterial.LEAVES;
|
||||
return EDhApiBlockMaterial.LEAVES;
|
||||
}
|
||||
else if (this.blockState.is(Blocks.LAVA))
|
||||
{
|
||||
return IrisBlockMaterial.LAVA;
|
||||
return EDhApiBlockMaterial.LAVA;
|
||||
}
|
||||
else if (this.isLiquid() || this.blockState.is(Blocks.WATER))
|
||||
{
|
||||
return IrisBlockMaterial.WATER;
|
||||
return EDhApiBlockMaterial.WATER;
|
||||
}
|
||||
else if (this.blockState.getSoundType() == SoundType.WOOD
|
||||
|| serialString.contains("root")
|
||||
@@ -543,7 +661,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return IrisBlockMaterial.WOOD;
|
||||
return EDhApiBlockMaterial.WOOD;
|
||||
}
|
||||
else if (this.blockState.getSoundType() == SoundType.METAL
|
||||
#if MC_VER >= MC_1_19_2
|
||||
@@ -555,11 +673,11 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return IrisBlockMaterial.METAL;
|
||||
return EDhApiBlockMaterial.METAL;
|
||||
}
|
||||
else if (serialString.contains("grass_block"))
|
||||
{
|
||||
return IrisBlockMaterial.GRASS;
|
||||
return EDhApiBlockMaterial.GRASS;
|
||||
}
|
||||
else if (
|
||||
serialString.contains("dirt")
|
||||
@@ -569,7 +687,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
|| serialString.contains("mycelium")
|
||||
)
|
||||
{
|
||||
return IrisBlockMaterial.DIRT;
|
||||
return EDhApiBlockMaterial.DIRT;
|
||||
}
|
||||
#if MC_VER >= MC_1_17_1
|
||||
else if (this.blockState.getSoundType() == SoundType.DEEPSLATE
|
||||
@@ -578,37 +696,37 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
|| this.blockState.getSoundType() == SoundType.POLISHED_DEEPSLATE
|
||||
|| serialString.contains("deepslate") )
|
||||
{
|
||||
return IrisBlockMaterial.DEEPSLATE;
|
||||
return EDhApiBlockMaterial.DEEPSLATE;
|
||||
}
|
||||
#endif
|
||||
else if (this.serialString.contains("snow"))
|
||||
{
|
||||
return IrisBlockMaterial.SNOW;
|
||||
return EDhApiBlockMaterial.SNOW;
|
||||
}
|
||||
else if (serialString.contains("sand"))
|
||||
{
|
||||
return IrisBlockMaterial.SAND;
|
||||
return EDhApiBlockMaterial.SAND;
|
||||
}
|
||||
else if (serialString.contains("terracotta"))
|
||||
{
|
||||
return IrisBlockMaterial.TERRACOTTA;
|
||||
return EDhApiBlockMaterial.TERRACOTTA;
|
||||
}
|
||||
else if (this.blockState.is(BlockTags.BASE_STONE_NETHER))
|
||||
{
|
||||
return IrisBlockMaterial.NETHER_STONE;
|
||||
return EDhApiBlockMaterial.NETHER_STONE;
|
||||
}
|
||||
else if (serialString.contains("stone")
|
||||
|| serialString.contains("ore"))
|
||||
{
|
||||
return IrisBlockMaterial.STONE;
|
||||
return EDhApiBlockMaterial.STONE;
|
||||
}
|
||||
else if (this.blockState.getLightEmission() > 0)
|
||||
{
|
||||
return IrisBlockMaterial.ILLUMINATED;
|
||||
return EDhApiBlockMaterial.ILLUMINATED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IrisBlockMaterial.UNKOWN;
|
||||
return EDhApiBlockMaterial.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-10
@@ -227,6 +227,9 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
LevelChunkSection[] sections = this.chunk.getSections();
|
||||
for (int index = sections.length-1; index >= 0; index--)
|
||||
{
|
||||
// update at each position to fix using the max height if the chunk is empty
|
||||
this.maxNonEmptyHeight = this.getChunkSectionMinHeight(index) + 16;
|
||||
|
||||
if (sections[index] == null)
|
||||
{
|
||||
continue;
|
||||
@@ -234,7 +237,7 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
|
||||
if (!isChunkSectionEmpty(sections[index]))
|
||||
{
|
||||
this.maxNonEmptyHeight = this.getChunkSectionMinHeight(index) + 16;
|
||||
// non-empty section found
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -251,15 +254,7 @@ public class ChunkWrapper implements IChunkWrapper
|
||||
return section.hasOnlyAir();
|
||||
#endif
|
||||
}
|
||||
private int getChunkSectionMinHeight(int index)
|
||||
{
|
||||
// convert from an index to a block coordinate
|
||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||
return this.chunk.getSections()[index].bottomBlockY();
|
||||
#else
|
||||
return this.chunk.getSectionYFromSectionIndex(index) * 16;
|
||||
#endif
|
||||
}
|
||||
private int getChunkSectionMinHeight(int index) { return (index * 16) + this.getMinBuildHeight(); }
|
||||
|
||||
|
||||
@Override
|
||||
|
||||
+12
-7
@@ -158,19 +158,22 @@ public class ClassicConfigGUI
|
||||
// button.active = entries.stream().allMatch(e -> e.inLimits);
|
||||
|
||||
|
||||
if (((ConfigEntry) info).isValid(value) == 0 && info.getType() != List.class)
|
||||
if (info.getType() == String.class
|
||||
|| info.getType() == List.class)
|
||||
{
|
||||
((ConfigEntry) info).uiSetWithoutSaving(stringValue);
|
||||
}
|
||||
else if (((ConfigEntry) info).isValid(value) == 0)
|
||||
{
|
||||
if (!cast)
|
||||
{
|
||||
((ConfigEntry) info).uiSetWithoutSaving(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
((ConfigEntry) info).uiSetWithoutSaving(value.intValue());
|
||||
}
|
||||
}
|
||||
// else if (((ConfigEntry) info).isValidMemoryAddress() == 0)
|
||||
// {
|
||||
// if (((List<String>) info.get()).size() == ((EntryInfo) info.guiValue).index)
|
||||
// info.uiSet(((List<String>) info.get()).add(""));
|
||||
// info.uiSet(((List<String>) info.get()).set(((EntryInfo) info.guiValue).index, Arrays.stream(((EntryInfo) info.guiValue).tempValue.replace("[", "").replace("]", "").split(", ")).collect(Collectors.toList()).get(0)));
|
||||
// }
|
||||
|
||||
return true;
|
||||
};
|
||||
@@ -443,7 +446,9 @@ public class ClassicConfigGUI
|
||||
String key = translationPrefix + (newInfo.category.isEmpty() ? "" : newInfo.category + ".") + newInfo.getName() + ".@tooltip";
|
||||
|
||||
if (((EntryInfo) newInfo.guiValue).error != null && text.equals(name))
|
||||
{
|
||||
DhRenderTooltip(matrices, font, ((EntryInfo) newInfo.guiValue).error.getValue(), mouseX, mouseY);
|
||||
}
|
||||
else if (I18n.exists(key) && (text != null && text.equals(name)))
|
||||
{
|
||||
List<Component> list = new ArrayList<>();
|
||||
|
||||
+9
-3
@@ -101,11 +101,17 @@ public class ChangelogScreen extends DhScreen
|
||||
this.changelog.add("");
|
||||
this.changelog.add("");
|
||||
|
||||
String changelog = ModrinthGetter.changeLogs.get(versionID);
|
||||
if (changelog == null)
|
||||
{
|
||||
// in case something goes wrong this will prevent null pointers
|
||||
changelog = "";
|
||||
}
|
||||
|
||||
// Get the release changelog and split it by the new lines
|
||||
String[] unwrappedChangelog = // Arrays.asList could be used if a list object is desired here vs List.of which is only available for Java 9+
|
||||
new MarkdownFormatter.MinecraftFormat().convertTo( // This formats markdown to minecraft's "§" characters
|
||||
ModrinthGetter.changeLogs.get(versionID)
|
||||
).split("\\n");
|
||||
// This formats markdown to minecraft's "§" charactersnew MarkdownFormatter.MinecraftFormat().convertTo(
|
||||
new MarkdownFormatter.MinecraftFormat().convertTo(changelog).split("\\n");
|
||||
// Makes the words wrap around to not go off the screen
|
||||
for (String str : unwrappedChangelog)
|
||||
{
|
||||
|
||||
+55
-65
@@ -31,6 +31,7 @@ import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
@@ -44,6 +45,7 @@ import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import net.minecraft.CrashReport;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.multiplayer.ServerData;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -60,16 +62,15 @@ import org.jetbrains.annotations.Nullable;
|
||||
* A singleton that wraps the Minecraft object.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 3-5-2022
|
||||
*/
|
||||
//@Environment(EnvType.CLIENT)
|
||||
public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecraftSharedWrapper
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
||||
private static final Minecraft MINECRAFT = Minecraft.getInstance();
|
||||
|
||||
public static final MinecraftClientWrapper INSTANCE = new MinecraftClientWrapper();
|
||||
|
||||
public final Minecraft mc = Minecraft.getInstance();
|
||||
|
||||
|
||||
/**
|
||||
* The lightmap for the current:
|
||||
@@ -100,10 +101,7 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
||||
* This doesn't affect OpenGL objects in any way.
|
||||
*/
|
||||
@Override
|
||||
public void clearFrameObjectCache()
|
||||
{
|
||||
this.lightMap = null;
|
||||
}
|
||||
public void clearFrameObjectCache() { this.lightMap = null; }
|
||||
|
||||
|
||||
|
||||
@@ -119,10 +117,10 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
||||
{
|
||||
default:
|
||||
case AUTO:
|
||||
if (this.mc.level != null)
|
||||
if (MINECRAFT.level != null)
|
||||
{
|
||||
Direction mcDir = McObjectConverter.Convert(lodDirection);
|
||||
return this.mc.level.getShade(mcDir, true);
|
||||
return MINECRAFT.level.getShade(mcDir, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -151,42 +149,58 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSinglePlayerServer() { return this.mc.hasSingleplayerServer(); }
|
||||
public boolean hasSinglePlayerServer() { return MINECRAFT.hasSingleplayerServer(); }
|
||||
@Override
|
||||
public boolean clientConnectedToDedicatedServer() { return this.mc.getCurrentServer() != null && !this.hasSinglePlayerServer(); }
|
||||
public boolean clientConnectedToDedicatedServer() { return MINECRAFT.getCurrentServer() != null && !this.hasSinglePlayerServer(); }
|
||||
@Override
|
||||
public boolean connectedToReplay() { return !MINECRAFT.hasSingleplayerServer() && MINECRAFT.getCurrentServer() == null; }
|
||||
|
||||
@Override
|
||||
public String getCurrentServerName() { return this.mc.getCurrentServer().name; }
|
||||
public String getCurrentServerName()
|
||||
{
|
||||
if (this.connectedToReplay())
|
||||
{
|
||||
return ClientOnlySaveStructure.REPLAY_SERVER_FOLDER_NAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerData server = MINECRAFT.getCurrentServer();
|
||||
return (server != null) ? server.name : "NULL";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentServerIp() { return this.mc.getCurrentServer().ip; }
|
||||
public String getCurrentServerIp()
|
||||
{
|
||||
if (this.connectedToReplay())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerData server = MINECRAFT.getCurrentServer();
|
||||
return (server != null) ? server.ip : "NA";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentServerVersion()
|
||||
{
|
||||
return this.mc.getCurrentServer().version.getString();
|
||||
ServerData server = MINECRAFT.getCurrentServer();
|
||||
return (server != null) ? server.version.getString() : "UNKOWN";
|
||||
}
|
||||
|
||||
//=============//
|
||||
// Simple gets //
|
||||
//=============//
|
||||
|
||||
public LocalPlayer getPlayer()
|
||||
{
|
||||
return this.mc.player;
|
||||
}
|
||||
public LocalPlayer getPlayer() { return MINECRAFT.player; }
|
||||
|
||||
@Override
|
||||
public boolean playerExists()
|
||||
{
|
||||
return this.mc.player != null;
|
||||
}
|
||||
public boolean playerExists() { return MINECRAFT.player != null; }
|
||||
|
||||
@Override
|
||||
public UUID getPlayerUUID()
|
||||
{
|
||||
return this.getPlayer().getUUID();
|
||||
}
|
||||
public UUID getPlayerUUID() { return this.getPlayer().getUUID(); }
|
||||
|
||||
@Override
|
||||
public DhBlockPos getPlayerBlockPos()
|
||||
@@ -199,18 +213,13 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
||||
public DhChunkPos getPlayerChunkPos()
|
||||
{
|
||||
#if MC_VER < MC_1_17_1
|
||||
ChunkPos playerPos = new ChunkPos(getPlayer().blockPosition());
|
||||
ChunkPos playerPos = new ChunkPos(this.getPlayer().blockPosition());
|
||||
#else
|
||||
ChunkPos playerPos = this.getPlayer().chunkPosition();
|
||||
#endif
|
||||
return new DhChunkPos(playerPos.x, playerPos.z);
|
||||
}
|
||||
|
||||
public ModelManager getModelManager()
|
||||
{
|
||||
return this.mc.getModelManager();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IClientLevelWrapper getWrappedClientLevel()
|
||||
@@ -222,7 +231,7 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
||||
@Nullable
|
||||
public IClientLevelWrapper getWrappedClientLevel(boolean bypassMultiverse)
|
||||
{
|
||||
ClientLevel level = this.mc.level;
|
||||
ClientLevel level = MINECRAFT.level;
|
||||
if (level == null)
|
||||
{
|
||||
return null;
|
||||
@@ -231,25 +240,18 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
||||
return ClientLevelWrapper.getWrapper(level, bypassMultiverse);
|
||||
}
|
||||
|
||||
/** Please move over to getInstallationDirectory() */
|
||||
@Deprecated
|
||||
@Override
|
||||
public File getGameDirectory()
|
||||
{
|
||||
return this.getInstallationDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProfilerWrapper getProfiler()
|
||||
{
|
||||
if (this.profilerWrapper == null)
|
||||
{
|
||||
this.profilerWrapper = new ProfilerWrapper(this.mc.getProfiler());
|
||||
this.profilerWrapper = new ProfilerWrapper(MINECRAFT.getProfiler());
|
||||
}
|
||||
else if (this.mc.getProfiler() != this.profilerWrapper.profiler)
|
||||
else if (MINECRAFT.getProfiler() != this.profilerWrapper.profiler)
|
||||
{
|
||||
this.profilerWrapper.profiler = this.mc.getProfiler();
|
||||
this.profilerWrapper.profiler = MINECRAFT.getProfiler();
|
||||
}
|
||||
|
||||
return this.profilerWrapper;
|
||||
}
|
||||
|
||||
@@ -259,7 +261,7 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
||||
{
|
||||
ArrayList<ILevelWrapper> worlds = new ArrayList<ILevelWrapper>();
|
||||
|
||||
Iterable<ServerLevel> serverWorlds = this.mc.getSingleplayerServer().getAllLevels();
|
||||
Iterable<ServerLevel> serverWorlds = MINECRAFT.getSingleplayerServer().getAllLevels();
|
||||
for (ServerLevel world : serverWorlds)
|
||||
{
|
||||
worlds.add(ServerLevelWrapper.getWrapper(world));
|
||||
@@ -273,15 +275,12 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
||||
@Override
|
||||
public void sendChatMessage(String string)
|
||||
{
|
||||
LocalPlayer p = this.getPlayer();
|
||||
if (p == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
LocalPlayer player = this.getPlayer();
|
||||
if (player == null) return;
|
||||
#if MC_VER < MC_1_19_2
|
||||
p.sendMessage(new TextComponent(string), getPlayer().getUUID());
|
||||
player.sendMessage(new TextComponent(string), getPlayer().getUUID());
|
||||
#else
|
||||
p.sendSystemMessage(net.minecraft.network.chat.Component.translatable(string));
|
||||
player.sendSystemMessage(net.minecraft.network.chat.Component.translatable(string));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -306,24 +305,15 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getOptionsObject()
|
||||
{
|
||||
return this.mc.options;
|
||||
}
|
||||
public Object getOptionsObject() { return MINECRAFT.options; }
|
||||
|
||||
@Override
|
||||
public boolean isDedicatedServer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public boolean isDedicatedServer() { return false; }
|
||||
|
||||
@Override
|
||||
public File getInstallationDirectory()
|
||||
{
|
||||
return this.mc.gameDirectory;
|
||||
}
|
||||
public File getInstallationDirectory() { return MINECRAFT.gameDirectory; }
|
||||
|
||||
@Override
|
||||
public void executeOnRenderThread(Runnable runnable) { this.mc.execute(runnable); }
|
||||
public void executeOnRenderThread(Runnable runnable) { MINECRAFT.execute(runnable); }
|
||||
|
||||
}
|
||||
|
||||
+5
-8
@@ -21,9 +21,7 @@ package com.seibel.distanthorizons.common.wrappers.minecraft;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -38,10 +36,10 @@ import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.render.DhApiRenderProxy;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
||||
|
||||
#if MC_VER < MC_1_19_4
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
#else
|
||||
import org.joml.Matrix4f;
|
||||
@@ -55,9 +53,9 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOpt
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IDimensionTypeWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3d;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3d;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3f;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
||||
@@ -81,7 +79,6 @@ import net.minecraft.world.level.material.FogType;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
|
||||
/**
|
||||
@@ -415,7 +412,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
||||
// so this will have to do for now
|
||||
IDimensionTypeWrapper dimensionType = level.getDimensionType();
|
||||
|
||||
LightMapWrapper wrapper = this.lightmapByDimensionType.compute(dimensionType, (dimType, oldWrapper) -> new LightMapWrapper());
|
||||
LightMapWrapper wrapper = this.lightmapByDimensionType.computeIfAbsent(dimensionType, (dimType) -> new LightMapWrapper());
|
||||
wrapper.uploadLightmap(lightPixels);
|
||||
}
|
||||
|
||||
|
||||
+12
-9
@@ -36,14 +36,6 @@ public class LightMapWrapper implements ILightMapWrapper
|
||||
|
||||
public LightMapWrapper() { }
|
||||
|
||||
private void createLightmap(NativeImage image)
|
||||
{
|
||||
this.textureId = GL32.glGenTextures();
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.textureId);
|
||||
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, image.format().glFormat(), image.getWidth(), image.getHeight(),
|
||||
0, image.format().glFormat(), GL32.GL_UNSIGNED_BYTE, (ByteBuffer) null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
@@ -53,14 +45,25 @@ public class LightMapWrapper implements ILightMapWrapper
|
||||
public void uploadLightmap(NativeImage image)
|
||||
{
|
||||
int currentBind = GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.textureId);
|
||||
if (this.textureId == 0)
|
||||
{
|
||||
this.createLightmap(image);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.textureId);
|
||||
}
|
||||
image.upload(0, 0, 0, false);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, currentBind);
|
||||
}
|
||||
private void createLightmap(NativeImage image)
|
||||
{
|
||||
this.textureId = GL32.glGenTextures();
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.textureId);
|
||||
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, image.format().glFormat(), image.getWidth(), image.getHeight(),
|
||||
0, image.format().glFormat(), GL32.GL_UNSIGNED_BYTE, (ByteBuffer) null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void bind()
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import com.google.common.collect.MapMaker;
|
||||
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3d;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3d;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.ServerPlayerConnection;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
+41
-6
@@ -1,14 +1,14 @@
|
||||
package com.seibel.distanthorizons.common.wrappers.world;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
|
||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.block.cache.ClientBlockDetailMap;
|
||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.level.IKeyedClientLevelManager;
|
||||
import com.seibel.distanthorizons.core.level.*;
|
||||
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
@@ -19,6 +19,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IDimensionTypeWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
@@ -39,14 +40,18 @@ import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||
public class ClientLevelWrapper implements IClientLevelWrapper
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(ClientLevelWrapper.class.getSimpleName());
|
||||
private static final ConcurrentHashMap<ClientLevel, ClientLevelWrapper> LEVEL_WRAPPER_BY_CLIENT_LEVEL = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentHashMap<ClientLevel, ClientLevelWrapper> LEVEL_WRAPPER_BY_CLIENT_LEVEL = new ConcurrentHashMap<>(); // TODO can leak
|
||||
private static final IKeyedClientLevelManager KEYED_CLIENT_LEVEL_MANAGER = SingletonInjector.INSTANCE.get(IKeyedClientLevelManager.class);
|
||||
|
||||
private static final Minecraft MINECRAFT = Minecraft.getInstance();
|
||||
|
||||
private final ClientLevel level;
|
||||
private final ClientBlockDetailMap blockMap = new ClientBlockDetailMap(this);
|
||||
|
||||
private BlockStateWrapper dirtBlockWrapper;
|
||||
private BiomeWrapper plainsBiomeWrapper;
|
||||
@Deprecated // TODO circular references are bad
|
||||
private IDhLevel parentDhLevel;
|
||||
|
||||
|
||||
|
||||
@@ -94,7 +99,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
||||
{
|
||||
try
|
||||
{
|
||||
Iterable<ServerLevel> serverLevels = MinecraftClientWrapper.INSTANCE.mc.getSingleplayerServer().getAllLevels();
|
||||
Iterable<ServerLevel> serverLevels = MINECRAFT.getSingleplayerServer().getAllLevels();
|
||||
|
||||
// attempt to find the server level with the same dimension type
|
||||
// TODO this assumes only one level per dimension type, the SubDimensionLevelMatcher will need to be added for supporting multiple levels per dimension
|
||||
@@ -191,7 +196,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
||||
public boolean hasSkyLight() { return this.level.dimensionType().hasSkyLight(); }
|
||||
|
||||
@Override
|
||||
public int getHeight() { return this.level.getHeight(); }
|
||||
public int getMaxHeight() { return this.level.getHeight(); }
|
||||
|
||||
@Override
|
||||
public int getMinHeight()
|
||||
@@ -240,7 +245,37 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
||||
public ClientLevel getWrappedMcObject() { return this.level; }
|
||||
|
||||
@Override
|
||||
public void onUnload() { LEVEL_WRAPPER_BY_CLIENT_LEVEL.remove(this.level); }
|
||||
public void onUnload()
|
||||
{
|
||||
LEVEL_WRAPPER_BY_CLIENT_LEVEL.remove(this.level);
|
||||
this.parentDhLevel = null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===================//
|
||||
// generic rendering //
|
||||
//===================//
|
||||
|
||||
@Override
|
||||
public void setParentLevel(IDhLevel parentLevel) { this.parentDhLevel = parentLevel; }
|
||||
|
||||
@Override
|
||||
public IDhApiCustomRenderRegister getRenderRegister()
|
||||
{
|
||||
if (this.parentDhLevel == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.parentDhLevel.getGenericRenderer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// base overrides //
|
||||
//================//
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
|
||||
+28
-26
@@ -23,19 +23,18 @@ import java.io.File;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
|
||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.block.cache.ServerBlockDetailMap;
|
||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@@ -49,7 +48,6 @@ import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||
#endif
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @version 2022-9-16
|
||||
@@ -59,8 +57,9 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
private static final ConcurrentHashMap<ServerLevel, ServerLevelWrapper> LEVEL_WRAPPER_BY_SERVER_LEVEL = new ConcurrentHashMap<>();
|
||||
|
||||
final ServerLevel level;
|
||||
ServerBlockDetailMap blockMap = new ServerBlockDetailMap(this);
|
||||
private final ServerLevel level;
|
||||
@Deprecated // TODO circular references are bad
|
||||
private IDhLevel parentDhLevel;
|
||||
|
||||
|
||||
|
||||
@@ -81,19 +80,6 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
||||
// methods //
|
||||
//=========//
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IClientLevelWrapper tryGetClientLevelWrapper()
|
||||
{
|
||||
MinecraftClientWrapper client = MinecraftClientWrapper.INSTANCE;
|
||||
if (client.mc.level == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ClientLevelWrapper.getWrapper(client.mc.level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getSaveFolder()
|
||||
{
|
||||
@@ -133,7 +119,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight()
|
||||
public int getMaxHeight()
|
||||
{
|
||||
return this.level.getHeight();
|
||||
}
|
||||
@@ -147,6 +133,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
||||
return this.level.getMinBuildHeight();
|
||||
#endif
|
||||
}
|
||||
|
||||
@Override
|
||||
public IChunkWrapper tryGetChunk(DhChunkPos pos)
|
||||
{
|
||||
@@ -183,18 +170,33 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerLevel getWrappedMcObject()
|
||||
{
|
||||
return this.level;
|
||||
}
|
||||
public ServerLevel getWrappedMcObject() { return this.level; }
|
||||
|
||||
@Override
|
||||
public void onUnload() { LEVEL_WRAPPER_BY_SERVER_LEVEL.remove(this.level); }
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
public void setParentLevel(IDhLevel parentLevel) { this.parentDhLevel = parentLevel; }
|
||||
|
||||
@Override
|
||||
public IDhApiCustomRenderRegister getRenderRegister()
|
||||
{
|
||||
return "Wrapped{" + this.level.toString() + "@" + this.getDimensionName() + "}";
|
||||
if (this.parentDhLevel == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.parentDhLevel.getGenericRenderer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// base overrides //
|
||||
//================//
|
||||
|
||||
@Override
|
||||
public String toString() { return "Wrapped{" + this.level.toString() + "@" + this.getDimensionName() + "}"; }
|
||||
|
||||
}
|
||||
+14
-12
@@ -346,8 +346,11 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
||||
}
|
||||
else if (event.hasTimeout(Config.Client.Advanced.WorldGenerator.worldGenerationTimeoutLengthInSeconds.get(), TimeUnit.SECONDS))
|
||||
{
|
||||
EVENT_LOGGER.error("Batching World Generator: " + event + " timed out and terminated! Please lower your CPU load.");
|
||||
EVENT_LOGGER.info("Dump PrefEvent: " + event.timer);
|
||||
EVENT_LOGGER.warn(
|
||||
"Batching World Generator: [" + event + "] timed out and terminated after ["+Config.Client.Advanced.WorldGenerator.worldGenerationTimeoutLengthInSeconds.get()+"] seconds. " +
|
||||
"\nYour computer might be overloaded or your world gen mods might be causing world gen to take longer than expected. " +
|
||||
"\nEither increase DH's world gen timeout or reduce your computer's CPU load.");
|
||||
EVENT_LOGGER.debug("Dump PrefEvent: " + event.timer);
|
||||
try
|
||||
{
|
||||
if (!event.terminate())
|
||||
@@ -416,12 +419,15 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
||||
CompoundTag chunkData = this.getChunkNbtData(chunkPos);
|
||||
newChunk = this.loadOrMakeChunk(chunkPos, chunkData);
|
||||
|
||||
// get chunk lighting
|
||||
ChunkLoader.CombinedChunkLightStorage combinedLights = ChunkLoader.readLight(newChunk, chunkData);
|
||||
if (combinedLights != null)
|
||||
if (Config.Client.Advanced.LodBuilding.pullLightingForPregeneratedChunks.get())
|
||||
{
|
||||
chunkSkyLightingByDhPos.put(dhChunkPos, combinedLights.skyLightStorage);
|
||||
chunkBlockLightingByDhPos.put(dhChunkPos, combinedLights.blockLightStorage);
|
||||
// attempt to get chunk lighting
|
||||
ChunkLoader.CombinedChunkLightStorage combinedLights = ChunkLoader.readLight(newChunk, chunkData);
|
||||
if (combinedLights != null)
|
||||
{
|
||||
chunkSkyLightingByDhPos.put(dhChunkPos, combinedLights.skyLightStorage);
|
||||
chunkBlockLightingByDhPos.put(dhChunkPos, combinedLights.blockLightStorage);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (RuntimeException loadChunkError)
|
||||
@@ -471,7 +477,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
||||
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, region, this.serverlevel.getLevelWrapper());
|
||||
chunkWrapperList.set(x, z, chunkWrapper);
|
||||
|
||||
// try getting the chunk lighting
|
||||
// try setting the wrapper's lighting
|
||||
if (chunkBlockLightingByDhPos.containsKey(chunkWrapper.getChunkPos()))
|
||||
{
|
||||
chunkWrapper.setBlockLightStorage(chunkBlockLightingByDhPos.get(chunkWrapper.getChunkPos()));
|
||||
@@ -479,10 +485,6 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
||||
chunkWrapper.setUseDhLighting(true);
|
||||
chunkWrapper.setIsDhLightCorrect(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
int k = 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+10
-6
@@ -252,8 +252,8 @@ public class ChunkLoader
|
||||
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
||||
#endif
|
||||
#endif
|
||||
int i = #if MC_VER < MC_1_17_1 16; #else level.getSectionsCount(); #endif
|
||||
LevelChunkSection[] chunkSections = new LevelChunkSection[i];
|
||||
int sectionYIndex = #if MC_VER < MC_1_17_1 16; #else level.getSectionsCount(); #endif
|
||||
LevelChunkSection[] chunkSections = new LevelChunkSection[sectionYIndex];
|
||||
|
||||
boolean isLightOn = chunkData.getBoolean("isLightOn");
|
||||
boolean hasSkyLight = level.dimensionType().hasSkyLight();
|
||||
@@ -288,7 +288,7 @@ public class ChunkLoader
|
||||
#endif
|
||||
|
||||
blockStateContainer = tagSection.contains("block_states", 10)
|
||||
? BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagSection.getCompound("block_states")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string))
|
||||
? BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagSection.getCompound("block_states")).promotePartial(string -> logBlockDeserializationWarning(chunkPos, sectionYPos, string))
|
||||
#if MC_VER < MC_1_20_6
|
||||
.getOrThrow(false, LOGGER::error)
|
||||
#else
|
||||
@@ -303,7 +303,7 @@ public class ChunkLoader
|
||||
#else
|
||||
|
||||
biomeContainer = tagSection.contains("biomes", 10)
|
||||
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, i, (String) string))
|
||||
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logBiomeDeserializationWarning(chunkPos, sectionYIndex, (String) string))
|
||||
#if MC_VER < MC_1_20_6
|
||||
.getOrThrow(false, LOGGER::error)
|
||||
#else
|
||||
@@ -495,9 +495,13 @@ public class ChunkLoader
|
||||
}
|
||||
}
|
||||
|
||||
private static void logErrors(ChunkPos chunkPos, int i, String string)
|
||||
private static void logBlockDeserializationWarning(ChunkPos chunkPos, int sectionYIndex, String message)
|
||||
{
|
||||
LOGGER.error("Distant Horizons: Recoverable errors when loading section [" + chunkPos.x + ", " + i + ", " + chunkPos.z + "]: " + string);
|
||||
LOGGER.warn("Unable to deserialize blocks for chunk section [" + chunkPos.x + ", " + sectionYIndex + ", " + chunkPos.z + "], error: ["+message+"]. This can probably be ignored, although if your world looks wrong, optimizing it via the single player menu then deleting your DH database(s) should fix the problem.");
|
||||
}
|
||||
private static void logBiomeDeserializationWarning(ChunkPos chunkPos, int sectionYIndex, String message)
|
||||
{
|
||||
LOGGER.warn("Unable to deserialize biomes for chunk section [" + chunkPos.x + ", " + sectionYIndex + ", " + chunkPos.z + "], error: ["+message+"]. This can probably be ignored, although if your world looks wrong, optimizing it via the single player menu then deleting your DH database(s) should fix the problem.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
+6
-1
@@ -61,7 +61,12 @@ public final class StepBiomes
|
||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||
{
|
||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||
if (!chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||
if (chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||
{
|
||||
// this chunk has already generated this step
|
||||
continue;
|
||||
}
|
||||
else if (chunk instanceof ProtoChunk)
|
||||
{
|
||||
#if MC_VER < MC_1_21
|
||||
((ProtoChunk) chunk).setStatus(STATUS);
|
||||
|
||||
+6
-2
@@ -59,8 +59,12 @@ public final class StepFeatures
|
||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||
{
|
||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||
if (!chunkWrapper.getStatus().isOrAfter(STATUS)
|
||||
&& chunk instanceof ProtoChunk)
|
||||
if (chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||
{
|
||||
// this chunk has already generated this step
|
||||
continue;
|
||||
}
|
||||
else if (chunk instanceof ProtoChunk)
|
||||
{
|
||||
#if MC_VER < MC_1_21
|
||||
((ProtoChunk) chunk).setStatus(STATUS);
|
||||
|
||||
+6
-1
@@ -59,7 +59,12 @@ public final class StepStructureReference
|
||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||
{
|
||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||
if (!chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||
if (chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||
{
|
||||
// this chunk has already generated this step
|
||||
continue;
|
||||
}
|
||||
else if (chunk instanceof ProtoChunk)
|
||||
{
|
||||
#if MC_VER < MC_1_21
|
||||
((ProtoChunk) chunk).setStatus(STATUS);
|
||||
|
||||
+9
-4
@@ -76,7 +76,12 @@ public final class StepStructureStart
|
||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||
{
|
||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||
if (!chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||
if (chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||
{
|
||||
// this chunk has already generated this step
|
||||
continue;
|
||||
}
|
||||
else if (chunk instanceof ProtoChunk)
|
||||
{
|
||||
#if MC_VER < MC_1_21
|
||||
((ProtoChunk) chunk).setStatus(STATUS);
|
||||
@@ -88,12 +93,12 @@ public final class StepStructureStart
|
||||
}
|
||||
|
||||
#if MC_VER < MC_1_19_2
|
||||
if (environment.params.worldGenSettings.generateFeatures())
|
||||
if (this.environment.params.worldGenSettings.generateFeatures())
|
||||
{
|
||||
#elif MC_VER < MC_1_19_4
|
||||
if (environment.params.worldGenSettings.generateStructures()) {
|
||||
if (this.environment.params.worldGenSettings.generateStructures()) {
|
||||
#else
|
||||
if (environment.params.worldOptions.generateStructures())
|
||||
if (this.environment.params.worldOptions.generateStructures())
|
||||
{
|
||||
#endif
|
||||
for (ChunkAccess chunk : chunksToDo)
|
||||
|
||||
+6
-1
@@ -58,7 +58,12 @@ public final class StepSurface
|
||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||
{
|
||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||
if (!chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||
if (chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||
{
|
||||
// this chunk has already generated this step
|
||||
continue;
|
||||
}
|
||||
else if (chunk instanceof ProtoChunk)
|
||||
{
|
||||
#if MC_VER < MC_1_21
|
||||
((ProtoChunk) chunk).setStatus(STATUS);
|
||||
|
||||
Reference in New Issue
Block a user