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

View file

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

View file

@ -34,12 +34,13 @@ public class RedstoneLinkBlock extends ProperDirectionalBlock implements ITE<Red
public RedstoneLinkBlock(Properties properties) { public RedstoneLinkBlock(Properties properties) {
super(properties); super(properties);
setDefaultState(getDefaultState().with(POWERED, false).with(RECEIVER, false)); setDefaultState(getDefaultState().with(POWERED, false)
.with(RECEIVER, false));
} }
@Override @Override
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
boolean isMoving) { boolean isMoving) {
Direction blockFacing = state.get(FACING); Direction blockFacing = state.get(FACING);
if (fromPos.equals(pos.offset(blockFacing.getOpposite()))) { if (fromPos.equals(pos.offset(blockFacing.getOpposite()))) {
@ -63,19 +64,23 @@ public class RedstoneLinkBlock extends ProperDirectionalBlock implements ITE<Red
if (state.get(RECEIVER)) if (state.get(RECEIVER))
return; return;
boolean shouldPower = worldIn.getWorld().isBlockPowered(pos); int power = getPower(worldIn, pos);
for (Direction direction : Iterate.directions) {
BlockPos blockpos = pos.offset(direction);
shouldPower |= worldIn.getRedstonePower(blockpos, Direction.UP) > 0;
}
boolean previouslyPowered = state.get(POWERED); boolean previouslyPowered = state.get(POWERED);
if (previouslyPowered != power > 0)
if (previouslyPowered != shouldPower) {
worldIn.setBlockState(pos, state.cycle(POWERED), 2); 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 @Override
@ -94,7 +99,12 @@ public class RedstoneLinkBlock extends ProperDirectionalBlock implements ITE<Red
public int getWeakPower(BlockState state, IBlockReader blockAccess, BlockPos pos, Direction side) { public int getWeakPower(BlockState state, IBlockReader blockAccess, BlockPos pos, Direction side) {
if (!state.get(RECEIVER)) if (!state.get(RECEIVER))
return 0; return 0;
return state.get(POWERED) ? 15 : 0; try {
RedstoneLinkTileEntity tileEntity = getTileEntity(blockAccess, pos);
return tileEntity.getReceivedSignal();
} catch (TileEntityException e) {
}
return 0;
} }
@Override @Override
@ -115,7 +125,7 @@ public class RedstoneLinkBlock extends ProperDirectionalBlock implements ITE<Red
@Override @Override
public ActionResultType onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, public ActionResultType onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
BlockRayTraceResult hit) { BlockRayTraceResult hit) {
if (player.isSneaking()) if (player.isSneaking())
return toggleMode(state, worldIn, pos); return toggleMode(state, worldIn, pos);
return ActionResultType.PASS; return ActionResultType.PASS;
@ -128,13 +138,12 @@ public class RedstoneLinkBlock extends ProperDirectionalBlock implements ITE<Red
RedstoneLinkTileEntity te = getTileEntity(worldIn, pos); RedstoneLinkTileEntity te = getTileEntity(worldIn, pos);
Boolean wasReceiver = state.get(RECEIVER); Boolean wasReceiver = state.get(RECEIVER);
boolean blockPowered = worldIn.isBlockPowered(pos); boolean blockPowered = worldIn.isBlockPowered(pos);
worldIn.setBlockState(pos, state.cycle(RECEIVER).with(POWERED, blockPowered), 3); worldIn.setBlockState(pos, state.cycle(RECEIVER)
if (wasReceiver) { .with(POWERED, blockPowered), 3);
te.transmit(worldIn.isBlockPowered(pos)); te.transmit(wasReceiver ? 0 : getPower(worldIn, pos));
} else
te.transmit(false);
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
} catch (TileEntityException e) {} } catch (TileEntityException e) {
}
return ActionResultType.PASS; return ActionResultType.PASS;
} }
@ -152,7 +161,8 @@ public class RedstoneLinkBlock extends ProperDirectionalBlock implements ITE<Red
@Override @Override
public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) { 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); BlockState neighbour = worldIn.getBlockState(neighbourPos);
return Block.hasSolidSide(neighbour, worldIn, neighbourPos, state.get(FACING)); 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 { public class RedstoneLinkTileEntity extends SmartTileEntity {
private boolean receivedSignal; private boolean receivedSignalChanged;
private boolean transmittedSignal; private int receivedSignal;
private int transmittedSignal;
private LinkBehaviour link; private LinkBehaviour link;
private boolean transmitter; private boolean transmitter;
@ -46,16 +47,18 @@ public class RedstoneLinkTileEntity extends SmartTileEntity {
: LinkBehaviour.receiver(this, slots, this::setSignal); : LinkBehaviour.receiver(this, slots, this::setSignal);
} }
public boolean getSignal() { public int getSignal() {
return transmittedSignal; return transmittedSignal;
} }
public void setSignal(boolean powered) { public void setSignal(int power) {
receivedSignal = powered; if (receivedSignal != power)
receivedSignalChanged = true;
receivedSignal = power;
} }
public void transmit(boolean signal) { public void transmit(int strength) {
transmittedSignal = signal; transmittedSignal = strength;
if (link != null) if (link != null)
link.notifySignalChange(); link.notifySignalChange();
} }
@ -63,8 +66,9 @@ public class RedstoneLinkTileEntity extends SmartTileEntity {
@Override @Override
public CompoundNBT write(CompoundNBT compound) { public CompoundNBT write(CompoundNBT compound) {
compound.putBoolean("Transmitter", transmitter); compound.putBoolean("Transmitter", transmitter);
compound.putBoolean("Receive", receivedSignal); compound.putInt("Receive", getReceivedSignal());
compound.putBoolean("Transmit", transmittedSignal); compound.putBoolean("ReceivedChanged", receivedSignalChanged);
compound.putInt("Transmit", transmittedSignal);
return super.write(compound); return super.write(compound);
} }
@ -73,9 +77,10 @@ public class RedstoneLinkTileEntity extends SmartTileEntity {
transmitter = compound.getBoolean("Transmitter"); transmitter = compound.getBoolean("Transmitter");
super.read(compound); super.read(compound);
receivedSignal = compound.getBoolean("Receive"); receivedSignal = compound.getInt("Receive");
receivedSignalChanged = compound.getBoolean("ReceivedChanged");
if (world == null || world.isRemote || !link.newPosition) if (world == null || world.isRemote || !link.newPosition)
transmittedSignal = compound.getBoolean("Transmit"); transmittedSignal = compound.getInt("Transmit");
} }
@Override @Override
@ -95,16 +100,21 @@ public class RedstoneLinkTileEntity extends SmartTileEntity {
return; return;
if (world.isRemote) if (world.isRemote)
return; return;
BlockState blockState = getBlockState(); BlockState blockState = getBlockState();
if (!AllBlocks.REDSTONE_LINK.has(blockState)) if (!AllBlocks.REDSTONE_LINK.has(blockState))
return; return;
if (receivedSignal != blockState.get(POWERED)) { if ((getReceivedSignal() > 0) != blockState.get(POWERED)) {
receivedSignalChanged = true;
world.setBlockState(pos, blockState.cycle(POWERED)); world.setBlockState(pos, blockState.cycle(POWERED));
}
if (receivedSignalChanged) {
Direction attachedFace = blockState.get(RedstoneLinkBlock.FACING).getOpposite(); Direction attachedFace = blockState.get(RedstoneLinkBlock.FACING).getOpposite();
BlockPos attachedPos = pos.offset(attachedFace); BlockPos attachedPos = pos.offset(attachedFace);
world.notifyNeighbors(pos, world.getBlockState(pos).getBlock());
world.notifyNeighbors(attachedPos, world.getBlockState(attachedPos).getBlock()); world.notifyNeighbors(attachedPos, world.getBlockState(attachedPos).getBlock());
return;
} }
} }
@ -112,4 +122,8 @@ public class RedstoneLinkTileEntity extends SmartTileEntity {
return !getBlockState().get(RedstoneLinkBlock.RECEIVER); return !getBlockState().get(RedstoneLinkBlock.RECEIVER);
} }
public int getReceivedSignal() {
return receivedSignal;
}
} }

View file

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

View file

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