diff --git a/src/main/java/me/pepperbell/continuity/api/client/QuadProcessor.java b/src/main/java/me/pepperbell/continuity/api/client/QuadProcessor.java index 06f3e4df..80b32922 100644 --- a/src/main/java/me/pepperbell/continuity/api/client/QuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/api/client/QuadProcessor.java @@ -15,7 +15,7 @@ import net.minecraft.world.BlockRenderView; public interface QuadProcessor { - ProcessingResult processQuad(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context); + ProcessingResult processQuad(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context); interface ProcessingContext extends ProcessingDataProvider { void addEmitterConsumer(Consumer consumer); diff --git a/src/main/java/me/pepperbell/continuity/client/model/CtmBakedModel.java b/src/main/java/me/pepperbell/continuity/client/model/CtmBakedModel.java index ba9d65f8..4cfe7859 100644 --- a/src/main/java/me/pepperbell/continuity/client/model/CtmBakedModel.java +++ b/src/main/java/me/pepperbell/continuity/client/model/CtmBakedModel.java @@ -14,6 +14,7 @@ import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.texture.Sprite; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; @@ -47,7 +48,24 @@ public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos return; } - quadTransform.prepare(blockView, state, pos, randomSupplier, ContinuityConfig.INSTANCE.useManualCulling.get(), getSliceFunc(state)); + // The correct way to get the appearance of the origin state from within a block model is to (1) call + // getAppearance on the result of blockView.getBlockState(pos) instead of the passed state and (2) pass the + // pos and world state of the adjacent block as the source pos and source state. + // (1) is not followed here because at this point in execution, within this call to + // CtmBakedModel#emitBlockQuads, the state parameter must already contain the world state. Even if this + // CtmBakedModel is wrapped, then the wrapper must pass the same state as it received because not doing so can + // cause crashes when the wrapped model is a vanilla multipart model or delegates to one. Thus, getting the + // world state again is inefficient and unnecessary. + // (2) is not possible here because the appearance state is necessary to get the slice and only the processors + // within the slice actually perform checks on adjacent blocks. Likewise, the processors themselves cannot + // retrieve the appearance state since the correct processors can only be chosen with the initially correct + // appearance state. + // Additionally, the side is chosen to always be the first constant of the enum (DOWN) for simplicity. Querying + // the appearance for all six sides would be more correct, but less efficient. This may be fixed in the future, + // especially if there is an actual use case for it. + BlockState appearanceState = state.getAppearance(blockView, pos, Direction.DOWN, state, pos); + + quadTransform.prepare(blockView, appearanceState, state, pos, randomSupplier, ContinuityConfig.INSTANCE.useManualCulling.get(), getSliceFunc(appearanceState)); context.pushTransform(quadTransform); super.emitBlockQuads(blockView, state, pos, randomSupplier, context); @@ -87,6 +105,7 @@ protected static class CtmQuadTransform implements RenderContext.QuadTransform { protected final CullingCache cullingCache = new CullingCache(); protected BlockRenderView blockView; + protected BlockState appearanceState; protected BlockState state; protected BlockPos pos; protected Supplier randomSupplier; @@ -116,7 +135,7 @@ protected Boolean transformOnce(MutableQuadView quad, int pass) { QuadProcessors.Slice slice = sliceFunc.apply(sprite); QuadProcessor[] processors = pass == 0 ? slice.processors() : slice.multipassProcessors(); for (QuadProcessor processor : processors) { - QuadProcessor.ProcessingResult result = processor.processQuad(quad, sprite, blockView, state, pos, randomSupplier, pass, processingContext); + QuadProcessor.ProcessingResult result = processor.processQuad(quad, sprite, blockView, appearanceState, state, pos, randomSupplier, pass, processingContext); if (result == QuadProcessor.ProcessingResult.NEXT_PROCESSOR) { continue; } @@ -137,8 +156,9 @@ public boolean isActive() { return active; } - public void prepare(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, boolean useManualCulling, Function sliceFunc) { + public void prepare(BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, boolean useManualCulling, Function sliceFunc) { this.blockView = blockView; + this.appearanceState = appearanceState; this.state = state; this.pos = pos; this.randomSupplier = randomSupplier; @@ -153,6 +173,7 @@ public void prepare(BlockRenderView blockView, BlockState state, BlockPos pos, S public void reset() { blockView = null; + appearanceState = null; state = null; pos = null; randomSupplier = null; diff --git a/src/main/java/me/pepperbell/continuity/client/processor/AbstractQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/AbstractQuadProcessor.java index 866175cf..74e4fbbc 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/AbstractQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/AbstractQuadProcessor.java @@ -20,12 +20,12 @@ public AbstractQuadProcessor(Sprite[] sprites, ProcessingPredicate processingPre } @Override - public ProcessingResult processQuad(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { - if (!processingPredicate.shouldProcessQuad(quad, sprite, blockView, state, pos, context)) { + public ProcessingResult processQuad(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { + if (!processingPredicate.shouldProcessQuad(quad, sprite, blockView, appearanceState, state, pos, context)) { return ProcessingResult.NEXT_PROCESSOR; } - return processQuadInner(quad, sprite, blockView, state, pos, randomSupplier, pass, context); + return processQuadInner(quad, sprite, blockView, appearanceState, state, pos, randomSupplier, pass, context); } - public abstract ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context); + public abstract ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context); } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/BaseProcessingPredicate.java b/src/main/java/me/pepperbell/continuity/client/processor/BaseProcessingPredicate.java index 6151bde6..8713d378 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/BaseProcessingPredicate.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/BaseProcessingPredicate.java @@ -38,7 +38,7 @@ public BaseProcessingPredicate(@Nullable EnumSet faces, @Nullable Pre } @Override - public boolean shouldProcessQuad(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, ProcessingDataProvider dataProvider) { + public boolean shouldProcessQuad(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, ProcessingDataProvider dataProvider) { if (heightPredicate != null) { if (!heightPredicate.test(pos.getY())) { return false; @@ -46,8 +46,8 @@ public boolean shouldProcessQuad(QuadView quad, Sprite sprite, BlockRenderView b } if (faces != null) { Direction face = quad.lightFace(); - if (state.contains(Properties.AXIS)) { - Direction.Axis axis = state.get(Properties.AXIS); + if (appearanceState.contains(Properties.AXIS)) { + Direction.Axis axis = appearanceState.get(Properties.AXIS); if (axis == Direction.Axis.X) { face = face.rotateClockwise(Direction.Axis.Z); } else if (axis == Direction.Axis.Z) { @@ -59,13 +59,13 @@ public boolean shouldProcessQuad(QuadView quad, Sprite sprite, BlockRenderView b } } if (biomePredicate != null) { - Biome biome = dataProvider.getData(ProcessingDataKeys.BIOME_CACHE_KEY).get(blockView, pos); + Biome biome = dataProvider.getData(ProcessingDataKeys.BIOME_CACHE).get(blockView, pos); if (biome == null || !biomePredicate.test(biome)) { return false; } } if (blockEntityNamePredicate != null) { - String blockEntityName = dataProvider.getData(ProcessingDataKeys.BLOCK_ENTITY_NAME_CACHE_KEY).get(blockView, pos); + String blockEntityName = dataProvider.getData(ProcessingDataKeys.BLOCK_ENTITY_NAME_CACHE).get(blockView, pos); if (blockEntityName == null || !blockEntityNamePredicate.test(blockEntityName)) { return false; } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/CompactCtmQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/CompactCtmQuadProcessor.java index a95988e0..3b37f8fb 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/CompactCtmQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/CompactCtmQuadProcessor.java @@ -69,11 +69,11 @@ public CompactCtmQuadProcessor(Sprite[] sprites, ProcessingPredicate processingP } @Override - public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { - int orientation = orientationMode.getOrientation(quad, state); + public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { + int orientation = orientationMode.getOrientation(quad, appearanceState); Direction[] directions = DirectionMaps.getMap(quad.lightFace())[orientation]; - BlockPos.Mutable mutablePos = context.getData(ProcessingDataKeys.MUTABLE_POS_KEY); - int connections = CtmSpriteProvider.getConnections(connectionPredicate, innerSeams, directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); + BlockPos.Mutable mutablePos = context.getData(ProcessingDataKeys.MUTABLE_POS); + int connections = CtmSpriteProvider.getConnections(directions, connectionPredicate, innerSeams, mutablePos, blockView, appearanceState, state, pos, quad.lightFace(), sprite); // @@ -157,7 +157,7 @@ public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, Bl return ProcessingResult.STOP; } - VertexContainer vertexContainer = context.getData(ProcessingDataKeys.VERTEX_CONTAINER_KEY); + VertexContainer vertexContainer = context.getData(ProcessingDataKeys.VERTEX_CONTAINER); vertexContainer.fillBaseVertices(quad); QuadEmitter extraQuadEmitter = context.getExtraQuadEmitter(); @@ -385,7 +385,7 @@ public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, Bl spriteIndexB = temp; } - VertexContainer vertexContainer = context.getData(ProcessingDataKeys.VERTEX_CONTAINER_KEY); + VertexContainer vertexContainer = context.getData(ProcessingDataKeys.VERTEX_CONTAINER); vertexContainer.fillBaseVertices(quad); QuadEmitter extraQuadEmitter = context.getExtraQuadEmitter(); diff --git a/src/main/java/me/pepperbell/continuity/client/processor/ConnectionPredicate.java b/src/main/java/me/pepperbell/continuity/client/processor/ConnectionPredicate.java index acf0cd56..9705ebbc 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/ConnectionPredicate.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/ConnectionPredicate.java @@ -7,17 +7,19 @@ import net.minecraft.world.BlockRenderView; public interface ConnectionPredicate { - boolean shouldConnect(BlockRenderView blockView, BlockState state, BlockPos pos, BlockState toState, Direction face, Sprite quadSprite); + boolean shouldConnect(BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, BlockState otherAppearanceState, BlockState otherState, BlockPos otherPos, Direction face, Sprite quadSprite); - default boolean shouldConnect(BlockRenderView blockView, BlockState state, BlockPos pos, BlockPos toPos, Direction face, Sprite quadSprite) { - return shouldConnect(blockView, state, pos, blockView.getBlockState(toPos), face, quadSprite); + default boolean shouldConnect(BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, BlockPos otherPos, Direction face, Sprite quadSprite) { + BlockState otherState = blockView.getBlockState(otherPos); + BlockState otherAppearanceState = otherState.getAppearance(blockView, otherPos, face, state, pos); + return shouldConnect(blockView, appearanceState, state, pos, otherAppearanceState, otherState, otherPos, face, quadSprite); } - default boolean shouldConnect(BlockRenderView blockView, BlockState state, BlockPos pos, BlockPos.Mutable toPos, Direction face, Sprite quadSprite, boolean innerSeams) { - if (shouldConnect(blockView, state, pos, toPos, face, quadSprite)) { + default boolean shouldConnect(BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, BlockPos.Mutable otherPos, Direction face, Sprite quadSprite, boolean innerSeams) { + if (shouldConnect(blockView, appearanceState, state, pos, otherPos, face, quadSprite)) { if (innerSeams) { - toPos.move(face); - return !shouldConnect(blockView, state, pos, toPos, face, quadSprite); + otherPos.move(face); + return !shouldConnect(blockView, appearanceState, state, pos, otherPos, face, quadSprite); } else { return true; } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/ProcessingDataKeys.java b/src/main/java/me/pepperbell/continuity/client/processor/ProcessingDataKeys.java index e2d7dbe8..985843c2 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/ProcessingDataKeys.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/ProcessingDataKeys.java @@ -11,12 +11,12 @@ import net.minecraft.util.math.BlockPos; public final class ProcessingDataKeys { - public static final ProcessingDataKey MUTABLE_POS_KEY = create("mutable_pos", BlockPos.Mutable::new); - public static final ProcessingDataKey BIOME_CACHE_KEY = create("biome_cache", BaseProcessingPredicate.BiomeCache::new, BaseProcessingPredicate.BiomeCache::reset); - public static final ProcessingDataKey BLOCK_ENTITY_NAME_CACHE_KEY = create("block_entity_name_cache", BaseProcessingPredicate.BlockEntityNameCache::new, BaseProcessingPredicate.BlockEntityNameCache::reset); - public static final ProcessingDataKey VERTEX_CONTAINER_KEY = create("vertex_container", CompactCtmQuadProcessor.VertexContainer::new); - public static final ProcessingDataKey STANDARD_OVERLAY_EMITTER_POOL_KEY = create("standard_overlay_emitter_pool", StandardOverlayQuadProcessor.OverlayEmitterPool::new, StandardOverlayQuadProcessor.OverlayEmitterPool::reset); - public static final ProcessingDataKey SIMPLE_OVERLAY_EMITTER_POOL_KEY = create("simple_overlay_emitter_pool", SimpleOverlayQuadProcessor.OverlayEmitterPool::new, SimpleOverlayQuadProcessor.OverlayEmitterPool::reset); + public static final ProcessingDataKey MUTABLE_POS = create("mutable_pos", BlockPos.Mutable::new); + public static final ProcessingDataKey BIOME_CACHE = create("biome_cache", BaseProcessingPredicate.BiomeCache::new, BaseProcessingPredicate.BiomeCache::reset); + public static final ProcessingDataKey BLOCK_ENTITY_NAME_CACHE = create("block_entity_name_cache", BaseProcessingPredicate.BlockEntityNameCache::new, BaseProcessingPredicate.BlockEntityNameCache::reset); + public static final ProcessingDataKey VERTEX_CONTAINER = create("vertex_container", CompactCtmQuadProcessor.VertexContainer::new); + public static final ProcessingDataKey STANDARD_OVERLAY_EMITTER_POOL = create("standard_overlay_emitter_pool", StandardOverlayQuadProcessor.OverlayEmitterPool::new, StandardOverlayQuadProcessor.OverlayEmitterPool::reset); + public static final ProcessingDataKey SIMPLE_OVERLAY_EMITTER_POOL = create("simple_overlay_emitter_pool", SimpleOverlayQuadProcessor.OverlayEmitterPool::new, SimpleOverlayQuadProcessor.OverlayEmitterPool::reset); private static ProcessingDataKey create(String id, Supplier valueSupplier) { return ProcessingDataKeyRegistry.get().registerKey(ContinuityClient.asId(id), valueSupplier); diff --git a/src/main/java/me/pepperbell/continuity/client/processor/ProcessingPredicate.java b/src/main/java/me/pepperbell/continuity/client/processor/ProcessingPredicate.java index cfd28121..86237939 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/ProcessingPredicate.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/ProcessingPredicate.java @@ -8,5 +8,5 @@ import net.minecraft.world.BlockRenderView; public interface ProcessingPredicate { - boolean shouldProcessQuad(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, ProcessingDataProvider dataProvider); + boolean shouldProcessQuad(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, ProcessingDataProvider dataProvider); } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/TopQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/TopQuadProcessor.java index 221c7bda..066114a9 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/TopQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/TopQuadProcessor.java @@ -25,18 +25,18 @@ public TopQuadProcessor(Sprite[] sprites, ProcessingPredicate processingPredicat } @Override - public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { + public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { Direction lightFace = quad.lightFace(); Direction.Axis axis; - if (state.contains(Properties.AXIS)) { - axis = state.get(Properties.AXIS); + if (appearanceState.contains(Properties.AXIS)) { + axis = appearanceState.get(Properties.AXIS); } else { axis = Direction.Axis.Y; } if (lightFace.getAxis() != axis) { Direction up = Direction.from(axis, Direction.AxisDirection.POSITIVE); - BlockPos.Mutable mutablePos = context.getData(ProcessingDataKeys.MUTABLE_POS_KEY).set(pos, up); - if (connectionPredicate.shouldConnect(blockView, state, pos, mutablePos, lightFace, sprite, innerSeams)) { + BlockPos.Mutable mutablePos = context.getData(ProcessingDataKeys.MUTABLE_POS).set(pos, up); + if (connectionPredicate.shouldConnect(blockView, appearanceState, state, pos, mutablePos, lightFace, sprite, innerSeams)) { return SimpleQuadProcessor.process(quad, sprite, sprites[0]); } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/overlay/OverlayProcessingPredicate.java b/src/main/java/me/pepperbell/continuity/client/processor/overlay/OverlayProcessingPredicate.java index 2b730125..88c4ec4d 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/overlay/OverlayProcessingPredicate.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/overlay/OverlayProcessingPredicate.java @@ -24,8 +24,8 @@ public OverlayProcessingPredicate(@Nullable EnumSet faces, @Nullable } @Override - public boolean shouldProcessQuad(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, ProcessingDataProvider dataProvider) { - if (!super.shouldProcessQuad(quad, sprite, blockView, state, pos, dataProvider)) { + public boolean shouldProcessQuad(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, ProcessingDataProvider dataProvider) { + if (!super.shouldProcessQuad(quad, sprite, blockView, appearanceState, state, pos, dataProvider)) { return false; } return QuadUtil.isQuadUnitSquare(quad); diff --git a/src/main/java/me/pepperbell/continuity/client/processor/overlay/SimpleOverlayQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/overlay/SimpleOverlayQuadProcessor.java index e9b0076c..091e553a 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/overlay/SimpleOverlayQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/overlay/SimpleOverlayQuadProcessor.java @@ -42,11 +42,11 @@ public SimpleOverlayQuadProcessor(SpriteProvider spriteProvider, ProcessingPredi } @Override - public ProcessingResult processQuad(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { - if (processingPredicate.shouldProcessQuad(quad, sprite, blockView, state, pos, context)) { - Sprite newSprite = spriteProvider.getSprite(quad, sprite, blockView, state, pos, randomSupplier, context); + public ProcessingResult processQuad(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { + if (processingPredicate.shouldProcessQuad(quad, sprite, blockView, appearanceState, state, pos, context)) { + Sprite newSprite = spriteProvider.getSprite(quad, sprite, blockView, appearanceState, state, pos, randomSupplier, context); if (newSprite != null && !TextureUtil.isMissingSprite(newSprite)) { - OverlayEmitter emitter = context.getData(ProcessingDataKeys.SIMPLE_OVERLAY_EMITTER_POOL_KEY).get(); + OverlayEmitter emitter = context.getData(ProcessingDataKeys.SIMPLE_OVERLAY_EMITTER_POOL).get(); emitter.prepare(quad.lightFace(), newSprite, RenderUtil.getTintColor(tintBlock, blockView, pos, tintIndex), material); context.addEmitterConsumer(emitter); } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/overlay/StandardOverlayQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/overlay/StandardOverlayQuadProcessor.java index d83e3fcc..d2246b42 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/overlay/StandardOverlayQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/overlay/StandardOverlayQuadProcessor.java @@ -34,7 +34,6 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; -import net.minecraft.world.EmptyBlockView; public class StandardOverlayQuadProcessor extends AbstractQuadProcessor { @Nullable @@ -63,142 +62,140 @@ public StandardOverlayQuadProcessor(Sprite[] sprites, ProcessingPredicate proces this.tintIndex = tintIndex; this.tintBlock = tintBlock; material = RenderUtil.getMaterialFinder().blendMode(0, layer).find(); + + // Turn all missing sprites into null, since it is more efficient to check for a null sprite than a missing + // sprite. There is no functional difference between missing and null sprites for this processor. + for (int i = 0; i < sprites.length; i++) { + Sprite sprite = sprites[i]; + if (TextureUtil.isMissingSprite(sprite)) { + sprites[i] = null; + } + } } @Override - public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { + public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { Direction lightFace = quad.lightFace(); - OverlayEmitter emitter = getEmitter(blockView, pos, state, lightFace, sprite, DirectionMaps.getMap(lightFace)[0], context); + OverlayEmitter emitter = getEmitter(blockView, appearanceState, state, pos, lightFace, sprite, DirectionMaps.getMap(lightFace)[0], context); if (emitter != null) { context.addEmitterConsumer(emitter); } return ProcessingResult.NEXT_PROCESSOR; } - protected boolean appliesOverlay(BlockState other, BlockRenderView blockView, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { - if (other.getBlock().hasDynamicBounds()) { - return false; - } - if (!other.isFullCube(EmptyBlockView.INSTANCE, BlockPos.ORIGIN)) { + protected boolean appliesOverlay(BlockState otherAppearanceState, BlockState otherState, BlockPos otherPos, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { + // OptiFine never applies overlays from blocks with dynamic bounds. To improve mod compatibility, call + // isFullCube with the correct values and do not check for dynamic bounds explicitly. For vanilla blocks, this + // change only makes it so retracted pistons and shulker boxes can apply overlays. + if (!otherState.isFullCube(blockView, otherPos)) { return false; } if (connectBlocksPredicate != null) { - if (!connectBlocksPredicate.test(other)) { + if (!connectBlocksPredicate.test(otherAppearanceState)) { return false; } } if (connectTilesSet != null) { - if (!connectTilesSet.contains(SpriteCalculator.getSprite(other, face).getContents().getId())) { + if (!connectTilesSet.contains(SpriteCalculator.getSprite(otherAppearanceState, face).getContents().getId())) { return false; } } - return !connectionPredicate.shouldConnect(blockView, state, pos, other, face, quadSprite); + return !connectionPredicate.shouldConnect(blockView, appearanceState, state, pos, otherAppearanceState, otherState, otherPos, face, quadSprite); } - protected boolean hasSameOverlay(BlockState other, BlockRenderView blockView, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { + protected boolean hasSameOverlay(@Nullable BlockState otherAppearanceState, Direction face) { + if (otherAppearanceState == null) { + return false; + } if (matchBlocksPredicate != null) { - if (!matchBlocksPredicate.test(other)) { + if (!matchBlocksPredicate.test(otherAppearanceState)) { return false; } } if (matchTilesSet != null) { - if (!matchTilesSet.contains(SpriteCalculator.getSprite(other, face).getContents().getId())) { + if (!matchTilesSet.contains(SpriteCalculator.getSprite(otherAppearanceState, face).getContents().getId())) { return false; } } return true; } - protected boolean appliesOverlayUnobscured(BlockState state0, Direction direction0, BlockRenderView blockView, BlockPos pos, BlockState state, Direction lightFace, Sprite quadSprite, BlockPos.Mutable mutablePos) { - boolean a0 = appliesOverlay(state0, blockView, state, pos, lightFace, quadSprite); - if (a0) { - mutablePos.set(pos, direction0).move(lightFace); - a0 = !blockView.getBlockState(mutablePos).isOpaqueFullCube(blockView, mutablePos); - } - return a0; - } - - protected boolean hasSameOverlayUnobscured(BlockState state0, Direction direction0, BlockRenderView blockView, BlockPos pos, BlockState state, Direction lightFace, Sprite quadSprite, BlockPos.Mutable mutablePos) { - boolean s0 = hasSameOverlay(state0, blockView, state, pos, lightFace, quadSprite); - if (s0) { - mutablePos.set(pos, direction0).move(lightFace); - s0 = !blockView.getBlockState(mutablePos).isOpaqueFullCube(blockView, mutablePos); - } - return s0; - } - - protected boolean appliesOverlayCorner(Direction direction0, Direction direction1, BlockRenderView blockView, BlockPos pos, BlockState state, Direction lightFace, Sprite quadSprite, BlockPos.Mutable mutablePos) { - mutablePos.set(pos, direction0).move(direction1); - boolean corner0 = appliesOverlay(blockView.getBlockState(mutablePos), blockView, state, pos, lightFace, quadSprite); - if (corner0) { + protected boolean appliesOverlayCorner(Direction dir0, Direction dir1, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Direction lightFace, Sprite quadSprite) { + mutablePos.set(pos, dir0).move(dir1); + BlockState otherState = blockView.getBlockState(mutablePos); + BlockState otherAppearanceState = otherState.getAppearance(blockView, mutablePos, lightFace, state, pos); + if (appliesOverlay(otherAppearanceState, otherState, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite)) { mutablePos.move(lightFace); - corner0 = !blockView.getBlockState(mutablePos).isOpaqueFullCube(blockView, mutablePos); + return !blockView.getBlockState(mutablePos).isOpaqueFullCube(blockView, mutablePos); } - return corner0; + return false; } - protected OverlayEmitter fromCorner(Direction direction0, Direction direction1, int sprite0, int sprite1, OverlayEmitter emitter, BlockRenderView blockView, BlockPos pos, BlockState state, Direction lightFace, Sprite quadSprite, BlockPos.Mutable mutablePos) { + protected OverlayEmitter fromTwoSidesAdj(OverlayEmitter emitter, @Nullable BlockState appearanceState0, @Nullable BlockState appearanceState1, Direction dir0, Direction dir1, int sprite, int spriteC01, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Direction lightFace, Sprite quadSprite) { prepareEmitter(emitter, lightFace, blockView, pos); - emitter.addSprite(sprites[sprite0]); - mutablePos.set(pos, direction0).move(direction1); - if (appliesOverlay(blockView.getBlockState(mutablePos), blockView, state, pos, lightFace, quadSprite)) { - mutablePos.move(lightFace); - if (!blockView.getBlockState(mutablePos).isOpaqueFullCube(blockView, mutablePos)) { - emitter.addSprite(sprites[sprite1]); - } + emitter.addSprite(sprites[sprite]); + // OptiFine does not check whether the other two adjacent blocks have the same overlay before trying to apply + // the corner overlay. I consider this a bug since it is inconsistent with other cases, so it is fixed here by + // checking those blocks. + if ((hasSameOverlay(appearanceState0, lightFace) + || hasSameOverlay(appearanceState1, lightFace)) + && appliesOverlayCorner(dir0, dir1, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite)) { + emitter.addSprite(sprites[spriteC01]); } return emitter; } - protected OverlayEmitter fromOneSide(BlockState state0, BlockState state1, BlockState state2, Direction direction0, Direction direction1, Direction direction2, int sprite0, int sprite1, int sprite2, OverlayEmitter emitter, BlockRenderView blockView, BlockPos pos, BlockState state, Direction lightFace, Sprite quadSprite, BlockPos.Mutable mutablePos) { - boolean s0 = hasSameOverlayUnobscured(state0, direction0, blockView, pos, state, lightFace, quadSprite, mutablePos); - boolean s1 = hasSameOverlayUnobscured(state1, direction1, blockView, pos, state, lightFace, quadSprite, mutablePos); - boolean s2 = hasSameOverlayUnobscured(state2, direction2, blockView, pos, state, lightFace, quadSprite, mutablePos); + protected OverlayEmitter fromOneSide(OverlayEmitter emitter, @Nullable BlockState appearanceState0, @Nullable BlockState appearanceState1, @Nullable BlockState appearanceState2, Direction dir0, Direction dir1, Direction dir2, int sprite, int spriteC01, int spriteC12, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Direction lightFace, Sprite quadSprite) { + boolean c01; + boolean c12; + if (hasSameOverlay(appearanceState1, lightFace)) { + c01 = true; + c12 = true; + } else { + c01 = hasSameOverlay(appearanceState0, lightFace); + c12 = hasSameOverlay(appearanceState2, lightFace); + } prepareEmitter(emitter, lightFace, blockView, pos); - emitter.addSprite(sprites[sprite0]); - if (s0 | s1) { - if (appliesOverlayCorner(direction0, direction1, blockView, pos, state, lightFace, quadSprite, mutablePos)) { - emitter.addSprite(sprites[sprite1]); - } + emitter.addSprite(sprites[sprite]); + if (c01 && appliesOverlayCorner(dir0, dir1, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite)) { + emitter.addSprite(sprites[spriteC01]); } - if (s1 | s2) { - if (appliesOverlayCorner(direction1, direction2, blockView, pos, state, lightFace, quadSprite, mutablePos)) { - emitter.addSprite(sprites[sprite2]); - } + if (c12 && appliesOverlayCorner(dir1, dir2, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite)) { + emitter.addSprite(sprites[spriteC12]); } return emitter; } protected static OverlayEmitter getEmitter(ProcessingDataProvider dataProvider) { - return dataProvider.getData(ProcessingDataKeys.STANDARD_OVERLAY_EMITTER_POOL_KEY).get(); + return dataProvider.getData(ProcessingDataKeys.STANDARD_OVERLAY_EMITTER_POOL).get(); } protected void prepareEmitter(OverlayEmitter emitter, Direction face, BlockRenderView blockView, BlockPos pos) { emitter.prepare(face, RenderUtil.getTintColor(tintBlock, blockView, pos, tintIndex), material); } - protected OverlayEmitter prepareEmitter(OverlayEmitter emitter, Direction face, BlockRenderView blockView, BlockPos pos, int sprite1) { + protected OverlayEmitter prepareEmitter(OverlayEmitter emitter, Direction face, BlockRenderView blockView, BlockPos pos, int sprite0) { prepareEmitter(emitter, face, blockView, pos); - emitter.addSprite(sprites[sprite1]); + emitter.addSprite(sprites[sprite0]); return emitter; } - protected OverlayEmitter prepareEmitter(OverlayEmitter emitter, Direction face, BlockRenderView blockView, BlockPos pos, int sprite1, int sprite2) { + protected OverlayEmitter prepareEmitter(OverlayEmitter emitter, Direction face, BlockRenderView blockView, BlockPos pos, int sprite0, int sprite1) { prepareEmitter(emitter, face, blockView, pos); + emitter.addSprite(sprites[sprite0]); emitter.addSprite(sprites[sprite1]); - emitter.addSprite(sprites[sprite2]); return emitter; } /* - 0: D R (CORNER) + 0: CORNER D+R 1: D - 2: L D (CORNER) + 2: CORNER L+D 3: D R 4: L D 5: L D R - 6: L D T + 6: L D U 7: R 8: L D R U 9: L @@ -206,127 +203,126 @@ protected OverlayEmitter prepareEmitter(OverlayEmitter emitter, Direction face, 11: L U 12: D R U 13: L R U - 14: R U (CORNER) + 14: CORNER R+U 15: U - 16: L U (CORNER) + 16: CORNER L+U */ @Nullable - protected OverlayEmitter getEmitter(BlockRenderView blockView, BlockPos pos, BlockState state, Direction lightFace, Sprite quadSprite, Direction[] directions, ProcessingDataProvider dataProvider) { - BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS_KEY); - - // - - mutablePos.set(pos, directions[0]); - BlockState state0 = blockView.getBlockState(mutablePos); - boolean left = appliesOverlayUnobscured(state0, directions[0], blockView, pos, state, lightFace, quadSprite, mutablePos); - mutablePos.set(pos, directions[1]); - BlockState state1 = blockView.getBlockState(mutablePos); - boolean down = appliesOverlayUnobscured(state1, directions[1], blockView, pos, state, lightFace, quadSprite, mutablePos); - mutablePos.set(pos, directions[2]); - BlockState state2 = blockView.getBlockState(mutablePos); - boolean right = appliesOverlayUnobscured(state2, directions[2], blockView, pos, state, lightFace, quadSprite, mutablePos); - mutablePos.set(pos, directions[3]); - BlockState state3 = blockView.getBlockState(mutablePos); - boolean up = appliesOverlayUnobscured(state3, directions[3], blockView, pos, state, lightFace, quadSprite, mutablePos); - - // - - if (left & down & right & up) { - return prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 8); - } - if (left & down & right) { - return prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 5); - } - if (left & down & up) { - return prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 6); - } - if (left & right & up) { - return prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 13); - } - if (down & right & up) { - return prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 12); - } - - if (left & right) { - return prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 9, 7); - } - if (up & down) { - return prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 15, 1); - } - - if (left & down) { - return fromCorner(directions[2], directions[3], 4, 14, getEmitter(dataProvider), blockView, pos, state, lightFace, quadSprite, mutablePos); - } - if (down & right) { - return fromCorner(directions[0], directions[3], 3, 16, getEmitter(dataProvider), blockView, pos, state, lightFace, quadSprite, mutablePos); - } - if (right & up) { - return fromCorner(directions[0], directions[1], 10, 2, getEmitter(dataProvider), blockView, pos, state, lightFace, quadSprite, mutablePos); - } - if (up & left) { - return fromCorner(directions[1], directions[2], 11, 0, getEmitter(dataProvider), blockView, pos, state, lightFace, quadSprite, mutablePos); - } - - // - - if (left) { - return fromOneSide(state1, state2, state3, directions[1], directions[2], directions[3], 9, 0, 14, getEmitter(dataProvider), blockView, pos, state, lightFace, quadSprite, mutablePos); - } - if (down) { - return fromOneSide(state2, state3, state0, directions[2], directions[3], directions[0], 1, 14, 16, getEmitter(dataProvider), blockView, pos, state, lightFace, quadSprite, mutablePos); - } - if (right) { - return fromOneSide(state3, state0, state1, directions[3], directions[0], directions[1], 7, 16, 2, getEmitter(dataProvider), blockView, pos, state, lightFace, quadSprite, mutablePos); - } - if (up) { - return fromOneSide(state0, state1, state2, directions[0], directions[1], directions[2], 15, 2, 0, getEmitter(dataProvider), blockView, pos, state, lightFace, quadSprite, mutablePos); - } - - // - - boolean s0 = hasSameOverlayUnobscured(state0, directions[0], blockView, pos, state, lightFace, quadSprite, mutablePos); - boolean s1 = hasSameOverlayUnobscured(state1, directions[1], blockView, pos, state, lightFace, quadSprite, mutablePos); - boolean s2 = hasSameOverlayUnobscured(state2, directions[2], blockView, pos, state, lightFace, quadSprite, mutablePos); - boolean s3 = hasSameOverlayUnobscured(state3, directions[3], blockView, pos, state, lightFace, quadSprite, mutablePos); - - boolean corner0 = false; - boolean corner1 = false; - boolean corner2 = false; - boolean corner3 = false; - if (s0 | s1) { - corner0 = appliesOverlayCorner(directions[0], directions[1], blockView, pos, state, lightFace, quadSprite, mutablePos); - } - if (s1 | s2) { - corner1 = appliesOverlayCorner(directions[1], directions[2], blockView, pos, state, lightFace, quadSprite, mutablePos); - } - if (s2 | s3) { - corner2 = appliesOverlayCorner(directions[2], directions[3], blockView, pos, state, lightFace, quadSprite, mutablePos); - } - if (s3 | s0) { - corner3 = appliesOverlayCorner(directions[3], directions[0], blockView, pos, state, lightFace, quadSprite, mutablePos); - } - - if (corner0 | corner1 | corner2 | corner3) { - OverlayEmitter emitter = getEmitter(dataProvider); - prepareEmitter(emitter, lightFace, blockView, pos); - if (corner0) { - emitter.addSprite(sprites[2]); + protected OverlayEmitter getEmitter(BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Direction lightFace, Sprite quadSprite, Direction[] directions, ProcessingDataProvider dataProvider) { + BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS); + + // [up] | [right] | [down] | [left] + // 8 + // 1 * 4 + // 2 + int applications = 0; + + mutablePos.set(pos, directions[0]).move(lightFace); + BlockState appearanceState0; + if (!blockView.getBlockState(mutablePos).isOpaqueFullCube(blockView, mutablePos)) { + mutablePos.set(pos, directions[0]); + BlockState state0 = blockView.getBlockState(mutablePos); + appearanceState0 = state0.getAppearance(blockView, mutablePos, lightFace, state, pos); + if (appliesOverlay(appearanceState0, state0, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite)) { + applications |= 0b0001; } - if (corner1) { - emitter.addSprite(sprites[0]); + } else { + appearanceState0 = null; + } + + mutablePos.set(pos, directions[1]).move(lightFace); + BlockState appearanceState1; + if (!blockView.getBlockState(mutablePos).isOpaqueFullCube(blockView, mutablePos)) { + mutablePos.set(pos, directions[1]); + BlockState state1 = blockView.getBlockState(mutablePos); + appearanceState1 = state1.getAppearance(blockView, mutablePos, lightFace, state, pos); + if (appliesOverlay(appearanceState1, state1, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite)) { + applications |= 0b0010; } - if (corner2) { - emitter.addSprite(sprites[14]); + } else { + appearanceState1 = null; + } + + mutablePos.set(pos, directions[2]).move(lightFace); + BlockState appearanceState2; + if (!blockView.getBlockState(mutablePos).isOpaqueFullCube(blockView, mutablePos)) { + mutablePos.set(pos, directions[2]); + BlockState state2 = blockView.getBlockState(mutablePos); + appearanceState2 = state2.getAppearance(blockView, mutablePos, lightFace, state, pos); + if (appliesOverlay(appearanceState2, state2, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite)) { + applications |= 0b0100; } - if (corner3) { - emitter.addSprite(sprites[16]); + } else { + appearanceState2 = null; + } + + mutablePos.set(pos, directions[3]).move(lightFace); + BlockState appearanceState3; + if (!blockView.getBlockState(mutablePos).isOpaqueFullCube(blockView, mutablePos)) { + mutablePos.set(pos, directions[3]); + BlockState state3 = blockView.getBlockState(mutablePos); + appearanceState3 = state3.getAppearance(blockView, mutablePos, lightFace, state, pos); + if (appliesOverlay(appearanceState3, state3, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite)) { + applications |= 0b1000; } - return emitter; - } - - // - - return null; + } else { + appearanceState3 = null; + } + + return switch (applications) { + case 0b1111 -> prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 8); + case 0b0111 -> prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 5); + case 0b1011 -> prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 6); + case 0b1101 -> prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 13); + case 0b1110 -> prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 12); + // + case 0b0101 -> prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 9, 7); + case 0b1010 -> prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 1, 15); + // + case 0b0011 -> fromTwoSidesAdj(getEmitter(dataProvider), appearanceState2, appearanceState3, directions[2], directions[3], 4, 14, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + case 0b0110 -> fromTwoSidesAdj(getEmitter(dataProvider), appearanceState3, appearanceState0, directions[3], directions[0], 3, 16, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + case 0b1100 -> fromTwoSidesAdj(getEmitter(dataProvider), appearanceState0, appearanceState1, directions[0], directions[1], 10, 2, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + case 0b1001 -> fromTwoSidesAdj(getEmitter(dataProvider), appearanceState1, appearanceState2, directions[1], directions[2], 11, 0, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + // + case 0b0001 -> fromOneSide(getEmitter(dataProvider), appearanceState1, appearanceState2, appearanceState3, directions[1], directions[2], directions[3], 9, 0, 14, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + case 0b0010 -> fromOneSide(getEmitter(dataProvider), appearanceState2, appearanceState3, appearanceState0, directions[2], directions[3], directions[0], 1, 14, 16, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + case 0b0100 -> fromOneSide(getEmitter(dataProvider), appearanceState3, appearanceState0, appearanceState1, directions[3], directions[0], directions[1], 7, 16, 2, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + case 0b1000 -> fromOneSide(getEmitter(dataProvider), appearanceState0, appearanceState1, appearanceState2, directions[0], directions[1], directions[2], 15, 2, 0, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + // + case 0b0000 -> { + boolean s0 = hasSameOverlay(appearanceState0, lightFace); + boolean s1 = hasSameOverlay(appearanceState1, lightFace); + boolean s2 = hasSameOverlay(appearanceState2, lightFace); + boolean s3 = hasSameOverlay(appearanceState3, lightFace); + + boolean c01 = (s0 | s1) && appliesOverlayCorner(directions[0], directions[1], mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + boolean c12 = (s1 | s2) && appliesOverlayCorner(directions[1], directions[2], mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + boolean c23 = (s2 | s3) && appliesOverlayCorner(directions[2], directions[3], mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + boolean c30 = (s3 | s0) && appliesOverlayCorner(directions[3], directions[0], mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + + if (c01 | c12 | c23 | c30) { + OverlayEmitter emitter = getEmitter(dataProvider); + prepareEmitter(emitter, lightFace, blockView, pos); + if (c01) { + emitter.addSprite(sprites[2]); + } + if (c12) { + emitter.addSprite(sprites[0]); + } + if (c23) { + emitter.addSprite(sprites[14]); + } + if (c30) { + emitter.addSprite(sprites[16]); + } + yield emitter; + } + + yield null; + } + // + default -> throw new IllegalStateException("Unexpected value: " + applications); + }; } public static class OverlayEmitter implements Consumer { @@ -353,10 +349,9 @@ public void prepare(Direction face, int color, RenderMaterial material) { this.material = material; } - public void addSprite(Sprite sprite) { - if (sprite != null && !TextureUtil.isMissingSprite(sprite)) { - sprites[spriteAmount] = sprite; - spriteAmount++; + public void addSprite(@Nullable Sprite sprite) { + if (sprite != null) { + sprites[spriteAmount++] = sprite; } } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/CtmSpriteProvider.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/CtmSpriteProvider.java index 9cb170ac..9246e52b 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/simple/CtmSpriteProvider.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/CtmSpriteProvider.java @@ -56,18 +56,18 @@ public CtmSpriteProvider(Sprite[] sprites, ConnectionPredicate connectionPredica @Override @Nullable - public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { - Direction[] directions = DirectionMaps.getDirections(orientationMode, quad, state); - BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS_KEY); - int connections = getConnections(connectionPredicate, innerSeams, directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); + public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { + Direction[] directions = DirectionMaps.getDirections(orientationMode, quad, appearanceState); + BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS); + int connections = getConnections(directions, connectionPredicate, innerSeams, mutablePos, blockView, appearanceState, state, pos, quad.lightFace(), sprite); return sprites[SPRITE_INDEX_MAP[connections]]; } - public static int getConnections(ConnectionPredicate connectionPredicate, boolean innerSeams, Direction[] directions, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { + public static int getConnections(Direction[] directions, ConnectionPredicate connectionPredicate, boolean innerSeams, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { int connections = 0; for (int i = 0; i < 4; i++) { mutablePos.set(pos, directions[i]); - if (connectionPredicate.shouldConnect(blockView, state, pos, mutablePos, face, quadSprite, innerSeams)) { + if (connectionPredicate.shouldConnect(blockView, appearanceState, state, pos, mutablePos, face, quadSprite, innerSeams)) { connections |= 1 << (i * 2); } } @@ -76,7 +76,7 @@ public static int getConnections(ConnectionPredicate connectionPredicate, boolea int index2 = (i + 1) % 4; if (((connections >>> index1 * 2) & 1) == 1 && ((connections >>> index2 * 2) & 1) == 1) { mutablePos.set(pos, directions[index1]).move(directions[index2]); - if (connectionPredicate.shouldConnect(blockView, state, pos, mutablePos, face, quadSprite, innerSeams)) { + if (connectionPredicate.shouldConnect(blockView, appearanceState, state, pos, mutablePos, face, quadSprite, innerSeams)) { connections |= 1 << (i * 2 + 1); } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/FixedSpriteProvider.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/FixedSpriteProvider.java index 67f9e197..4be8eac9 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/simple/FixedSpriteProvider.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/FixedSpriteProvider.java @@ -22,7 +22,7 @@ public FixedSpriteProvider(Sprite sprite) { @Override @Nullable - public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { + public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { return this.sprite; } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/HorizontalSpriteProvider.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/HorizontalSpriteProvider.java index 11ccc2b7..2aaa68a0 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/simple/HorizontalSpriteProvider.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/HorizontalSpriteProvider.java @@ -39,18 +39,18 @@ public HorizontalSpriteProvider(Sprite[] sprites, ConnectionPredicate connection @Override @Nullable - public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { - Direction[] directions = DirectionMaps.getDirections(orientationMode, quad, state); - BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS_KEY); - int connections = getConnections(directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); + public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { + Direction[] directions = DirectionMaps.getDirections(orientationMode, quad, appearanceState); + BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS); + int connections = getConnections(directions, mutablePos, blockView, appearanceState, state, pos, quad.lightFace(), sprite); return sprites[SPRITE_INDEX_MAP[connections]]; } - protected int getConnections(Direction[] directions, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { + protected int getConnections(Direction[] directions, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { int connections = 0; for (int i = 0; i < 2; i++) { mutablePos.set(pos, directions[i * 2]); - if (connectionPredicate.shouldConnect(blockView, state, pos, mutablePos, face, quadSprite, innerSeams)) { + if (connectionPredicate.shouldConnect(blockView, appearanceState, state, pos, mutablePos, face, quadSprite, innerSeams)) { connections |= 1 << i; } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/HorizontalVerticalSpriteProvider.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/HorizontalVerticalSpriteProvider.java index 1781149f..6e976486 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/simple/HorizontalVerticalSpriteProvider.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/HorizontalVerticalSpriteProvider.java @@ -36,28 +36,28 @@ public HorizontalVerticalSpriteProvider(Sprite[] sprites, ConnectionPredicate co @Override @Nullable - public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { - Direction[] directions = DirectionMaps.getDirections(orientationMode, quad, state); - BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS_KEY); - int connections = getConnections(directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); + public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { + Direction[] directions = DirectionMaps.getDirections(orientationMode, quad, appearanceState); + BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS); + int connections = getConnections(directions, mutablePos, blockView, appearanceState, state, pos, quad.lightFace(), sprite); if (connections != 0) { return sprites[SPRITE_INDEX_MAP[connections]]; } else { - int secondaryConnections = getSecondaryConnections(directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); + int secondaryConnections = getSecondaryConnections(directions, mutablePos, blockView, appearanceState, state, pos, quad.lightFace(), sprite); return sprites[SECONDARY_SPRITE_INDEX_MAP[secondaryConnections]]; } } - protected int getSecondaryConnections(Direction[] directions, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { + protected int getSecondaryConnections(Direction[] directions, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { int connections = 0; for (int i = 0; i < 2; i++) { Direction direction = directions[i * 2 + 1]; mutablePos.set(pos, direction); - if (connectionPredicate.shouldConnect(blockView, state, pos, mutablePos, face, quadSprite, innerSeams)) { + if (connectionPredicate.shouldConnect(blockView, appearanceState, state, pos, mutablePos, face, quadSprite, innerSeams)) { connections |= 1 << (i * 3 + 1); for (int j = 0; j < 2; j++) { mutablePos.set(pos, direction).move(directions[((i + j) % 2) * 2]); - if (connectionPredicate.shouldConnect(blockView, state, pos, mutablePos, face, quadSprite, innerSeams)) { + if (connectionPredicate.shouldConnect(blockView, appearanceState, state, pos, mutablePos, face, quadSprite, innerSeams)) { connections |= 1 << (i * 3 + j * 2); } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/RandomSpriteProvider.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/RandomSpriteProvider.java index 3fdf36b7..60da9bf9 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/simple/RandomSpriteProvider.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/RandomSpriteProvider.java @@ -36,26 +36,26 @@ public RandomSpriteProvider(Sprite[] sprites, RandomIndexProvider indexProvider, @Override @Nullable - public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { - Direction face = symmetry.apply(quad.lightFace()); + public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { + Direction face = quad.lightFace(); int x = pos.getX(); int y = pos.getY(); int z = pos.getZ(); if (linked) { - Block block = state.getBlock(); - BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS_KEY).set(pos); + Block block = appearanceState.getBlock(); + BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS).set(pos); int i = 0; do { mutablePos.setY(mutablePos.getY() - 1); i++; - } while (i < 3 && block == blockView.getBlockState(mutablePos).getBlock()); + } while (i < 3 && block == blockView.getBlockState(mutablePos).getAppearance(blockView, mutablePos, face, state, pos).getBlock()); y = mutablePos.getY() + 1; } - int seed = MathUtil.mix(x, y, z, face.ordinal(), randomLoops); + int seed = MathUtil.mix(x, y, z, symmetry.apply(face).ordinal(), randomLoops); return sprites[indexProvider.getRandomIndex(seed)]; } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/RepeatSpriteProvider.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/RepeatSpriteProvider.java index 1c2a0491..9c3ac23a 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/simple/RepeatSpriteProvider.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/RepeatSpriteProvider.java @@ -33,7 +33,7 @@ public RepeatSpriteProvider(Sprite[] sprites, int width, int height, Symmetry sy @Override @Nullable - public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { + public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { Direction face = symmetry.apply(quad.lightFace()); int x = pos.getX(); @@ -77,7 +77,7 @@ public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, } } - switch (orientationMode.getOrientation(quad, state)) { + switch (orientationMode.getOrientation(quad, appearanceState)) { case 1 -> { int temp = spriteX; spriteX = -spriteY - 1; diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/SimpleQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/SimpleQuadProcessor.java index 92101d7e..f2207d5a 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/simple/SimpleQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/SimpleQuadProcessor.java @@ -28,11 +28,11 @@ public SimpleQuadProcessor(SpriteProvider spriteProvider, ProcessingPredicate pr } @Override - public ProcessingResult processQuad(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { - if (!processingPredicate.shouldProcessQuad(quad, sprite, blockView, state, pos, context)) { + public ProcessingResult processQuad(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { + if (!processingPredicate.shouldProcessQuad(quad, sprite, blockView, appearanceState, state, pos, context)) { return ProcessingResult.NEXT_PROCESSOR; } - Sprite newSprite = spriteProvider.getSprite(quad, sprite, blockView, state, pos, randomSupplier, context); + Sprite newSprite = spriteProvider.getSprite(quad, sprite, blockView, appearanceState, state, pos, randomSupplier, context); return process(quad, sprite, newSprite); } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/SpriteProvider.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/SpriteProvider.java index 5c87131c..479c3b24 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/simple/SpriteProvider.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/SpriteProvider.java @@ -15,7 +15,7 @@ public interface SpriteProvider { @Nullable - Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider); + Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider); interface Factory { SpriteProvider createSpriteProvider(Sprite[] sprites, T properties); diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/VerticalHorizontalSpriteProvider.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/VerticalHorizontalSpriteProvider.java index dd455a84..055af0cf 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/simple/VerticalHorizontalSpriteProvider.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/VerticalHorizontalSpriteProvider.java @@ -36,28 +36,28 @@ public VerticalHorizontalSpriteProvider(Sprite[] sprites, ConnectionPredicate co @Override @Nullable - public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { - Direction[] directions = DirectionMaps.getDirections(orientationMode, quad, state); - BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS_KEY); - int connections = getConnections(directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); + public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { + Direction[] directions = DirectionMaps.getDirections(orientationMode, quad, appearanceState); + BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS); + int connections = getConnections(directions, mutablePos, blockView, appearanceState, state, pos, quad.lightFace(), sprite); if (connections != 0) { return sprites[SPRITE_INDEX_MAP[connections]]; } else { - int secondaryConnections = getSecondaryConnections(directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); + int secondaryConnections = getSecondaryConnections(directions, mutablePos, blockView, appearanceState, state, pos, quad.lightFace(), sprite); return sprites[SECONDARY_SPRITE_INDEX_MAP[secondaryConnections]]; } } - protected int getSecondaryConnections(Direction[] directions, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { + protected int getSecondaryConnections(Direction[] directions, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { int connections = 0; for (int i = 0; i < 2; i++) { Direction direction = directions[i * 2]; mutablePos.set(pos, direction); - if (connectionPredicate.shouldConnect(blockView, state, pos, mutablePos, face, quadSprite, innerSeams)) { + if (connectionPredicate.shouldConnect(blockView, state, appearanceState, pos, mutablePos, face, quadSprite, innerSeams)) { connections |= 1 << (i * 3); for (int j = 0; j < 2; j++) { mutablePos.set(pos, direction).move(directions[((i + j) % 2) * 2 + 1]); - if (connectionPredicate.shouldConnect(blockView, state, pos, mutablePos, face, quadSprite, innerSeams)) { + if (connectionPredicate.shouldConnect(blockView, appearanceState, state, pos, mutablePos, face, quadSprite, innerSeams)) { connections |= 1 << ((i * 3 + j * 2 + 5) % 6); } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/VerticalSpriteProvider.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/VerticalSpriteProvider.java index b3489e5a..5c123776 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/simple/VerticalSpriteProvider.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/VerticalSpriteProvider.java @@ -41,18 +41,18 @@ public VerticalSpriteProvider(Sprite[] sprites, ConnectionPredicate connectionPr @Override @Nullable - public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { - Direction[] directions = DirectionMaps.getDirections(orientationMode, quad, state); - BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS_KEY); - int connections = getConnections(directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); + public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { + Direction[] directions = DirectionMaps.getDirections(orientationMode, quad, appearanceState); + BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS); + int connections = getConnections(directions, mutablePos, blockView, appearanceState, state, pos, quad.lightFace(), sprite); return sprites[SPRITE_INDEX_MAP[connections]]; } - protected int getConnections(Direction[] directions, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { + protected int getConnections(Direction[] directions, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { int connections = 0; for (int i = 0; i < 2; i++) { mutablePos.set(pos, directions[i * 2 + 1]); - if (connectionPredicate.shouldConnect(blockView, state, pos, mutablePos, face, quadSprite, innerSeams)) { + if (connectionPredicate.shouldConnect(blockView, appearanceState, state, pos, mutablePos, face, quadSprite, innerSeams)) { connections |= 1 << i; } } diff --git a/src/main/java/me/pepperbell/continuity/client/properties/BasicConnectingCtmProperties.java b/src/main/java/me/pepperbell/continuity/client/properties/BasicConnectingCtmProperties.java index 6e46feb9..54f54709 100644 --- a/src/main/java/me/pepperbell/continuity/client/properties/BasicConnectingCtmProperties.java +++ b/src/main/java/me/pepperbell/continuity/client/properties/BasicConnectingCtmProperties.java @@ -67,29 +67,29 @@ public ConnectionPredicate getConnectionPredicate() { public enum ConnectionType implements ConnectionPredicate { BLOCK { @Override - public boolean shouldConnect(BlockRenderView blockView, BlockState state, BlockPos pos, BlockState toState, Direction face, Sprite quadSprite) { - return state.getBlock() == toState.getBlock(); + public boolean shouldConnect(BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, BlockState otherAppearanceState, BlockState otherState, BlockPos otherPos, Direction face, Sprite quadSprite) { + return appearanceState.getBlock() == otherAppearanceState.getBlock(); } }, TILE { @Override - public boolean shouldConnect(BlockRenderView blockView, BlockState state, BlockPos pos, BlockState toState, Direction face, Sprite quadSprite) { - if (state == toState) { + public boolean shouldConnect(BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, BlockState otherAppearanceState, BlockState otherState, BlockPos otherPos, Direction face, Sprite quadSprite) { + if (appearanceState == otherAppearanceState) { return true; } - return quadSprite == SpriteCalculator.getSprite(toState, face); + return quadSprite == SpriteCalculator.getSprite(otherAppearanceState, face); } }, MATERIAL { @Override - public boolean shouldConnect(BlockRenderView blockView, BlockState state, BlockPos pos, BlockState toState, Direction face, Sprite quadSprite) { - return state.getMaterial() == toState.getMaterial(); + public boolean shouldConnect(BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, BlockState otherAppearanceState, BlockState otherState, BlockPos otherPos, Direction face, Sprite quadSprite) { + return appearanceState.getMaterial() == otherAppearanceState.getMaterial(); } }, STATE { @Override - public boolean shouldConnect(BlockRenderView blockView, BlockState state, BlockPos pos, BlockState toState, Direction face, Sprite quadSprite) { - return state == toState; + public boolean shouldConnect(BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, BlockState otherAppearanceState, BlockState otherState, BlockPos otherPos, Direction face, Sprite quadSprite) { + return appearanceState == otherAppearanceState; } }; } diff --git a/src/main/java/me/pepperbell/continuity/impl/client/ProcessingContextImpl.java b/src/main/java/me/pepperbell/continuity/impl/client/ProcessingContextImpl.java index c1d03ce7..0f62cf81 100644 --- a/src/main/java/me/pepperbell/continuity/impl/client/ProcessingContextImpl.java +++ b/src/main/java/me/pepperbell/continuity/impl/client/ProcessingContextImpl.java @@ -3,6 +3,8 @@ import java.util.List; import java.util.function.Consumer; +import org.jetbrains.annotations.Nullable; + import it.unimi.dsi.fastutil.objects.ObjectArrayList; import me.pepperbell.continuity.api.client.ProcessingDataKey; import me.pepperbell.continuity.api.client.ProcessingDataKeyRegistry; @@ -54,6 +56,7 @@ public T getData(ProcessingDataKey key) { } @SuppressWarnings("unchecked") + @Nullable public T getDataOrNull(ProcessingDataKey key) { return (T) processingData[key.getRawId()]; }