diff --git a/src/main/java/com/ghostipedia/cosmiccore/integration/sable/SableAssemblyRotationHolder.java b/src/main/java/com/ghostipedia/cosmiccore/integration/sable/SableAssemblyRotationHolder.java new file mode 100644 index 00000000..4321ec14 --- /dev/null +++ b/src/main/java/com/ghostipedia/cosmiccore/integration/sable/SableAssemblyRotationHolder.java @@ -0,0 +1,23 @@ +package com.ghostipedia.cosmiccore.integration.sable; + +import net.minecraft.world.level.block.Rotation; + +public final class SableAssemblyRotationHolder { + + private static final ThreadLocal CURRENT = new ThreadLocal<>(); + + private SableAssemblyRotationHolder() {} + + public static void set(Rotation rotation) { + CURRENT.set(rotation); + } + + public static void clear() { + CURRENT.remove(); + } + + public static Rotation current() { + Rotation rotation = CURRENT.get(); + return rotation == null ? Rotation.NONE : rotation; + } +} diff --git a/src/main/java/com/ghostipedia/cosmiccore/mixin/sable/BlockHighlightSubLevelMixin.java b/src/main/java/com/ghostipedia/cosmiccore/mixin/sable/BlockHighlightSubLevelMixin.java new file mode 100644 index 00000000..295b5f78 --- /dev/null +++ b/src/main/java/com/ghostipedia/cosmiccore/mixin/sable/BlockHighlightSubLevelMixin.java @@ -0,0 +1,45 @@ +package com.ghostipedia.cosmiccore.mixin.sable; + +import com.gregtechceu.gtceu.client.ClientEventListener; +import com.gregtechceu.gtceu.client.renderer.BlockHighlightRenderer; + +import net.minecraft.client.Minecraft; +import net.minecraft.core.Vec3i; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.HitResult; +import net.neoforged.neoforge.client.event.RenderHighlightEvent; + +import dev.ryanhcode.sable.Sable; +import dev.ryanhcode.sable.mixinhelpers.block_outline_render.SubLevelCamera; +import dev.ryanhcode.sable.sublevel.ClientSubLevel; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(value = ClientEventListener.class, remap = false) +public abstract class BlockHighlightSubLevelMixin { + + @Inject(method = "onBlockHighlightEvent", at = @At("HEAD"), cancellable = true) + private static void cosmiccore$transformSubLevelOverlay(RenderHighlightEvent.Block event, CallbackInfo ci) { + HitResult target = event.getTarget(); + if (!(target instanceof BlockHitResult blockTarget)) { + return; + } + Level level = Minecraft.getInstance().level; + if (level == null) { + return; + } + ClientSubLevel subLevel = (ClientSubLevel) Sable.HELPER.getContaining(level, (Vec3i) blockTarget.getBlockPos()); + if (subLevel == null) { + return; + } + SubLevelCamera subLevelCamera = new SubLevelCamera(); + subLevelCamera.setCamera(Minecraft.getInstance().gameRenderer.getMainCamera()); + subLevelCamera.setPose(subLevel.renderPose()); + BlockHighlightRenderer.renderBlockHighlight(event.getPoseStack(), subLevelCamera, blockTarget, + event.getMultiBufferSource(), event.getDeltaTracker().getGameTimeDeltaPartialTick(false)); + ci.cancel(); + } +} diff --git a/src/main/java/com/ghostipedia/cosmiccore/mixin/sable/PipeBlockSubLevelMixin.java b/src/main/java/com/ghostipedia/cosmiccore/mixin/sable/PipeBlockSubLevelMixin.java index 2a736767..6c451216 100644 --- a/src/main/java/com/ghostipedia/cosmiccore/mixin/sable/PipeBlockSubLevelMixin.java +++ b/src/main/java/com/ghostipedia/cosmiccore/mixin/sable/PipeBlockSubLevelMixin.java @@ -1,17 +1,22 @@ package com.ghostipedia.cosmiccore.mixin.sable; +import com.ghostipedia.cosmiccore.integration.sable.SableAssemblyRotationHolder; + import com.gregtechceu.gtceu.api.block.PipeBlock; import com.gregtechceu.gtceu.api.blockentity.PipeBlockEntity; import com.gregtechceu.gtceu.api.pipenet.LevelPipeNet; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.state.BlockState; import dev.ryanhcode.sable.api.block.BlockSubLevelAssemblyListener; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; @Mixin(value = PipeBlock.class, remap = false) public abstract class PipeBlockSubLevelMixin implements BlockSubLevelAssemblyListener { @@ -29,8 +34,36 @@ public void afterMove(ServerLevel originLevel, ServerLevel resultingLevel, Block tick(state, resultingLevel, newPos, resultingLevel.getRandom()); } if (resultingLevel.getBlockEntity(newPos) instanceof PipeBlockEntity pipe) { + cosmiccore$rotateConnections(pipe); pipe.getSyncDataHolder().resyncAllFields(); pipe.scheduleRenderUpdate(); } } + + @Unique + private static void cosmiccore$rotateConnections(PipeBlockEntity pipe) { + Rotation rotation = SableAssemblyRotationHolder.current(); + if (rotation == Rotation.NONE) { + return; + } + int connections = cosmiccore$rotateMask(pipe.getConnections(), rotation); + if (connections != pipe.getConnections()) { + pipe.setConnections(connections); + } + int blocked = cosmiccore$rotateMask(pipe.getBlockedConnections(), rotation); + if (blocked != pipe.getBlockedConnections()) { + pipe.setBlockedConnections(blocked); + } + } + + @Unique + private static int cosmiccore$rotateMask(int mask, Rotation rotation) { + int result = 0; + for (Direction dir : Direction.values()) { + if (PipeBlockEntity.isConnected(mask, dir)) { + result |= 1 << rotation.rotate(dir).ordinal(); + } + } + return result; + } } diff --git a/src/main/java/com/ghostipedia/cosmiccore/mixin/sable/SubLevelAssemblyHelperRotationCaptureMixin.java b/src/main/java/com/ghostipedia/cosmiccore/mixin/sable/SubLevelAssemblyHelperRotationCaptureMixin.java new file mode 100644 index 00000000..de8c72c8 --- /dev/null +++ b/src/main/java/com/ghostipedia/cosmiccore/mixin/sable/SubLevelAssemblyHelperRotationCaptureMixin.java @@ -0,0 +1,33 @@ +package com.ghostipedia.cosmiccore.mixin.sable; + +import com.ghostipedia.cosmiccore.integration.sable.SableAssemblyRotationHolder; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; + +import dev.ryanhcode.sable.api.SubLevelAssemblyHelper; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(value = SubLevelAssemblyHelper.class, remap = false) +public abstract class SubLevelAssemblyHelperRotationCaptureMixin { + + @Inject( + method = "moveBlocks(Lnet/minecraft/server/level/ServerLevel;Ldev/ryanhcode/sable/api/SubLevelAssemblyHelper$AssemblyTransform;Ljava/lang/Iterable;)V", + at = @At("HEAD")) + private static void cosmiccore$captureRotation(ServerLevel level, + SubLevelAssemblyHelper.AssemblyTransform transform, + Iterable positions, CallbackInfo ci) { + SableAssemblyRotationHolder.set(transform.getRotation()); + } + + @Inject( + method = "moveBlocks(Lnet/minecraft/server/level/ServerLevel;Ldev/ryanhcode/sable/api/SubLevelAssemblyHelper$AssemblyTransform;Ljava/lang/Iterable;)V", + at = @At("RETURN")) + private static void cosmiccore$clearRotation(ServerLevel level, SubLevelAssemblyHelper.AssemblyTransform transform, + Iterable positions, CallbackInfo ci) { + SableAssemblyRotationHolder.clear(); + } +} diff --git a/src/main/resources/cosmiccore.mixins.json b/src/main/resources/cosmiccore.mixins.json index 80019630..c4d46179 100644 --- a/src/main/resources/cosmiccore.mixins.json +++ b/src/main/resources/cosmiccore.mixins.json @@ -48,7 +48,8 @@ "gtfix.QuantumChestUpwardFacingCrashFixMixin", "gtfix.SchemaWidgetZoomMixin", "gtfix.SchemaWidgetPanMixin", - "gtfix.DummyChunkSourceThreadSafeMixin" + "gtfix.DummyChunkSourceThreadSafeMixin", + "sable.BlockHighlightSubLevelMixin" ], "mixins": [ "BlockPatternMixin", @@ -89,7 +90,8 @@ "worldgen.CubicSplineMultipointMixin", "sable.PipeBlockSubLevelMixin", "sable.MachineUIFactorySubLevelRangeMixin", - "sable.MetaMachineBlockSubLevelMixin" + "sable.MetaMachineBlockSubLevelMixin", + "sable.SubLevelAssemblyHelperRotationCaptureMixin" ], "injectors": { "defaultRequire": 1,