From ad97f322b263daa4010b2fb3dff2ffeb6acf3264 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 30 Oct 2023 07:46:21 -0500 Subject: [PATCH] Fix aether block tinting without breaking vanilla oceans --- .../block/cache/ClientBlockStateCache.java | 74 +++++++++++++++++-- 1 file changed, 68 insertions(+), 6 deletions(-) diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/cache/ClientBlockStateCache.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/cache/ClientBlockStateCache.java index 4d714f78a..85919de37 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/cache/ClientBlockStateCache.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/cache/ClientBlockStateCache.java @@ -46,8 +46,8 @@ import java.util.Random; import net.minecraft.world.level.block.state.BlockState; import org.apache.logging.log4j.Logger; +import java.util.HashSet; import java.util.List; -import java.util.Random; /** * @version 2022-9-16 @@ -57,6 +57,9 @@ public class ClientBlockStateCache private static final Logger LOGGER = DhLoggerBuilder.getLogger(); + private static final HashSet BLOCK_STATES_THAT_NEED_LEVEL = new HashSet<>(); + private static final HashSet BROKEN_BLOCK_STATES = new HashSet<>(); + #if PRE_MC_1_19_2 public static final Random random = new Random(0); #else @@ -235,11 +238,70 @@ public class ClientBlockStateCache public int getAndResolveFaceColor(BiomeWrapper biome, DhBlockPos pos) { // FIXME: impl per-face colors - if (!needPostTinting) return baseColor; - int tintColor = Minecraft.getInstance().getBlockColors() - .getColor(state, new TintWithoutLevelOverrider(biome), McObjectConverter.Convert(pos), tintIndex); - if (tintColor == -1) return baseColor; - return ColorUtil.multiplyARGBwithRGB(baseColor, tintColor); + + // only get the tint if the block needs to be tinted + if (!this.needPostTinting) + { + return this.baseColor; + } + + // don't try tinting blocks that don't support our method of tint getting + if (BROKEN_BLOCK_STATES.contains(this.state)) + { + return this.baseColor; + } + + + // attempt to get the tint + int tintColor = -1; + try + { + // try to use the fast tint getter logic first + if (!BLOCK_STATES_THAT_NEED_LEVEL.contains(this.state)) + { + try + { + tintColor = Minecraft.getInstance().getBlockColors() + .getColor(this.state, new TintWithoutLevelOverrider(biome), McObjectConverter.Convert(pos), this.tintIndex); + } + catch (UnsupportedOperationException e) + { + // this exception generally occurs if the tint requires other blocks besides itself + LOGGER.debug("Unable to use ["+TintWithoutLevelOverrider.class.getSimpleName()+"] to get the block tint for block: [" + this.state + "] and biome: [" + biome + "] at pos: " + pos + ". Error: [" + e.getMessage() + "]. Attempting to use backup method...", e); + BLOCK_STATES_THAT_NEED_LEVEL.add(this.state); + } + } + + // use the level logic only if requested + if (BLOCK_STATES_THAT_NEED_LEVEL.contains(this.state)) + { + // this logic can't be used all the time due to it breaking some blocks tinting + // specifically oceans don't render correctly + tintColor = Minecraft.getInstance().getBlockColors() + .getColor(this.state, new TintGetterOverrideFast(this.level), McObjectConverter.Convert(pos), this.tintIndex); + } + } + catch (Exception e) + { + // only display the error once per block/biome type to reduce log spam + if (!BROKEN_BLOCK_STATES.contains(this.state)) + { + LOGGER.warn("Failed to get block color for block: [" + this.state + "] and biome: [" + biome + "] at pos: " + pos + ". Error: ["+e.getMessage() + "]. Note: future errors for this block/biome will be ignored.", e); + BROKEN_BLOCK_STATES.add(this.state); + } + } + + + + if (tintColor != -1) + { + return ColorUtil.multiplyARGBwithRGB(this.baseColor, tintColor); + } + else + { + // unable to get the tinted color, use the base color instead + return this.baseColor; + } } }