mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-14 20:53:41 +01:00
Refactor multi-pos block destruction
- Replace DestroyProgressMixin with BlockDestructionProgressMixin and LevelRendererMixin - Replace DestroyProgressRenderingHandler with MultiPosDestructionHandler
This commit is contained in:
parent
b77388a8e4
commit
cf87508276
13 changed files with 156 additions and 78 deletions
|
@ -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<BeltTileEnt
|
|||
BlockPos currentPos = nextSegmentPosition(state, pos, forward);
|
||||
if (currentPos == null)
|
||||
continue;
|
||||
world.destroyBlockProgress(currentPos.hashCode(), currentPos, -1);
|
||||
BlockState currentState = world.getBlockState(currentPos);
|
||||
if (!AllBlocks.BELT.has(currentState))
|
||||
continue;
|
||||
|
@ -695,17 +695,14 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
|||
return false;
|
||||
}
|
||||
|
||||
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) {
|
||||
public Set<BlockPos> 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<DiscoveredLocation> ends = track.getConnected(reader, pos, state, false, null);
|
||||
|
|
|
@ -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<BlockPos> 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<BlockPos> getExtraPositions();
|
||||
|
||||
void setExtraPositions(@Nullable Set<BlockPos> positions);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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<BlockPos> getExtraPositions(ClientLevel level, BlockPos pos, BlockState blockState, int progress);
|
||||
}
|
|
@ -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<BlockPos> extraPositions;
|
||||
|
||||
@Override
|
||||
public Set<BlockPos> getExtraPositions() {
|
||||
return extraPositions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtraPositions(Set<BlockPos> positions) {
|
||||
extraPositions = positions;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<SortedSet<BlockDestructionProgress>> 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<BlockPos> 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<BlockPos> extraPositions = ((BlockDestructionProgressExtension) progress).getExtraPositions();
|
||||
if (extraPositions != null) {
|
||||
for (BlockPos extraPos : extraPositions) {
|
||||
long l = extraPos.asLong();
|
||||
Set<BlockDestructionProgress> set = destructionProgress.get(l);
|
||||
if (set != null) {
|
||||
set.remove(progress);
|
||||
if (set.isEmpty()) {
|
||||
destructionProgress.remove(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,12 +17,13 @@
|
|||
"accessor.ServerLevelAccessor"
|
||||
],
|
||||
"client": [
|
||||
"BlockDestructionProgressMixin",
|
||||
"CameraMixin",
|
||||
"DestroyProgressMixin",
|
||||
"EntityContraptionInteractionMixin",
|
||||
"FixNormalScalingMixin",
|
||||
"GameRendererMixin",
|
||||
"HeavyBootsOnPlayerMixin",
|
||||
"LevelRendererMixin",
|
||||
"MapRendererMapInstanceMixin",
|
||||
"ModelDataRefreshMixin",
|
||||
"WindowResizeMixin",
|
||||
|
|
Loading…
Reference in a new issue