135 lines
5.5 KiB
Java
135 lines
5.5 KiB
Java
package carpet.mixins;
|
|
|
|
import carpet.CarpetSettings;
|
|
import carpet.fakes.RedstoneWireBlockInterface;
|
|
import carpet.helpers.RedstoneWireTurbo;
|
|
import com.google.common.collect.Sets;
|
|
import org.spongepowered.asm.mixin.Mixin;
|
|
import org.spongepowered.asm.mixin.Shadow;
|
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
|
import org.spongepowered.asm.mixin.injection.At;
|
|
import org.spongepowered.asm.mixin.injection.Inject;
|
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
|
|
import java.util.Set;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.level.block.Block;
|
|
import net.minecraft.world.level.block.RedStoneWireBlock;
|
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
|
|
import static net.minecraft.world.level.block.RedStoneWireBlock.POWER;
|
|
|
|
@Mixin(RedStoneWireBlock.class)
|
|
public abstract class RedstoneWireBlock_fastMixin implements RedstoneWireBlockInterface {
|
|
|
|
@Shadow
|
|
private void updatePowerStrength(Level world_1, BlockPos blockPos_1, BlockState blockState_1) { }
|
|
|
|
@Shadow
|
|
private int calculateTargetStrength(Level world, BlockPos pos) { return 0; }
|
|
|
|
@Override
|
|
@Accessor("shouldSignal")
|
|
public abstract void setWiresGivePower(boolean wiresGivePower);
|
|
|
|
@Override
|
|
@Accessor("shouldSignal")
|
|
public abstract boolean getWiresGivePower();
|
|
|
|
// =
|
|
|
|
private RedstoneWireTurbo wireTurbo = null;
|
|
|
|
@Inject(method = "<init>", at = @At("RETURN"))
|
|
private void onRedstoneWireBlockCTOR(BlockBehaviour.Properties settings, CallbackInfo ci) {
|
|
//noinspection ConstantConditions
|
|
wireTurbo = new RedstoneWireTurbo((RedStoneWireBlock) (Object) this);
|
|
}
|
|
|
|
// =
|
|
|
|
public void fastUpdate(Level world, BlockPos pos, BlockState state, BlockPos source) {
|
|
// [CM] fastRedstoneDust -- update based on carpet rule
|
|
if (CarpetSettings.fastRedstoneDust) {
|
|
wireTurbo.updateSurroundingRedstone(world, pos, state, source);
|
|
return;
|
|
}
|
|
updatePowerStrength(world, pos, state);
|
|
}
|
|
|
|
/**
|
|
* @author theosib, soykaf, gnembon
|
|
*/
|
|
@Inject(method = "updatePowerStrength", at = @At("HEAD"), cancellable = true)
|
|
private void updateLogicAlternative(Level world, BlockPos pos, BlockState state, CallbackInfo cir) {
|
|
if (CarpetSettings.fastRedstoneDust) {
|
|
updateLogicPublic(world, pos, state);
|
|
cir.cancel();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public BlockState updateLogicPublic(Level world_1, BlockPos blockPos_1, BlockState blockState_1) {
|
|
int i = this.calculateTargetStrength(world_1, blockPos_1);
|
|
BlockState blockState = blockState_1;
|
|
if (blockState_1.getValue(POWER) != i) {
|
|
blockState_1 = blockState_1.setValue(POWER, i);
|
|
if (world_1.getBlockState(blockPos_1) == blockState) {
|
|
// [Space Walker] suppress shape updates and emit those manually to
|
|
// bypass the new neighbor update stack.
|
|
if (world_1.setBlock(blockPos_1, blockState_1, Block.UPDATE_KNOWN_SHAPE | Block.UPDATE_CLIENTS))
|
|
wireTurbo.updateNeighborShapes(world_1, blockPos_1, blockState_1);
|
|
}
|
|
|
|
if (!CarpetSettings.fastRedstoneDust) {
|
|
Set<BlockPos> set = Sets.newHashSet();
|
|
set.add(blockPos_1);
|
|
Direction[] var6 = Direction.values();
|
|
int var7 = var6.length;
|
|
|
|
for (int var8 = 0; var8 < var7; ++var8) {
|
|
Direction direction = var6[var8];
|
|
set.add(blockPos_1.relative(direction));
|
|
}
|
|
|
|
for (BlockPos blockPos : set) {
|
|
world_1.updateNeighborsAt(blockPos, blockState_1.getBlock());
|
|
}
|
|
}
|
|
}
|
|
return blockState_1;
|
|
}
|
|
|
|
// =
|
|
|
|
|
|
@Redirect(method = "onPlace", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/RedStoneWireBlock;updatePowerStrength(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)V"))
|
|
private void redirectOnBlockAddedUpdate(RedStoneWireBlock self, Level world_1, BlockPos blockPos_1, BlockState blockState_1) {
|
|
fastUpdate(world_1, blockPos_1, blockState_1, null);
|
|
}
|
|
|
|
@Redirect(method = "onRemove", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/RedStoneWireBlock;updatePowerStrength(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)V"))
|
|
private void redirectOnStateReplacedUpdate(RedStoneWireBlock self, Level world_1, BlockPos blockPos_1, BlockState blockState_1) {
|
|
fastUpdate(world_1, blockPos_1, blockState_1, null);
|
|
}
|
|
|
|
@Redirect(method = "neighborChanged", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/RedStoneWireBlock;updatePowerStrength(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)V"))
|
|
private void redirectNeighborUpdateUpdate(
|
|
RedStoneWireBlock self,
|
|
Level world_1,
|
|
BlockPos blockPos_1,
|
|
BlockState blockState_1,
|
|
BlockState blockState_2,
|
|
Level world_2,
|
|
BlockPos blockPos_2,
|
|
Block block_1,
|
|
BlockPos blockPos_3,
|
|
boolean boolean_1) {
|
|
fastUpdate(world_1, blockPos_1, blockState_1, blockPos_3);
|
|
}
|
|
}
|