Analog Redstone Links

- Redstone link receivers now emit their signal with the level of the strongest transmitter of the same frequency
This commit is contained in:
simibubi 2020-06-04 15:33:56 +02:00
parent 82a2d128f1
commit 82ed9cd85d
6 changed files with 83 additions and 56 deletions

View file

@ -86,7 +86,7 @@ public class RedstoneLinkNetworkHandler {
public void updateNetworkOf(LinkBehaviour actor) {
Set<LinkBehaviour> network = getNetworkOf(actor);
boolean powered = false;
int power = 0;
for (Iterator<LinkBehaviour> iterator = network.iterator(); iterator.hasNext();) {
LinkBehaviour other = iterator.next();
@ -105,10 +105,9 @@ public class RedstoneLinkNetworkHandler {
}
if (!withinRange(actor, other))
continue;
if (other.isTransmitting()) {
powered = true;
power = Math.max(other.getTransmittedStrength(), power);
if (power == 15)
break;
}
}
for (Iterator<LinkBehaviour> iterator = network.iterator(); iterator.hasNext();) {
@ -120,7 +119,7 @@ public class RedstoneLinkNetworkHandler {
if (!withinRange(actor, other))
continue;
if (other.isListening())
other.updateReceiver(powered);
other.updateReceiver(power);
}
}

View file

@ -29,8 +29,8 @@ public class LinkedExtractorTileEntity extends ExtractorTileEntity {
super.addBehaviours(behaviours);
}
public void setSignal(boolean powered) {
receivedSignal = powered;
public void setSignal(int powered) {
receivedSignal = powered > 0;
}
@Override

View file

@ -34,12 +34,13 @@ public class RedstoneLinkBlock extends ProperDirectionalBlock implements ITE<Red
public RedstoneLinkBlock(Properties properties) {
super(properties);
setDefaultState(getDefaultState().with(POWERED, false).with(RECEIVER, false));
setDefaultState(getDefaultState().with(POWERED, false)
.with(RECEIVER, false));
}
@Override
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
boolean isMoving) {
boolean isMoving) {
Direction blockFacing = state.get(FACING);
if (fromPos.equals(pos.offset(blockFacing.getOpposite()))) {
@ -63,19 +64,23 @@ public class RedstoneLinkBlock extends ProperDirectionalBlock implements ITE<Red
if (state.get(RECEIVER))
return;
boolean shouldPower = worldIn.getWorld().isBlockPowered(pos);
for (Direction direction : Iterate.directions) {
BlockPos blockpos = pos.offset(direction);
shouldPower |= worldIn.getRedstonePower(blockpos, Direction.UP) > 0;
}
int power = getPower(worldIn, pos);
boolean previouslyPowered = state.get(POWERED);
if (previouslyPowered != shouldPower) {
if (previouslyPowered != power > 0)
worldIn.setBlockState(pos, state.cycle(POWERED), 2);
withTileEntityDo(worldIn, pos, te -> te.transmit(!previouslyPowered));
}
int transmit = power;
withTileEntityDo(worldIn, pos, te -> te.transmit(transmit));
}
private int getPower(World worldIn, BlockPos pos) {
int power = 0;
for (Direction direction : Iterate.directions)
power = Math.max(worldIn.getRedstonePower(pos.offset(direction), direction), power);
for (Direction direction : Iterate.directions)
power = Math.max(worldIn.getRedstonePower(pos.offset(direction), Direction.UP), power);
return power;
}
@Override
@ -94,7 +99,12 @@ public class RedstoneLinkBlock extends ProperDirectionalBlock implements ITE<Red
public int getWeakPower(BlockState state, IBlockReader blockAccess, BlockPos pos, Direction side) {
if (!state.get(RECEIVER))
return 0;
return state.get(POWERED) ? 15 : 0;
try {
RedstoneLinkTileEntity tileEntity = getTileEntity(blockAccess, pos);
return tileEntity.getReceivedSignal();
} catch (TileEntityException e) {
}
return 0;
}
@Override
@ -115,7 +125,7 @@ public class RedstoneLinkBlock extends ProperDirectionalBlock implements ITE<Red
@Override
public ActionResultType onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
BlockRayTraceResult hit) {
BlockRayTraceResult hit) {
if (player.isSneaking())
return toggleMode(state, worldIn, pos);
return ActionResultType.PASS;
@ -128,13 +138,12 @@ public class RedstoneLinkBlock extends ProperDirectionalBlock implements ITE<Red
RedstoneLinkTileEntity te = getTileEntity(worldIn, pos);
Boolean wasReceiver = state.get(RECEIVER);
boolean blockPowered = worldIn.isBlockPowered(pos);
worldIn.setBlockState(pos, state.cycle(RECEIVER).with(POWERED, blockPowered), 3);
if (wasReceiver) {
te.transmit(worldIn.isBlockPowered(pos));
} else
te.transmit(false);
worldIn.setBlockState(pos, state.cycle(RECEIVER)
.with(POWERED, blockPowered), 3);
te.transmit(wasReceiver ? 0 : getPower(worldIn, pos));
return ActionResultType.SUCCESS;
} catch (TileEntityException e) {}
} catch (TileEntityException e) {
}
return ActionResultType.PASS;
}
@ -152,7 +161,8 @@ public class RedstoneLinkBlock extends ProperDirectionalBlock implements ITE<Red
@Override
public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) {
BlockPos neighbourPos = pos.offset(state.get(FACING).getOpposite());
BlockPos neighbourPos = pos.offset(state.get(FACING)
.getOpposite());
BlockState neighbour = worldIn.getBlockState(neighbourPos);
return Block.hasSolidSide(neighbour, worldIn, neighbourPos, state.get(FACING));
}

View file

@ -20,8 +20,9 @@ import net.minecraft.util.math.BlockPos;
public class RedstoneLinkTileEntity extends SmartTileEntity {
private boolean receivedSignal;
private boolean transmittedSignal;
private boolean receivedSignalChanged;
private int receivedSignal;
private int transmittedSignal;
private LinkBehaviour link;
private boolean transmitter;
@ -46,16 +47,18 @@ public class RedstoneLinkTileEntity extends SmartTileEntity {
: LinkBehaviour.receiver(this, slots, this::setSignal);
}
public boolean getSignal() {
public int getSignal() {
return transmittedSignal;
}
public void setSignal(boolean powered) {
receivedSignal = powered;
public void setSignal(int power) {
if (receivedSignal != power)
receivedSignalChanged = true;
receivedSignal = power;
}
public void transmit(boolean signal) {
transmittedSignal = signal;
public void transmit(int strength) {
transmittedSignal = strength;
if (link != null)
link.notifySignalChange();
}
@ -63,8 +66,9 @@ public class RedstoneLinkTileEntity extends SmartTileEntity {
@Override
public CompoundNBT write(CompoundNBT compound) {
compound.putBoolean("Transmitter", transmitter);
compound.putBoolean("Receive", receivedSignal);
compound.putBoolean("Transmit", transmittedSignal);
compound.putInt("Receive", getReceivedSignal());
compound.putBoolean("ReceivedChanged", receivedSignalChanged);
compound.putInt("Transmit", transmittedSignal);
return super.write(compound);
}
@ -73,9 +77,10 @@ public class RedstoneLinkTileEntity extends SmartTileEntity {
transmitter = compound.getBoolean("Transmitter");
super.read(compound);
receivedSignal = compound.getBoolean("Receive");
receivedSignal = compound.getInt("Receive");
receivedSignalChanged = compound.getBoolean("ReceivedChanged");
if (world == null || world.isRemote || !link.newPosition)
transmittedSignal = compound.getBoolean("Transmit");
transmittedSignal = compound.getInt("Transmit");
}
@Override
@ -95,16 +100,21 @@ public class RedstoneLinkTileEntity extends SmartTileEntity {
return;
if (world.isRemote)
return;
BlockState blockState = getBlockState();
if (!AllBlocks.REDSTONE_LINK.has(blockState))
return;
if (receivedSignal != blockState.get(POWERED)) {
if ((getReceivedSignal() > 0) != blockState.get(POWERED)) {
receivedSignalChanged = true;
world.setBlockState(pos, blockState.cycle(POWERED));
}
if (receivedSignalChanged) {
Direction attachedFace = blockState.get(RedstoneLinkBlock.FACING).getOpposite();
BlockPos attachedPos = pos.offset(attachedFace);
world.notifyNeighbors(pos, world.getBlockState(pos).getBlock());
world.notifyNeighbors(attachedPos, world.getBlockState(attachedPos).getBlock());
return;
}
}
@ -112,4 +122,8 @@ public class RedstoneLinkTileEntity extends SmartTileEntity {
return !getBlockState().get(RedstoneLinkBlock.RECEIVER);
}
public int getReceivedSignal() {
return receivedSignal;
}
}

View file

@ -30,8 +30,8 @@ public class LinkedTransposerTileEntity extends TransposerTileEntity {
super.addBehaviours(behaviours);
}
public void setSignal(boolean powered) {
receivedSignal = powered;
public void setSignal(int powered) {
receivedSignal = powered > 0;
}
@Override

View file

@ -36,8 +36,8 @@ public class LinkBehaviour extends TileEntityBehaviour {
public boolean newPosition;
private Mode mode;
private Supplier<Boolean> transmission;
private Consumer<Boolean> signalCallback;
private Supplier<Integer> transmission;
private Consumer<Integer> signalCallback;
protected LinkBehaviour(SmartTileEntity te, Pair<ValueBoxTransform, ValueBoxTransform> slots) {
super(te);
@ -50,7 +50,7 @@ public class LinkBehaviour extends TileEntityBehaviour {
}
public static LinkBehaviour receiver(SmartTileEntity te, Pair<ValueBoxTransform, ValueBoxTransform> slots,
Consumer<Boolean> signalCallback) {
Consumer<Integer> signalCallback) {
LinkBehaviour behaviour = new LinkBehaviour(te, slots);
behaviour.signalCallback = signalCallback;
behaviour.mode = Mode.RECEIVE;
@ -58,7 +58,7 @@ public class LinkBehaviour extends TileEntityBehaviour {
}
public static LinkBehaviour transmitter(SmartTileEntity te, Pair<ValueBoxTransform, ValueBoxTransform> slots,
Supplier<Boolean> transmission) {
Supplier<Integer> transmission) {
LinkBehaviour behaviour = new LinkBehaviour(te, slots);
behaviour.transmission = transmission;
behaviour.mode = Mode.TRANSMIT;
@ -81,14 +81,14 @@ public class LinkBehaviour extends TileEntityBehaviour {
return mode == Mode.RECEIVE;
}
public boolean isTransmitting() {
return mode == Mode.TRANSMIT && transmission.get();
public int getTransmittedStrength() {
return mode == Mode.TRANSMIT ? transmission.get() : 0;
}
public void updateReceiver(boolean networkPowered) {
public void updateReceiver(int networkPower) {
if (!newPosition)
return;
signalCallback.accept(networkPowered);
signalCallback.accept(networkPower);
}
public void notifySignalChange() {
@ -119,14 +119,18 @@ public class LinkBehaviour extends TileEntityBehaviour {
@Override
public void writeNBT(CompoundNBT compound) {
super.writeNBT(compound);
compound.put("FrequencyFirst", frequencyFirst.getStack().write(new CompoundNBT()));
compound.put("FrequencyLast", frequencyLast.getStack().write(new CompoundNBT()));
compound.putLong("LastKnownPosition", tileEntity.getPos().toLong());
compound.put("FrequencyFirst", frequencyFirst.getStack()
.write(new CompoundNBT()));
compound.put("FrequencyLast", frequencyLast.getStack()
.write(new CompoundNBT()));
compound.putLong("LastKnownPosition", tileEntity.getPos()
.toLong());
}
@Override
public void readNBT(CompoundNBT compound) {
long positionInTag = tileEntity.getPos().toLong();
long positionInTag = tileEntity.getPos()
.toLong();
long positionKey = compound.getLong("LastKnownPosition");
newPosition = positionInTag != positionKey;
@ -172,7 +176,7 @@ public class LinkBehaviour extends TileEntityBehaviour {
float scale;
public SlotPositioning(Function<BlockState, Pair<Vec3d, Vec3d>> offsetsForState,
Function<BlockState, Vec3d> rotationForState) {
Function<BlockState, Vec3d> rotationForState) {
offsets = offsetsForState;
rotation = rotationForState;
scale = 1;