Compare commits

...

10 Commits

Author SHA1 Message Date
James Seibel 0b691ebcd5 remove dev from version number 2026-04-18 21:43:46 -05:00
James Seibel 3c35c52803 make mod loader name order consistent 2026-04-18 21:43:13 -05:00
James Seibel 0ed4964ee5 Fix MC 1.18 and older compiling 2026-04-18 20:12:43 -05:00
James Seibel b7cf7b61c8 Fix underwater grids and air handling
Some constructor methods weren't static so it was possible to pass in incorrect info, this has been fixed.
2026-04-18 20:01:12 -05:00
James Seibel 54b0ccfce6 add mod loaders to the merged jars 2026-04-18 15:48:44 -05:00
James Seibel 050d00b628 up MC 26 dev version to 26.1.2
Doesn't change compiling any, just makes it so dev testing is done on MC 26.1.2
2026-04-18 15:48:32 -05:00
James Seibel 2733201ac3 set the API jar in the gradle.properties
done for consistency
2026-04-18 15:47:54 -05:00
James Seibel 26bf03205c build all scripts don't double-merge jars
jar merging handled automatically now
2026-04-18 11:25:22 -05:00
James Seibel 628d57d216 remove google-collect 2026-04-18 11:09:23 -05:00
James Seibel 58ed8259f2 up version number 3.0.0 -> 3.0.1 2026-04-18 10:37:03 -05:00
9 changed files with 459 additions and 438 deletions
+20
View File
@@ -5,4 +5,24 @@ plugins {
forgix { forgix {
autoRun = true autoRun = true
// add the mod loaders to the end of the jar
// put together in the format: "a", "a-b", "a-b-c"
String modLoaders = "";
((String) gradle.builds_for)
.split(",")
.each
{ loader ->
def loaderName = loader.trim()
if (modLoaders != "")
{
modLoaders += "-";
}
modLoaders += loaderName;
}
// merged jars are named in the format:
// "DistantHorizons-3.0.1-b-dev-26.1-fabric-neoforge.jar"
archiveClassifier = modLoaders
} }
-4
View File
@@ -20,10 +20,6 @@ for d in versionProperties/*; do
sh gradlew build -PmcVer=$version sh gradlew build -PmcVer=$version
if [ $? != 0 ]; then continue; fi if [ $? != 0 ]; then continue; fi
echo "==================== Merging $version ===================="
sh gradlew mergeJars -PmcVer=$version
if [ $? != 0 ]; then continue; fi
echo "==================== Moving jar ====================" echo "==================== Moving jar ===================="
mv build/forgix/*.jar buildAllJars/ mv build/forgix/*.jar buildAllJars/
done done
-3
View File
@@ -20,9 +20,6 @@ for %%f in (versionProperties\*) do (
echo ==================== Building !version! ==================== echo ==================== Building !version! ====================
call .\gradlew.bat build -PmcVer="!version!" call .\gradlew.bat build -PmcVer="!version!"
echo ==================== Merging !version! ====================
call .\gradlew.bat mergeJars -PmcVer="!version!"
echo ==================== Moving jar ==================== echo ==================== Moving jar ====================
move build\forgix\*.jar buildAllJars\ move build\forgix\*.jar buildAllJars\
) )
@@ -140,28 +140,8 @@ public class BlockStateWrapper implements IBlockStateWrapper
//==============// //==============//
//region //region
public static BlockStateWrapper fromBlockState(BlockState blockState, ILevelWrapper levelWrapper) /**
{ * Can be faster than {@link BlockStateWrapper#fromBlockState(BlockState, ILevelWrapper)}
if (blockState == null || blockState.isAir())
{
return AIR;
}
if (WRAPPER_BY_BLOCK_STATE.containsKey(blockState))
{
return WRAPPER_BY_BLOCK_STATE.get(blockState);
}
else
{
BlockStateWrapper newWrapper = createNewWrapper(blockState, levelWrapper);
WRAPPER_BY_BLOCK_STATE.put(blockState, newWrapper);
return newWrapper;
}
}
/**
* Can be faster than {@link BlockStateWrapper#fromBlockState(BlockState, ILevelWrapper)}
* in cases where the same block state is expected to be referenced multiple times. * in cases where the same block state is expected to be referenced multiple times.
*/ */
public static BlockStateWrapper fromBlockState(BlockState blockState, ILevelWrapper levelWrapper, IBlockStateWrapper guess) public static BlockStateWrapper fromBlockState(BlockState blockState, ILevelWrapper levelWrapper, IBlockStateWrapper guess)
@@ -179,9 +159,14 @@ public class BlockStateWrapper implements IBlockStateWrapper
return fromBlockState(blockState, levelWrapper); return fromBlockState(blockState, levelWrapper);
} }
} }
public static BlockStateWrapper fromBlockState(@Nullable BlockState blockState, ILevelWrapper levelWrapper)
private static BlockStateWrapper createNewWrapper(@Nullable BlockState blockState, ILevelWrapper levelWrapper)
{ {
// air is a special case
if (isAir(blockState))
{
return AIR;
}
// create a wrapper specifically for the API event to use // create a wrapper specifically for the API event to use
BlockStateWrapper apiWrapper = new BlockStateWrapper(blockState, levelWrapper, null); BlockStateWrapper apiWrapper = new BlockStateWrapper(blockState, levelWrapper, null);
DhApiBlockStateWrapperCreatedEvent.EventParam eventParam = new DhApiBlockStateWrapperCreatedEvent.EventParam(apiWrapper); DhApiBlockStateWrapperCreatedEvent.EventParam eventParam = new DhApiBlockStateWrapperCreatedEvent.EventParam(apiWrapper);
@@ -197,212 +182,408 @@ public class BlockStateWrapper implements IBlockStateWrapper
BlockStateWrapper returnWrapper = new BlockStateWrapper(blockState, levelWrapper, eventParam); BlockStateWrapper returnWrapper = new BlockStateWrapper(blockState, levelWrapper, eventParam);
return returnWrapper; return returnWrapper;
} }
private BlockStateWrapper(@Nullable BlockState blockState, ILevelWrapper levelWrapper, @Nullable DhApiBlockStateWrapperCreatedEvent.EventParam overrideEventParam) private BlockStateWrapper(
@Nullable BlockState blockState, ILevelWrapper levelWrapper,
@Nullable DhApiBlockStateWrapperCreatedEvent.EventParam overrideEventParam)
{ {
this.blockState = blockState; this.blockState = blockState;
this.serialString = this.serialize(levelWrapper); this.serialString = serialize(blockState, levelWrapper);
this.hashCode = Objects.hash(this.serialString); this.hashCode = Objects.hash(this.serialString);
// allow overriding if present
if (overrideEventParam != null
&& overrideEventParam.getBlockMaterial() != null)
{
this.blockMaterialId = overrideEventParam.getBlockMaterial().index;
}
else
{
// no API override, use the base logic
this.blockMaterialId = this.calculateEDhApiBlockMaterialId().index;
}
// allow overriding if present
if (overrideEventParam != null
&& overrideEventParam.getOpacity() != null)
{
this.opacity = overrideEventParam.getOpacity();
}
else
{
this.opacity = this.calculateOpacity();
}
// allow overriding if present
if (overrideEventParam != null
&& overrideEventParam.getAllowApiColorOverride() != null)
{
this.allowApiColorOverride = overrideEventParam.getAllowApiColorOverride();
}
else
{
this.allowApiColorOverride = false;
}
String lowerCaseSerial = this.serialString.toLowerCase(); String lowerCaseSerial = this.serialString.toLowerCase();
// beacon base blocks // is liquid //
#if MC_VER <= MC_1_18_2
// Used to handle older MC versions that don't have an simple way of getting the block's tags
List<String> oldBeaconBaseBlockNameList = Arrays.asList(
"iron_block",
"gold_block",
"diamond_block",
"emerald_block",
"netherite_block"
);
// Older MC versions are harder to get block tags, so just use a static list to determine beacon blocks
boolean isBeaconBaseBlock = false;
for (int i = 0; i < oldBeaconBaseBlockNameList.size(); i++)
{ {
String baseBlockName = oldBeaconBaseBlockNameList.get(i); if (this.isAir()
if (lowerCaseSerial.contains(baseBlockName)) || this.blockState == null) // == null isn't necessary since its handled in isAir() but is here to prevent intellij from complaining
{ {
isBeaconBaseBlock = true; this.isLiquid = false;
break;
}
}
this.isBeaconBaseBlock = isBeaconBaseBlock;
#else
if (blockState != null)
{
// check if this block has any tags
Stream<TagKey<Block>> tags;
#if MC_VER <= MC_1_21_11
tags = blockState.getTags();
#else
tags = blockState.tags();
#endif
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");
// beacon tint color
Color beaconTintColor = null;
if (this.blockState != null
// beacon blocks also show up here, but since they block the beacon beam we don't want their color
&& !this.isBeaconBlock)
{
Block block = this.blockState.getBlock();
if (block instanceof BeaconBeamBlock)
{
int colorInt;
#if MC_VER <= MC_1_19_4
colorInt = ((BeaconBeamBlock) block).getColor().getMaterialColor().col;
#else
colorInt = ((BeaconBeamBlock) block).getColor().getMapColor().col;
#endif
beaconTintColor = ColorUtil.toColorObjRGB(colorInt);
}
}
this.beaconTintColor = beaconTintColor;
// allow/deny beacon beam passage
boolean allowsBeaconBeamPassage;
if (this.blockState != null)
{
// get block properties (defaults to the values used by air)
boolean canOcclude = this.getCanOcclude();
boolean propagatesSkyLightDown = this.getPropagatesSkyLightDown();
if (lowerCaseSerial.contains("minecraft:bedrock"))
{
// bedrock is a special case fully opaque block that does allow beacons through
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)
{
// stairs, cake, fences, etc.
allowsBeaconBeamPassage = true;
} }
else else
{ {
// non-opaque blocks (glass, mob spawners, etc.)
// all allow beacons through
allowsBeaconBeamPassage = (this.opacity != LodUtil.BLOCK_FULLY_OPAQUE);
}
}
else
{
// air allows beacons through
allowsBeaconBeamPassage = true;
}
this.allowsBeaconBeamPassage = allowsBeaconBeamPassage;
// map color
if (this.blockState != null)
{
int mcColor = 0;
#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);
}
// is solid
if (this.isAir()
|| this.blockState == null) // "== null" isn't necessary since its handled in isAir() but is here to prevent intellij from complaining
{
this.isSolid = false;
}
else
{
#if MC_VER < MC_1_20_1
this.isSolid = this.blockState.getMaterial().isSolid();
#else
this.isSolid = !this.blockState.getCollisionShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO).isEmpty();
#endif
}
// is liquid
if (this.isAir()
|| this.blockState == null) // == null isn't necessary since its handled in isAir() but is here to prevent intellij from complaining
{
this.isLiquid = false;
}
else
{
#if MC_VER < MC_1_20_1 #if MC_VER < MC_1_20_1
this.isLiquid = this.blockState.getMaterial().isLiquid() || !this.blockState.getFluidState().isEmpty(); this.isLiquid = this.blockState.getMaterial().isLiquid() || !this.blockState.getFluidState().isEmpty();
#else #else
this.isLiquid = !this.blockState.getFluidState().isEmpty(); this.isLiquid = !this.blockState.getFluidState().isEmpty();
#endif #endif
}
} }
// API overriding //
{
if (overrideEventParam != null
&& overrideEventParam.getBlockMaterial() != null)
{
this.blockMaterialId = overrideEventParam.getBlockMaterial().index;
}
else
{
// no API override, use the base logic
this.blockMaterialId = calculateEDhApiBlockMaterialId(this.blockState, lowerCaseSerial, this.isLiquid).index;
}
// allow overriding if present
if (overrideEventParam != null
&& overrideEventParam.getOpacity() != null)
{
this.opacity = overrideEventParam.getOpacity();
}
else
{
this.opacity = calculateOpacity(this.blockState, isAir(this.blockState), this.isLiquid);
}
// allow overriding if present
if (overrideEventParam != null
&& overrideEventParam.getAllowApiColorOverride() != null)
{
this.allowApiColorOverride = overrideEventParam.getAllowApiColorOverride();
}
else
{
this.allowApiColorOverride = false;
}
}
// beacon handling //
{
// beacon base blocks
#if MC_VER <= MC_1_18_2
// Used to handle older MC versions that don't have an simple way of getting the block's tags
List<String> oldBeaconBaseBlockNameList = Arrays.asList(
"iron_block",
"gold_block",
"diamond_block",
"emerald_block",
"netherite_block"
);
// Older MC versions are harder to get block tags, so just use a static list to determine beacon blocks
boolean isBeaconBaseBlock = false;
for (int i = 0; i < oldBeaconBaseBlockNameList.size(); i++)
{
String baseBlockName = oldBeaconBaseBlockNameList.get(i);
if (lowerCaseSerial.contains(baseBlockName))
{
isBeaconBaseBlock = true;
break;
}
}
this.isBeaconBaseBlock = isBeaconBaseBlock;
#else
if (blockState != null)
{
// check if this block has any tags
Stream<TagKey<Block>> tags;
#if MC_VER <= MC_1_21_11
tags = blockState.getTags();
#else
tags = blockState.tags();
#endif
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");
// beacon tint color
Color beaconTintColor = null;
if (this.blockState != null
// beacon blocks also show up here, but since they block the beacon beam we don't want their color
&& !this.isBeaconBlock)
{
Block block = this.blockState.getBlock();
if (block instanceof BeaconBeamBlock)
{
int colorInt;
#if MC_VER <= MC_1_19_4
colorInt = ((BeaconBeamBlock) block).getColor().getMaterialColor().col;
#else
colorInt = ((BeaconBeamBlock) block).getColor().getMapColor().col;
#endif
beaconTintColor = ColorUtil.toColorObjRGB(colorInt);
}
}
this.beaconTintColor = beaconTintColor;
// allow/deny beacon beam passage
boolean allowsBeaconBeamPassage;
if (this.blockState != null)
{
// get block properties (defaults to the values used by air)
boolean canOcclude = getCanOcclude(this.blockState);
boolean propagatesSkyLightDown = getPropagatesSkyLightDown(this.blockState);
if (lowerCaseSerial.contains("minecraft:bedrock"))
{
// bedrock is a special case fully opaque block that does allow beacons through
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)
{
// stairs, cake, fences, etc.
allowsBeaconBeamPassage = true;
}
else
{
// non-opaque blocks (glass, mob spawners, etc.)
// all allow beacons through
allowsBeaconBeamPassage = (this.opacity != LodUtil.BLOCK_FULLY_OPAQUE);
}
}
else
{
// air allows beacons through
allowsBeaconBeamPassage = true;
}
this.allowsBeaconBeamPassage = allowsBeaconBeamPassage;
}
// map color //
{
if (this.blockState != null)
{
int mcColor = 0;
#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);
}
}
// is solid //
{
if (this.isAir()
|| this.blockState == null) // "== null" isn't necessary since its handled in isAir() but is here to prevent IntelliJ from complaining
{
this.isSolid = false;
}
else
{
#if MC_VER < MC_1_20_1
this.isSolid = this.blockState.getMaterial().isSolid();
#else
this.isSolid = !this.blockState.getCollisionShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO).isEmpty();
#endif
}
}
} }
// static constructor helpers //
//region
private static EDhApiBlockMaterial calculateEDhApiBlockMaterialId(
@Nullable BlockState blockState,
String lowercaseSerialString,
boolean isLiquid
)
{
if (blockState == null)
{
return EDhApiBlockMaterial.AIR;
}
if (blockState.is(BlockTags.LEAVES)
|| lowercaseSerialString.contains("bamboo")
|| lowercaseSerialString.contains("cactus")
|| lowercaseSerialString.contains("chorus_flower")
|| lowercaseSerialString.contains("mushroom")
)
{
return EDhApiBlockMaterial.LEAVES;
}
else if (blockState.is(Blocks.LAVA))
{
return EDhApiBlockMaterial.LAVA;
}
else if (isLiquid
|| blockState.is(Blocks.WATER))
{
return EDhApiBlockMaterial.WATER;
}
else if (blockState.getSoundType() == SoundType.WOOD
|| lowercaseSerialString.contains("root")
#if MC_VER >= MC_1_19_4
|| blockState.getSoundType() == SoundType.CHERRY_WOOD
#endif
)
{
return EDhApiBlockMaterial.WOOD;
}
else if (blockState.getSoundType() == SoundType.METAL
#if MC_VER >= MC_1_19_2
|| blockState.getSoundType() == SoundType.COPPER
#endif
#if MC_VER >= MC_1_20_4
|| blockState.getSoundType() == SoundType.COPPER_BULB
|| blockState.getSoundType() == SoundType.COPPER_GRATE
#endif
)
{
return EDhApiBlockMaterial.METAL;
}
else if (
lowercaseSerialString.contains("grass_block")
|| lowercaseSerialString.contains("grass_slab")
)
{
return EDhApiBlockMaterial.GRASS;
}
else if (
lowercaseSerialString.contains("dirt")
|| lowercaseSerialString.contains("gravel")
|| lowercaseSerialString.contains("mud")
|| lowercaseSerialString.contains("podzol")
|| lowercaseSerialString.contains("mycelium")
)
{
return EDhApiBlockMaterial.DIRT;
}
#if MC_VER >= MC_1_17_1
else if (blockState.getSoundType() == SoundType.DEEPSLATE
|| blockState.getSoundType() == SoundType.DEEPSLATE_BRICKS
|| blockState.getSoundType() == SoundType.DEEPSLATE_TILES
|| blockState.getSoundType() == SoundType.POLISHED_DEEPSLATE
|| lowercaseSerialString.contains("deepslate") )
{
return EDhApiBlockMaterial.DEEPSLATE;
}
#endif
else if (lowercaseSerialString.contains("snow"))
{
return EDhApiBlockMaterial.SNOW;
}
else if (lowercaseSerialString.contains("sand"))
{
return EDhApiBlockMaterial.SAND;
}
else if (lowercaseSerialString.contains("terracotta"))
{
return EDhApiBlockMaterial.TERRACOTTA;
}
else if (blockState.is(BlockTags.BASE_STONE_NETHER))
{
return EDhApiBlockMaterial.NETHER_STONE;
}
else if (lowercaseSerialString.contains("stone")
|| lowercaseSerialString.contains("ore"))
{
return EDhApiBlockMaterial.STONE;
}
else if (blockState.getLightEmission() > 0)
{
return EDhApiBlockMaterial.ILLUMINATED;
}
else
{
return EDhApiBlockMaterial.UNKNOWN;
}
}
private static int calculateOpacity(
@Nullable BlockState blockState,
boolean isAir, boolean isLiquid
)
{
// get block properties (defaults to the values used by air)
boolean canOcclude = getCanOcclude(blockState);
boolean propagatesSkyLightDown = getPropagatesSkyLightDown(blockState);
// this method isn't perfect, but works well enough for our use case
int opacity;
if (isAir)
{
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT;
}
else if (isLiquid && !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 = LodUtil.BLOCK_FULLY_TRANSPARENT + 1;
}
else if (propagatesSkyLightDown && !canOcclude)
{
// probably glass or some other fully transparent block
// !canOcclude is required to ignore stairs and slabs since
// propagateSkyLightDown is true for them, but they're solid and don't actually let light through
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT;
}
else
{
// default for all other blocks
opacity = LodUtil.BLOCK_FULLY_OPAQUE;
}
return opacity;
}
private static boolean getCanOcclude(@Nullable BlockState blockState)
{
// defaults to the value used by air
boolean canOcclude = false;
if (blockState != null)
{
canOcclude = blockState.canOcclude();
}
return canOcclude;
}
private static boolean getPropagatesSkyLightDown(@Nullable BlockState blockState)
{
// defaults to the value used by air
boolean propagatesSkyLightDown = true;
if (blockState != null)
{
#if MC_VER < MC_1_21_3
propagatesSkyLightDown = blockState.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
#else
propagatesSkyLightDown = blockState.propagatesSkylightDown();
#endif
}
return propagatesSkyLightDown;
}
//endregion
//endregion //endregion
@@ -480,15 +661,6 @@ public class BlockStateWrapper implements IBlockStateWrapper
return waterBlock; return waterBlock;
} }
public static void clearCachedIgnoreBlocks()
{
rendererIgnoredBlocks = null;
rendererIgnoredCaveBlocks = null;
waterSurfaceReplacementBlocks = null;
waterSubsurfaceReplacementBlocks = null;
waterBlock = null;
}
//endregion //endregion
@@ -545,7 +717,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
List<BlockState> blockStatesToIgnore = defaultBlockStateToIgnore.blockState.getBlock().getStateDefinition().getPossibleStates(); List<BlockState> blockStatesToIgnore = defaultBlockStateToIgnore.blockState.getBlock().getStateDefinition().getPossibleStates();
for (BlockState blockState : blockStatesToIgnore) for (BlockState blockState : blockStatesToIgnore)
{ {
BlockStateWrapper newBlockToIgnore = BlockStateWrapper.fromBlockState(blockState, levelWrapper); BlockStateWrapper newBlockToIgnore = fromBlockState(blockState, levelWrapper);
blockStateWrappers.add(newBlockToIgnore); blockStateWrappers.add(newBlockToIgnore);
} }
} }
@@ -568,6 +740,15 @@ public class BlockStateWrapper implements IBlockStateWrapper
return blockStateWrappers; return blockStateWrappers;
} }
public static void clearCachedIgnoreBlocks()
{
rendererIgnoredBlocks = null;
rendererIgnoredCaveBlocks = null;
waterSurfaceReplacementBlocks = null;
waterSubsurfaceReplacementBlocks = null;
waterBlock = null;
}
//endregion //endregion
@@ -579,73 +760,6 @@ public class BlockStateWrapper implements IBlockStateWrapper
@Override @Override
public int getOpacity() { return this.opacity; } public int getOpacity() { return this.opacity; }
private int calculateOpacity()
{
// get block properties (defaults to the values used by air)
boolean canOcclude = this.getCanOcclude();
boolean propagatesSkyLightDown = this.getPropagatesSkyLightDown();
// this method isn't perfect, but works well enough for our use case
int opacity;
if (this.isAir())
{
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT;
}
else if (this.isLiquid() && !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 = LodUtil.BLOCK_FULLY_TRANSPARENT + 1;
}
else if (propagatesSkyLightDown && !canOcclude)
{
// probably glass or some other fully transparent block
// !canOcclude is required to ignore stairs and slabs since
// propagateSkyLightDown is true for them, but they're solid and don't actually let light through
opacity = LodUtil.BLOCK_FULLY_TRANSPARENT;
}
else
{
// default for all other blocks
opacity = LodUtil.BLOCK_FULLY_OPAQUE;
}
return opacity;
}
private boolean getCanOcclude()
{
// defaults to the value used by air
boolean canOcclude = false;
if (this.blockState != null)
{
canOcclude = this.blockState.canOcclude();
}
return canOcclude;
}
private boolean getPropagatesSkyLightDown()
{
// defaults to the value used by air
boolean propagatesSkyLightDown = true;
if (this.blockState != null)
{
#if MC_VER < MC_1_21_3
propagatesSkyLightDown = this.blockState.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
#else
propagatesSkyLightDown = this.blockState.propagatesSkylightDown();
#endif
}
return propagatesSkyLightDown;
}
@Override @Override
public int getLightEmission() { return (this.blockState != null) ? this.blockState.getLightEmission() : 0; } public int getLightEmission() { return (this.blockState != null) ? this.blockState.getLightEmission() : 0; }
@@ -653,34 +767,12 @@ public class BlockStateWrapper implements IBlockStateWrapper
@Override @Override
public String getSerialString() { return this.serialString; } public String getSerialString() { return this.serialString; }
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null || this.getClass() != obj.getClass())
{
return false;
}
BlockStateWrapper that = (BlockStateWrapper) obj;
// the serialized value is used so we can test the contents instead of the references
return Objects.equals(this.getSerialString(), that.getSerialString());
}
@Override
public int hashCode() { return this.hashCode; }
@Override @Override
public Object getWrappedMcObject() { return this.blockState; } public Object getWrappedMcObject() { return this.blockState; }
@Override @Override
public boolean isAir() { return this.isAir(this.blockState); } public boolean isAir() { return isAir(this.blockState); }
public boolean isAir(BlockState blockState) { return blockState == null || blockState.isAir(); } public static boolean isAir(BlockState blockState) { return blockState == null || blockState.isAir(); }
@Override @Override
public boolean isSolid() { return this.isSolid; } public boolean isSolid() { return this.isSolid; }
@@ -705,9 +797,6 @@ public class BlockStateWrapper implements IBlockStateWrapper
@Override @Override
public byte getMaterialId() { return this.blockMaterialId; } public byte getMaterialId() { return this.blockMaterialId; }
@Override
public String toString() { return this.getSerialString(); }
//endregion //endregion
@@ -717,9 +806,9 @@ public class BlockStateWrapper implements IBlockStateWrapper
//=======================// //=======================//
//region //region
private String serialize(ILevelWrapper levelWrapper) private static String serialize(BlockState blockState, ILevelWrapper levelWrapper)
{ {
if (this.blockState == null) if (blockState == null)
{ {
return AIR_STRING; return AIR_STRING;
} }
@@ -740,27 +829,26 @@ public class BlockStateWrapper implements IBlockStateWrapper
#endif #endif
#if MC_VER <= MC_1_17_1 #if MC_VER <= MC_1_17_1
resourceLocation = Registry.BLOCK.getKey(this.blockState.getBlock()); resourceLocation = Registry.BLOCK.getKey(blockState.getBlock());
#elif MC_VER <= MC_1_19_2 #elif MC_VER <= MC_1_19_2
resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(this.blockState.getBlock()); resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(blockState.getBlock());
#elif MC_VER <= MC_1_21_1 #elif MC_VER <= MC_1_21_1
resourceLocation = registryAccess.registryOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock()); resourceLocation = registryAccess.registryOrThrow(Registries.BLOCK).getKey(blockState.getBlock());
#else #else
resourceLocation = registryAccess.lookupOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock()); resourceLocation = registryAccess.lookupOrThrow(Registries.BLOCK).getKey(blockState.getBlock());
#endif #endif
if (resourceLocation == null) if (resourceLocation == null)
{ {
LOGGER.warn("No ResourceLocation found, unable to serialize: " + this.blockState); LOGGER.warn("No ResourceLocation found, unable to serialize: " + blockState);
return AIR_STRING; return AIR_STRING;
} }
this.serialString = resourceLocation.getNamespace() + RESOURCE_LOCATION_SEPARATOR + resourceLocation.getPath() String serialString = resourceLocation.getNamespace() + RESOURCE_LOCATION_SEPARATOR + resourceLocation.getPath()
+ STATE_STRING_SEPARATOR + serializeBlockStateProperties(this.blockState); + STATE_STRING_SEPARATOR + serializeBlockStateProperties(blockState);
return serialString;
return this.serialString;
} }
@@ -899,7 +987,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
foundState = block.defaultBlockState(); foundState = block.defaultBlockState();
} }
foundWrapper = createNewWrapper(foundState, levelWrapper); foundWrapper = fromBlockState(foundState, levelWrapper);
return foundWrapper; return foundWrapper;
} }
catch (Exception e) catch (Exception e)
@@ -949,118 +1037,37 @@ public class BlockStateWrapper implements IBlockStateWrapper
//==============// //================//
// Iris methods // // base overrides //
//==============// //================//
//region //region
private EDhApiBlockMaterial calculateEDhApiBlockMaterialId() @Override
public boolean equals(Object obj)
{ {
if (this.blockState == null) if (this == obj)
{ {
return EDhApiBlockMaterial.AIR; return true;
} }
if (obj == null || this.getClass() != obj.getClass())
{
return false;
}
String serialString = this.getSerialString().toLowerCase(); BlockStateWrapper that = (BlockStateWrapper) obj;
// the serialized value is used so we can test the contents instead of the references
if (this.blockState.is(BlockTags.LEAVES) return Objects.equals(this.getSerialString(), that.getSerialString());
|| serialString.contains("bamboo")
|| serialString.contains("cactus")
|| serialString.contains("chorus_flower")
|| serialString.contains("mushroom")
)
{
return EDhApiBlockMaterial.LEAVES;
}
else if (this.blockState.is(Blocks.LAVA))
{
return EDhApiBlockMaterial.LAVA;
}
else if (this.isLiquid() || this.blockState.is(Blocks.WATER))
{
return EDhApiBlockMaterial.WATER;
}
else if (this.blockState.getSoundType() == SoundType.WOOD
|| serialString.contains("root")
#if MC_VER >= MC_1_19_4
|| this.blockState.getSoundType() == SoundType.CHERRY_WOOD
#endif
)
{
return EDhApiBlockMaterial.WOOD;
}
else if (this.blockState.getSoundType() == SoundType.METAL
#if MC_VER >= MC_1_19_2
|| this.blockState.getSoundType() == SoundType.COPPER
#endif
#if MC_VER >= MC_1_20_4
|| this.blockState.getSoundType() == SoundType.COPPER_BULB
|| this.blockState.getSoundType() == SoundType.COPPER_GRATE
#endif
)
{
return EDhApiBlockMaterial.METAL;
}
else if (
serialString.contains("grass_block")
|| serialString.contains("grass_slab")
)
{
return EDhApiBlockMaterial.GRASS;
}
else if (
serialString.contains("dirt")
|| serialString.contains("gravel")
|| serialString.contains("mud")
|| serialString.contains("podzol")
|| serialString.contains("mycelium")
)
{
return EDhApiBlockMaterial.DIRT;
}
#if MC_VER >= MC_1_17_1
else if (this.blockState.getSoundType() == SoundType.DEEPSLATE
|| this.blockState.getSoundType() == SoundType.DEEPSLATE_BRICKS
|| this.blockState.getSoundType() == SoundType.DEEPSLATE_TILES
|| this.blockState.getSoundType() == SoundType.POLISHED_DEEPSLATE
|| serialString.contains("deepslate") )
{
return EDhApiBlockMaterial.DEEPSLATE;
}
#endif
else if (this.serialString.contains("snow"))
{
return EDhApiBlockMaterial.SNOW;
}
else if (serialString.contains("sand"))
{
return EDhApiBlockMaterial.SAND;
}
else if (serialString.contains("terracotta"))
{
return EDhApiBlockMaterial.TERRACOTTA;
}
else if (this.blockState.is(BlockTags.BASE_STONE_NETHER))
{
return EDhApiBlockMaterial.NETHER_STONE;
}
else if (serialString.contains("stone")
|| serialString.contains("ore"))
{
return EDhApiBlockMaterial.STONE;
}
else if (this.blockState.getLightEmission() > 0)
{
return EDhApiBlockMaterial.ILLUMINATED;
}
else
{
return EDhApiBlockMaterial.UNKNOWN;
}
} }
@Override
public int hashCode() { return this.hashCode; }
@Override
public String toString() { return this.getSerialString(); }
//endregion //endregion
} }
+2 -1
View File
@@ -5,7 +5,8 @@ org.gradle.caching=true
# Mod Info # Mod Info
mod_name=DistantHorizons mod_name=DistantHorizons
mod_version=3.0.0-b api_name=DistantHorizonsApi
mod_version=3.0.1-b
api_version=6.0.0 api_version=6.0.0
maven_group=com.seibel.distanthorizons maven_group=com.seibel.distanthorizons
mod_readable_name=Distant Horizons mod_readable_name=Distant Horizons
+1 -1
View File
@@ -4,7 +4,7 @@ minecraft_version=1.21.3
parchment_version=1.21:2024.07.28 parchment_version=1.21:2024.07.28
compatible_minecraft_versions=["1.21.3"] compatible_minecraft_versions=["1.21.3"]
accessWidenerVersion=1_21_3 accessWidenerVersion=1_21_3
builds_for=neoforge,fabric builds_for=fabric,neoforge
# forge is broken due to gradle/build script issues # forge is broken due to gradle/build script issues
# Netty # Netty
+1 -1
View File
@@ -4,7 +4,7 @@ minecraft_version=1.21.4
parchment_version=1.21:2024.07.28 parchment_version=1.21:2024.07.28
compatible_minecraft_versions=["1.21.4"] compatible_minecraft_versions=["1.21.4"]
accessWidenerVersion=1_21_4 accessWidenerVersion=1_21_4
builds_for=neoforge,fabric builds_for=fabric,neoforge
# forge is broken due to gradle/build script issues # forge is broken due to gradle/build script issues
# Netty # Netty
+1 -1
View File
@@ -1,6 +1,6 @@
# 26.1.2 version # 26.1.2 version
java_version=25 java_version=25
minecraft_version=26.1 minecraft_version=26.1.2
parchment_version=1.21:2024.07.28 parchment_version=1.21:2024.07.28
# version range should be used instead of individual versions due to how NeoForge handles version loading # version range should be used instead of individual versions due to how NeoForge handles version loading
compatible_minecraft_versions=["26.1.0", "26.1.2"] compatible_minecraft_versions=["26.1.0", "26.1.2"]