From cf87508276f845675e64ad88cbf013298aac72a3 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Wed, 9 Nov 2022 16:52:22 -0800 Subject: [PATCH] Refactor multi-pos block destruction - Replace DestroyProgressMixin with BlockDestructionProgressMixin and LevelRendererMixin - Replace DestroyProgressRenderingHandler with MultiPosDestructionHandler --- .../contraptions/relays/belt/BeltBlock.java | 17 ++--- .../trains/CameraDistanceModifier.java | 5 ++ .../logistics/trains/TrackPropagator.java | 2 +- .../logistics/trains/track/TrackBlock.java | 22 +++--- .../BlockDestructionProgressExtension.java | 14 ++++ .../DestroyProgressRenderingHandler.java | 16 ----- .../render/MultiPosDestructionHandler.java | 17 +++++ .../mixin/BlockDestructionProgressMixin.java | 27 ++++++++ .../create/foundation/mixin/CameraMixin.java | 3 +- .../mixin/DestroyProgressMixin.java | 37 ---------- .../foundation/mixin/GameRendererMixin.java | 2 - .../foundation/mixin/LevelRendererMixin.java | 69 +++++++++++++++++++ src/main/resources/create.mixins.json | 3 +- 13 files changed, 156 insertions(+), 78 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/block/render/BlockDestructionProgressExtension.java delete mode 100644 src/main/java/com/simibubi/create/foundation/block/render/DestroyProgressRenderingHandler.java create mode 100644 src/main/java/com/simibubi/create/foundation/block/render/MultiPosDestructionHandler.java create mode 100644 src/main/java/com/simibubi/create/foundation/mixin/BlockDestructionProgressMixin.java delete mode 100644 src/main/java/com/simibubi/create/foundation/mixin/DestroyProgressMixin.java create mode 100644 src/main/java/com/simibubi/create/foundation/mixin/LevelRendererMixin.java diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltBlock.java index 8581b69ee..679965e2a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltBlock.java @@ -1,8 +1,10 @@ package com.simibubi.create.content.contraptions.relays.belt; import java.util.ArrayList; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Set; import java.util.function.Consumer; import org.apache.commons.lang3.mutable.MutableBoolean; @@ -25,13 +27,12 @@ import com.simibubi.create.content.schematics.ISpecialBlockItemRequirement; import com.simibubi.create.content.schematics.ItemRequirement; import com.simibubi.create.content.schematics.ItemRequirement.ItemUseType; import com.simibubi.create.foundation.block.ITE; -import com.simibubi.create.foundation.block.render.DestroyProgressRenderingHandler; +import com.simibubi.create.foundation.block.render.MultiPosDestructionHandler; import com.simibubi.create.foundation.block.render.ReducedDestroyEffects; import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult; import com.simibubi.create.foundation.utility.Iterate; import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; @@ -475,7 +476,6 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE getExtraPositions(ClientLevel level, BlockPos pos, BlockState blockState, int progress) { BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof BeltTileEntity belt) { - for (BlockPos beltPos : BeltBlock.getBeltChain(level, belt.getController())) { - renderer.destroyBlockProgress(beltPos.hashCode(), beltPos, progress); - } + return new HashSet<>(BeltBlock.getBeltChain(level, belt.getController())); } - return false; + return null; } } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/CameraDistanceModifier.java b/src/main/java/com/simibubi/create/content/logistics/trains/CameraDistanceModifier.java index ce02689f2..07bb9edf4 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/CameraDistanceModifier.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/CameraDistanceModifier.java @@ -1,12 +1,17 @@ package com.simibubi.create.content.logistics.trains; import com.simibubi.create.foundation.config.AllConfigs; +import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.animation.LerpedFloat; public class CameraDistanceModifier { private static final LerpedFloat multiplier = LerpedFloat.linear().startWithValue(1); + public static float getMultiplier() { + return getMultiplier(AnimationTickHolder.getPartialTicks()); + } + public static float getMultiplier(float partialTicks) { return multiplier.getValue(partialTicks); } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/TrackPropagator.java b/src/main/java/com/simibubi/create/content/logistics/trains/TrackPropagator.java index 02cbba4c1..611787364 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/TrackPropagator.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/TrackPropagator.java @@ -32,7 +32,7 @@ public class TrackPropagator { } public static void onRailRemoved(LevelAccessor reader, BlockPos pos, BlockState state) { - if (!(state.getBlock()instanceof ITrackBlock track)) + if (!(state.getBlock() instanceof ITrackBlock track)) return; Collection ends = track.getConnected(reader, pos, state, false, null); diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackBlock.java b/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackBlock.java index 48664b073..a30072daf 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackBlock.java @@ -11,12 +11,16 @@ import static com.simibubi.create.AllShapes.TRACK_ORTHO_LONG; import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Random; +import java.util.Set; import java.util.function.Consumer; +import org.jetbrains.annotations.Nullable; + import com.google.common.base.Predicates; import com.jozufozu.flywheel.core.PartialModel; import com.jozufozu.flywheel.util.transform.TransformStack; @@ -41,7 +45,7 @@ import com.simibubi.create.content.schematics.ItemRequirement; import com.simibubi.create.content.schematics.ItemRequirement.ItemUseType; import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.block.ProperWaterloggedBlock; -import com.simibubi.create.foundation.block.render.DestroyProgressRenderingHandler; +import com.simibubi.create.foundation.block.render.MultiPosDestructionHandler; import com.simibubi.create.foundation.block.render.ReducedDestroyEffects; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.BlockFace; @@ -53,7 +57,6 @@ import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.ChatFormatting; import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; @@ -773,15 +776,16 @@ public class TrackBlock extends Block return new ItemRequirement(ItemUseType.CONSUME, stacks); } - public static class RenderProperties extends ReducedDestroyEffects implements DestroyProgressRenderingHandler { + public static class RenderProperties extends ReducedDestroyEffects implements MultiPosDestructionHandler { @Override - public boolean renderDestroyProgress(ClientLevel level, LevelRenderer renderer, int breakerId, BlockPos pos, - int progress, BlockState blockState) { + @Nullable + public Set getExtraPositions(ClientLevel level, BlockPos pos, BlockState blockState, + int progress) { BlockEntity blockEntity = level.getBlockEntity(pos); - if (blockEntity instanceof TrackTileEntity track) - for (BlockPos trackPos : track.connections.keySet()) - renderer.destroyBlockProgress(pos.hashCode(), trackPos, progress); - return false; + if (blockEntity instanceof TrackTileEntity track) { + return new HashSet<>(track.connections.keySet()); + } + return null; } } diff --git a/src/main/java/com/simibubi/create/foundation/block/render/BlockDestructionProgressExtension.java b/src/main/java/com/simibubi/create/foundation/block/render/BlockDestructionProgressExtension.java new file mode 100644 index 000000000..2a7bca863 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/block/render/BlockDestructionProgressExtension.java @@ -0,0 +1,14 @@ +package com.simibubi.create.foundation.block.render; + +import java.util.Set; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.core.BlockPos; + +public interface BlockDestructionProgressExtension { + @Nullable + Set getExtraPositions(); + + void setExtraPositions(@Nullable Set positions); +} diff --git a/src/main/java/com/simibubi/create/foundation/block/render/DestroyProgressRenderingHandler.java b/src/main/java/com/simibubi/create/foundation/block/render/DestroyProgressRenderingHandler.java deleted file mode 100644 index e077bad1b..000000000 --- a/src/main/java/com/simibubi/create/foundation/block/render/DestroyProgressRenderingHandler.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.simibubi.create.foundation.block.render; - -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.client.IBlockRenderProperties; - -public interface DestroyProgressRenderingHandler extends IBlockRenderProperties { - /** - * Called before the default block breaking progress overlay is rendered. - * - * @return if the default rendering should be cancelled or not - */ - boolean renderDestroyProgress(ClientLevel level, LevelRenderer renderer, int breakerId, BlockPos pos, int progress, BlockState blockState); -} diff --git a/src/main/java/com/simibubi/create/foundation/block/render/MultiPosDestructionHandler.java b/src/main/java/com/simibubi/create/foundation/block/render/MultiPosDestructionHandler.java new file mode 100644 index 000000000..38176411e --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/block/render/MultiPosDestructionHandler.java @@ -0,0 +1,17 @@ +package com.simibubi.create.foundation.block.render; + +import java.util.Set; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.state.BlockState; + +public interface MultiPosDestructionHandler { + /** + * Returned set must be mutable and must not be changed after it is returned. + */ + @Nullable + Set getExtraPositions(ClientLevel level, BlockPos pos, BlockState blockState, int progress); +} diff --git a/src/main/java/com/simibubi/create/foundation/mixin/BlockDestructionProgressMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/BlockDestructionProgressMixin.java new file mode 100644 index 000000000..9d1fa6f41 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/BlockDestructionProgressMixin.java @@ -0,0 +1,27 @@ +package com.simibubi.create.foundation.mixin; + +import java.util.Set; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +import com.simibubi.create.foundation.block.render.BlockDestructionProgressExtension; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.BlockDestructionProgress; + +@Mixin(BlockDestructionProgress.class) +public class BlockDestructionProgressMixin implements BlockDestructionProgressExtension { + @Unique + private Set extraPositions; + + @Override + public Set getExtraPositions() { + return extraPositions; + } + + @Override + public void setExtraPositions(Set positions) { + extraPositions = positions; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/mixin/CameraMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/CameraMixin.java index b9e775431..f6a4aff92 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/CameraMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/CameraMixin.java @@ -5,7 +5,6 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; import com.simibubi.create.content.logistics.trains.CameraDistanceModifier; -import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.client.Camera; @@ -17,6 +16,6 @@ public abstract class CameraMixin { index = 0 ) public double modifyCameraOffset(double originalValue) { - return originalValue * CameraDistanceModifier.getMultiplier(AnimationTickHolder.getPartialTicks()); + return originalValue * CameraDistanceModifier.getMultiplier(); } } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/DestroyProgressMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/DestroyProgressMixin.java deleted file mode 100644 index cfad69339..000000000 --- a/src/main/java/com/simibubi/create/foundation/mixin/DestroyProgressMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.simibubi.create.foundation.mixin; - -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.simibubi.create.foundation.block.render.DestroyProgressRenderingHandler; - -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.client.IBlockRenderProperties; -import net.minecraftforge.client.RenderProperties; - -@Mixin(ClientLevel.class) -public class DestroyProgressMixin { - @Shadow - @Final - private LevelRenderer levelRenderer; - - @Inject(at = @At("HEAD"), method = "destroyBlockProgress(ILnet/minecraft/core/BlockPos;I)V", cancellable = true) - private void onDestroyBlockProgress(int breakerId, BlockPos pos, int progress, CallbackInfo ci) { - ClientLevel self = (ClientLevel) (Object) this; - BlockState state = self.getBlockState(pos); - IBlockRenderProperties properties = RenderProperties.get(state); - if (properties instanceof DestroyProgressRenderingHandler handler) { - if (handler.renderDestroyProgress(self, levelRenderer, breakerId, pos, progress, state)) { - ci.cancel(); - } - } else if (progress == -1) - levelRenderer.destroyBlockProgress(pos.hashCode(), pos, -1); - } -} diff --git a/src/main/java/com/simibubi/create/foundation/mixin/GameRendererMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/GameRendererMixin.java index bf42cb7c3..dcaa91b11 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/GameRendererMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/GameRendererMixin.java @@ -15,11 +15,9 @@ import net.minecraftforge.api.distmarker.OnlyIn; @OnlyIn(Dist.CLIENT) @Mixin(GameRenderer.class) public class GameRendererMixin { - @Inject(at = @At("TAIL"), method = "pick") private void bigShapePick(CallbackInfo ci) { BigOutlines.pick(); TrackBlockOutline.pickCurves(); } - } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/LevelRendererMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/LevelRendererMixin.java new file mode 100644 index 000000000..696240a80 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/LevelRendererMixin.java @@ -0,0 +1,69 @@ +package com.simibubi.create.foundation.mixin; + +import java.util.Set; +import java.util.SortedSet; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import com.google.common.collect.Sets; +import com.simibubi.create.foundation.block.render.BlockDestructionProgressExtension; +import com.simibubi.create.foundation.block.render.MultiPosDestructionHandler; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.renderer.LevelRenderer; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.BlockDestructionProgress; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.client.IBlockRenderProperties; +import net.minecraftforge.client.RenderProperties; + +@Mixin(LevelRenderer.class) +public class LevelRendererMixin { + @Shadow + private ClientLevel level; + + @Shadow + @Final + private Long2ObjectMap> destructionProgress; + + @Inject(method = "destroyBlockProgress(ILnet/minecraft/core/BlockPos;I)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/BlockDestructionProgress;updateTick(I)V", shift = Shift.AFTER), locals = LocalCapture.CAPTURE_FAILHARD) + private void onDestroyBlockProgress(int breakerId, BlockPos pos, int progress, CallbackInfo ci, BlockDestructionProgress progressObj) { + BlockState state = level.getBlockState(pos); + IBlockRenderProperties properties = RenderProperties.get(state); + if (properties instanceof MultiPosDestructionHandler handler) { + Set extraPositions = handler.getExtraPositions(level, pos, state, progress); + if (extraPositions != null) { + extraPositions.remove(pos); + ((BlockDestructionProgressExtension) progressObj).setExtraPositions(extraPositions); + for (BlockPos extraPos : extraPositions) { + destructionProgress.computeIfAbsent(extraPos.asLong(), l -> Sets.newTreeSet()).add(progressObj); + } + } + } + } + + @Inject(method = "removeProgress(Lnet/minecraft/server/level/BlockDestructionProgress;)V", at = @At("RETURN")) + private void onRemoveProgress(BlockDestructionProgress progress, CallbackInfo ci) { + Set extraPositions = ((BlockDestructionProgressExtension) progress).getExtraPositions(); + if (extraPositions != null) { + for (BlockPos extraPos : extraPositions) { + long l = extraPos.asLong(); + Set set = destructionProgress.get(l); + if (set != null) { + set.remove(progress); + if (set.isEmpty()) { + destructionProgress.remove(l); + } + } + } + } + } +} diff --git a/src/main/resources/create.mixins.json b/src/main/resources/create.mixins.json index beb183914..14c2d3a77 100644 --- a/src/main/resources/create.mixins.json +++ b/src/main/resources/create.mixins.json @@ -17,12 +17,13 @@ "accessor.ServerLevelAccessor" ], "client": [ + "BlockDestructionProgressMixin", "CameraMixin", - "DestroyProgressMixin", "EntityContraptionInteractionMixin", "FixNormalScalingMixin", "GameRendererMixin", "HeavyBootsOnPlayerMixin", + "LevelRendererMixin", "MapRendererMapInstanceMixin", "ModelDataRefreshMixin", "WindowResizeMixin",