mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-02-05 09:54:59 +01:00
Signal the Signal
- Changed redstone output type of signals to comparator - Redstone powered signals are now forced to red - Redstone powered signals now add a substantial path cost - Increased render distance of signal nixie details
This commit is contained in:
parent
c1f0ab8d1a
commit
8c444f1476
8 changed files with 141 additions and 63 deletions
|
@ -495,7 +495,7 @@ e815bfd854c2653f10828bb11950f7fb991d7efc assets/create/blockstates/stressometer.
|
||||||
a2454400b1cf9889f70aebdc89c52a1be25f543c assets/create/blockstates/tiled_glass_pane.json
|
a2454400b1cf9889f70aebdc89c52a1be25f543c assets/create/blockstates/tiled_glass_pane.json
|
||||||
96c45abe7a5d9273feaf5f747d14cee8e04b58da assets/create/blockstates/track.json
|
96c45abe7a5d9273feaf5f747d14cee8e04b58da assets/create/blockstates/track.json
|
||||||
98b936d72da49ee02eacd0b3244fe133e5575bb1 assets/create/blockstates/track_observer.json
|
98b936d72da49ee02eacd0b3244fe133e5575bb1 assets/create/blockstates/track_observer.json
|
||||||
408ae1009ee8bb2f2b83753d5909c53744f7865f assets/create/blockstates/track_signal.json
|
2bc61c806a9a903c139a79d4d296c119d9f590b2 assets/create/blockstates/track_signal.json
|
||||||
60609cfbcc9be6f7e41fb493ef3147beb9750b60 assets/create/blockstates/track_station.json
|
60609cfbcc9be6f7e41fb493ef3147beb9750b60 assets/create/blockstates/track_station.json
|
||||||
b000a6cde143f8a12fc8996d1ac8b5164f75253b assets/create/blockstates/train_door.json
|
b000a6cde143f8a12fc8996d1ac8b5164f75253b assets/create/blockstates/train_door.json
|
||||||
836c443ab8778f0ff2b16bdf5f3339a0871c273e assets/create/blockstates/train_trapdoor.json
|
836c443ab8778f0ff2b16bdf5f3339a0871c273e assets/create/blockstates/train_trapdoor.json
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
{
|
{
|
||||||
"variants": {
|
"variants": {
|
||||||
"type=entry_signal": {
|
"powered=false,type=entry_signal": {
|
||||||
"model": "create:block/track_signal/block_entry_signal"
|
"model": "create:block/track_signal/block_entry_signal"
|
||||||
},
|
},
|
||||||
"type=cross_signal": {
|
"powered=true,type=entry_signal": {
|
||||||
|
"model": "create:block/track_signal/block_entry_signal"
|
||||||
|
},
|
||||||
|
"powered=false,type=cross_signal": {
|
||||||
|
"model": "create:block/track_signal/block_cross_signal"
|
||||||
|
},
|
||||||
|
"powered=true,type=cross_signal": {
|
||||||
"model": "create:block/track_signal/block_cross_signal"
|
"model": "create:block/track_signal/block_cross_signal"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,7 +160,7 @@ public class NixieTubeRenderer extends SafeTileEntityRenderer<NixieTubeTileEntit
|
||||||
ms.pushPose();
|
ms.pushPose();
|
||||||
ms.translate(flip ? 4 / 16f : -4 / 16f, 0, 0);
|
ms.translate(flip ? 4 / 16f : -4 / 16f, 0, 0);
|
||||||
|
|
||||||
if (diff.lengthSqr() < 36 * 36) {
|
if (diff.lengthSqr() < 96 * 96) {
|
||||||
boolean vert = first ^ facing.getAxis()
|
boolean vert = first ^ facing.getAxis()
|
||||||
.isHorizontal();
|
.isHorizontal();
|
||||||
float longSide = yellow ? 1 : 4;
|
float longSide = yellow ? 1 : 4;
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class Navigation {
|
||||||
|
|
||||||
private TravellingPoint signalScout;
|
private TravellingPoint signalScout;
|
||||||
public Pair<UUID, Boolean> waitingForSignal;
|
public Pair<UUID, Boolean> waitingForSignal;
|
||||||
private Map<UUID, SignalBoundary> waitingForChainedGroups;
|
private Map<UUID, Pair<SignalBoundary, Boolean>> waitingForChainedGroups;
|
||||||
public double distanceToSignal;
|
public double distanceToSignal;
|
||||||
public int ticksWaitingForSignal;
|
public int ticksWaitingForSignal;
|
||||||
|
|
||||||
|
@ -158,13 +158,14 @@ public class Navigation {
|
||||||
|
|
||||||
boolean primary = entering.equals(signal.groups.getFirst());
|
boolean primary = entering.equals(signal.groups.getFirst());
|
||||||
boolean crossSignal = signal.types.get(primary) == SignalType.CROSS_SIGNAL;
|
boolean crossSignal = signal.types.get(primary) == SignalType.CROSS_SIGNAL;
|
||||||
boolean occupied = signalEdgeGroup.isOccupiedUnless(train);
|
boolean occupied =
|
||||||
|
signal.isForcedRed(nodes.getSecond()) || signalEdgeGroup.isOccupiedUnless(train);
|
||||||
|
|
||||||
if (!crossSignalTracked) {
|
if (!crossSignalTracked) {
|
||||||
if (crossSignal) { // Now entering cross signal path
|
if (crossSignal) { // Now entering cross signal path
|
||||||
trackingCrossSignal.setValue(Pair.of(boundary.id, primary));
|
trackingCrossSignal.setValue(Pair.of(boundary.id, primary));
|
||||||
crossSignalDistanceTracker.setValue(distance);
|
crossSignalDistanceTracker.setValue(distance);
|
||||||
waitingForChainedGroups.put(entering, signal);
|
waitingForChainedGroups.put(entering, Pair.of(signal, primary));
|
||||||
}
|
}
|
||||||
if (occupied) { // Section is occupied
|
if (occupied) { // Section is occupied
|
||||||
waitingForSignal = Pair.of(boundary.id, primary);
|
waitingForSignal = Pair.of(boundary.id, primary);
|
||||||
|
@ -179,7 +180,7 @@ public class Navigation {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crossSignalTracked) {
|
if (crossSignalTracked) {
|
||||||
waitingForChainedGroups.put(entering, signal); // Add group to chain
|
waitingForChainedGroups.put(entering, Pair.of(signal, primary)); // Add group to chain
|
||||||
if (occupied) { // Section is occupied, but wait at the cross signal that started the chain
|
if (occupied) { // Section is occupied, but wait at the cross signal that started the chain
|
||||||
waitingForSignal = trackingCrossSignal.getValue();
|
waitingForSignal = trackingCrossSignal.getValue();
|
||||||
distanceToSignal = crossSignalDistanceTracker.doubleValue();
|
distanceToSignal = crossSignalDistanceTracker.doubleValue();
|
||||||
|
@ -272,7 +273,7 @@ public class Navigation {
|
||||||
waitingForChainedGroups.forEach((groupId, boundary) -> {
|
waitingForChainedGroups.forEach((groupId, boundary) -> {
|
||||||
SignalEdgeGroup signalEdgeGroup = Create.RAILWAYS.signalEdgeGroups.get(groupId);
|
SignalEdgeGroup signalEdgeGroup = Create.RAILWAYS.signalEdgeGroups.get(groupId);
|
||||||
if (signalEdgeGroup != null)
|
if (signalEdgeGroup != null)
|
||||||
signalEdgeGroup.reserved = boundary;
|
signalEdgeGroup.reserved = boundary.getFirst();
|
||||||
});
|
});
|
||||||
waitingForChainedGroups.clear();
|
waitingForChainedGroups.clear();
|
||||||
}
|
}
|
||||||
|
@ -286,12 +287,18 @@ public class Navigation {
|
||||||
|
|
||||||
// Cross Signal
|
// Cross Signal
|
||||||
if (signal.types.get(waitingForSignal.getSecond()) == SignalType.CROSS_SIGNAL) {
|
if (signal.types.get(waitingForSignal.getSecond()) == SignalType.CROSS_SIGNAL) {
|
||||||
for (UUID groupId : waitingForChainedGroups.keySet()) {
|
for (Entry<UUID, Pair<SignalBoundary, Boolean>> entry : waitingForChainedGroups.entrySet()) {
|
||||||
SignalEdgeGroup signalEdgeGroup = Create.RAILWAYS.signalEdgeGroups.get(groupId);
|
Pair<SignalBoundary, Boolean> boundary = entry.getValue();
|
||||||
|
SignalEdgeGroup signalEdgeGroup = Create.RAILWAYS.signalEdgeGroups.get(entry.getKey());
|
||||||
if (signalEdgeGroup == null) { // Migration, re-initialize chain
|
if (signalEdgeGroup == null) { // Migration, re-initialize chain
|
||||||
waitingForSignal.setFirst(null);
|
waitingForSignal.setFirst(null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (boundary.getFirst()
|
||||||
|
.isForcedRed(boundary.getSecond())) {
|
||||||
|
train.reservedSignalBlocks.clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (signalEdgeGroup.isOccupiedUnless(train))
|
if (signalEdgeGroup.isOccupiedUnless(train))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -607,6 +614,10 @@ public class Navigation {
|
||||||
if (!point.canNavigateVia(node2))
|
if (!point.canNavigateVia(node2))
|
||||||
continue Search;
|
continue Search;
|
||||||
if (point instanceof SignalBoundary signal) {
|
if (point instanceof SignalBoundary signal) {
|
||||||
|
if (signal.isForcedRed(node2)) {
|
||||||
|
penalty += Train.Penalties.REDSTONE_RED_SIGNAL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
UUID group = signal.getGroup(node2);
|
UUID group = signal.getGroup(node2);
|
||||||
if (group == null)
|
if (group == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -989,7 +989,7 @@ public class Train {
|
||||||
public static class Penalties {
|
public static class Penalties {
|
||||||
static final int STATION = 200, STATION_WITH_TRAIN = 300;
|
static final int STATION = 200, STATION_WITH_TRAIN = 300;
|
||||||
static final int MANUAL_TRAIN = 200, IDLE_TRAIN = 700, ARRIVING_TRAIN = 50, WAITING_TRAIN = 50, ANY_TRAIN = 25,
|
static final int MANUAL_TRAIN = 200, IDLE_TRAIN = 700, ARRIVING_TRAIN = 50, WAITING_TRAIN = 50, ANY_TRAIN = 25,
|
||||||
RED_SIGNAL = 25;
|
RED_SIGNAL = 25, REDSTONE_RED_SIGNAL = 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNavigationPenalty() {
|
public int getNavigationPenalty() {
|
||||||
|
|
|
@ -2,6 +2,8 @@ package com.simibubi.create.content.logistics.trains.management.edgePoint.signal
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.simibubi.create.AllTileEntities;
|
import com.simibubi.create.AllTileEntities;
|
||||||
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
|
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
|
||||||
import com.simibubi.create.foundation.block.ITE;
|
import com.simibubi.create.foundation.block.ITE;
|
||||||
|
@ -13,18 +15,22 @@ import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.util.StringRepresentable;
|
import net.minecraft.util.StringRepresentable;
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||||
import net.minecraft.world.item.context.UseOnContext;
|
import net.minecraft.world.item.context.UseOnContext;
|
||||||
import net.minecraft.world.level.BlockGetter;
|
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.LevelReader;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.block.state.StateDefinition.Builder;
|
import net.minecraft.world.level.block.state.StateDefinition.Builder;
|
||||||
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||||
|
|
||||||
public class SignalBlock extends Block implements ITE<SignalTileEntity>, IWrenchable {
|
public class SignalBlock extends Block implements ITE<SignalTileEntity>, IWrenchable {
|
||||||
|
|
||||||
public static final EnumProperty<SignalType> TYPE = EnumProperty.create("type", SignalType.class);
|
public static final EnumProperty<SignalType> TYPE = EnumProperty.create("type", SignalType.class);
|
||||||
|
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
|
||||||
|
|
||||||
public enum SignalType implements StringRepresentable {
|
public enum SignalType implements StringRepresentable {
|
||||||
ENTRY_SIGNAL, CROSS_SIGNAL;
|
ENTRY_SIGNAL, CROSS_SIGNAL;
|
||||||
|
@ -37,7 +43,8 @@ public class SignalBlock extends Block implements ITE<SignalTileEntity>, IWrench
|
||||||
|
|
||||||
public SignalBlock(Properties p_53182_) {
|
public SignalBlock(Properties p_53182_) {
|
||||||
super(p_53182_);
|
super(p_53182_);
|
||||||
registerDefaultState(defaultBlockState().setValue(TYPE, SignalType.ENTRY_SIGNAL));
|
registerDefaultState(defaultBlockState().setValue(TYPE, SignalType.ENTRY_SIGNAL)
|
||||||
|
.setValue(POWERED, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -47,7 +54,41 @@ public class SignalBlock extends Block implements ITE<SignalTileEntity>, IWrench
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void createBlockStateDefinition(Builder<Block, BlockState> pBuilder) {
|
protected void createBlockStateDefinition(Builder<Block, BlockState> pBuilder) {
|
||||||
super.createBlockStateDefinition(pBuilder.add(TYPE));
|
super.createBlockStateDefinition(pBuilder.add(TYPE, POWERED));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public BlockState getStateForPlacement(BlockPlaceContext pContext) {
|
||||||
|
return this.defaultBlockState()
|
||||||
|
.setValue(POWERED, Boolean.valueOf(pContext.getLevel()
|
||||||
|
.hasNeighborSignal(pContext.getClickedPos())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void neighborChanged(BlockState pState, Level pLevel, BlockPos pPos, Block pBlock, BlockPos pFromPos,
|
||||||
|
boolean pIsMoving) {
|
||||||
|
if (pLevel.isClientSide)
|
||||||
|
return;
|
||||||
|
boolean powered = pState.getValue(POWERED);
|
||||||
|
if (powered == pLevel.hasNeighborSignal(pPos))
|
||||||
|
return;
|
||||||
|
if (powered) {
|
||||||
|
pLevel.scheduleTick(pPos, this, 4);
|
||||||
|
} else {
|
||||||
|
pLevel.setBlock(pPos, pState.cycle(POWERED), 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(BlockState pState, ServerLevel pLevel, BlockPos pPos, Random pRand) {
|
||||||
|
if (pState.getValue(POWERED) && !pLevel.hasNeighborSignal(pPos))
|
||||||
|
pLevel.setBlock(pPos, pState.cycle(POWERED), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -76,23 +117,13 @@ public class SignalBlock extends Block implements ITE<SignalTileEntity>, IWrench
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canConnectRedstone(BlockState state, BlockGetter world, BlockPos pos, Direction side) {
|
public boolean hasAnalogOutputSignal(BlockState pState) {
|
||||||
return side != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSignalSource(BlockState state) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(BlockState blockState, ServerLevel world, BlockPos pos, Random random) {
|
public int getAnalogOutputSignal(BlockState pState, Level blockAccess, BlockPos pPos) {
|
||||||
getTileEntityOptional(world, pos).ifPresent(SignalTileEntity::updatePowerAfterDelay);
|
return getTileEntityOptional(blockAccess, pPos).filter(SignalTileEntity::isPowered)
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
|
|
||||||
return getTileEntityOptional(blockAccess, pos).filter(SignalTileEntity::isPowered)
|
|
||||||
.map($ -> 15)
|
.map($ -> 15)
|
||||||
.orElse(0);
|
.orElse(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package com.simibubi.create.content.logistics.trains.management.edgePoint.signal;
|
package com.simibubi.create.content.logistics.trains.management.edgePoint.signal;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
|
@ -29,7 +28,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
|
||||||
public class SignalBoundary extends TrackEdgePoint {
|
public class SignalBoundary extends TrackEdgePoint {
|
||||||
|
|
||||||
public Couple<Set<BlockPos>> blockEntities;
|
public Couple<Map<BlockPos, Boolean>> blockEntities;
|
||||||
public Couple<SignalType> types;
|
public Couple<SignalType> types;
|
||||||
public Couple<UUID> groups;
|
public Couple<UUID> groups;
|
||||||
public Couple<Boolean> sidesToUpdate;
|
public Couple<Boolean> sidesToUpdate;
|
||||||
|
@ -38,7 +37,7 @@ public class SignalBoundary extends TrackEdgePoint {
|
||||||
private Couple<Map<UUID, Boolean>> chainedSignals;
|
private Couple<Map<UUID, Boolean>> chainedSignals;
|
||||||
|
|
||||||
public SignalBoundary() {
|
public SignalBoundary() {
|
||||||
blockEntities = Couple.create(HashSet::new);
|
blockEntities = Couple.create(HashMap::new);
|
||||||
chainedSignals = Couple.create(null, null);
|
chainedSignals = Couple.create(null, null);
|
||||||
groups = Couple.create(null, null);
|
groups = Couple.create(null, null);
|
||||||
sidesToUpdate = Couple.create(true, true);
|
sidesToUpdate = Couple.create(true, true);
|
||||||
|
@ -83,7 +82,8 @@ public class SignalBoundary extends TrackEdgePoint {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidate(LevelAccessor level) {
|
public void invalidate(LevelAccessor level) {
|
||||||
blockEntities.forEach(s -> s.forEach(pos -> invalidateAt(level, pos)));
|
blockEntities.forEach(s -> s.keySet()
|
||||||
|
.forEach(p -> invalidateAt(level, p)));
|
||||||
groups.forEach(uuid -> {
|
groups.forEach(uuid -> {
|
||||||
if (Create.RAILWAYS.signalEdgeGroups.remove(uuid) != null)
|
if (Create.RAILWAYS.signalEdgeGroups.remove(uuid) != null)
|
||||||
Create.RAILWAYS.sync.edgeGroupRemoved(uuid);
|
Create.RAILWAYS.sync.edgeGroupRemoved(uuid);
|
||||||
|
@ -97,18 +97,24 @@ public class SignalBoundary extends TrackEdgePoint {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tileAdded(BlockEntity tile, boolean front) {
|
public void tileAdded(BlockEntity tile, boolean front) {
|
||||||
Set<BlockPos> tilesOnSide = blockEntities.get(front);
|
Map<BlockPos, Boolean> tilesOnSide = blockEntities.get(front);
|
||||||
if (tilesOnSide.isEmpty())
|
if (tilesOnSide.isEmpty())
|
||||||
tile.getBlockState()
|
tile.getBlockState()
|
||||||
.getOptionalValue(SignalBlock.TYPE)
|
.getOptionalValue(SignalBlock.TYPE)
|
||||||
.ifPresent(type -> types.set(front, type));
|
.ifPresent(type -> types.set(front, type));
|
||||||
tilesOnSide.add(tile.getBlockPos());
|
tilesOnSide.put(tile.getBlockPos(), tile instanceof SignalTileEntity ste && ste.getReportedPower());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateTilePower(SignalTileEntity tile) {
|
||||||
|
for (boolean front : Iterate.trueAndFalse)
|
||||||
|
blockEntities.get(front)
|
||||||
|
.computeIfPresent(tile.getBlockPos(), (p, c) -> tile.getReportedPower());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tileRemoved(BlockPos tilePos, boolean front) {
|
public void tileRemoved(BlockPos tilePos, boolean front) {
|
||||||
blockEntities.forEach(s -> s.remove(tilePos));
|
blockEntities.forEach(s -> s.remove(tilePos));
|
||||||
if (blockEntities.both(Set::isEmpty))
|
if (blockEntities.both(Map::isEmpty))
|
||||||
removeFromAllGraphs();
|
removeFromAllGraphs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,8 +140,8 @@ public class SignalBoundary extends TrackEdgePoint {
|
||||||
|
|
||||||
public OverlayState getOverlayFor(BlockPos tile) {
|
public OverlayState getOverlayFor(BlockPos tile) {
|
||||||
for (boolean first : Iterate.trueAndFalse) {
|
for (boolean first : Iterate.trueAndFalse) {
|
||||||
Set<BlockPos> set = blockEntities.get(first);
|
Map<BlockPos, Boolean> set = blockEntities.get(first);
|
||||||
for (BlockPos blockPos : set) {
|
for (BlockPos blockPos : set.keySet()) {
|
||||||
if (blockPos.equals(tile))
|
if (blockPos.equals(tile))
|
||||||
return blockEntities.get(!first)
|
return blockEntities.get(!first)
|
||||||
.isEmpty() ? OverlayState.RENDER : OverlayState.DUAL;
|
.isEmpty() ? OverlayState.RENDER : OverlayState.DUAL;
|
||||||
|
@ -147,13 +153,13 @@ public class SignalBoundary extends TrackEdgePoint {
|
||||||
|
|
||||||
public SignalType getTypeFor(BlockPos tile) {
|
public SignalType getTypeFor(BlockPos tile) {
|
||||||
return types.get(blockEntities.getFirst()
|
return types.get(blockEntities.getFirst()
|
||||||
.contains(tile));
|
.containsKey(tile));
|
||||||
}
|
}
|
||||||
|
|
||||||
public SignalState getStateFor(BlockPos tile) {
|
public SignalState getStateFor(BlockPos tile) {
|
||||||
for (boolean first : Iterate.trueAndFalse) {
|
for (boolean first : Iterate.trueAndFalse) {
|
||||||
Set<BlockPos> set = blockEntities.get(first);
|
Map<BlockPos, Boolean> set = blockEntities.get(first);
|
||||||
if (set.contains(tile))
|
if (set.containsKey(tile))
|
||||||
return cachedStates.get(first);
|
return cachedStates.get(first);
|
||||||
}
|
}
|
||||||
return SignalState.INVALID;
|
return SignalState.INVALID;
|
||||||
|
@ -177,10 +183,14 @@ public class SignalBoundary extends TrackEdgePoint {
|
||||||
|
|
||||||
private void tickState(TrackGraph graph) {
|
private void tickState(TrackGraph graph) {
|
||||||
for (boolean current : Iterate.trueAndFalse) {
|
for (boolean current : Iterate.trueAndFalse) {
|
||||||
Set<BlockPos> set = blockEntities.get(current);
|
Map<BlockPos, Boolean> set = blockEntities.get(current);
|
||||||
if (set.isEmpty())
|
if (set.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
boolean forcedRed = set.values()
|
||||||
|
.stream()
|
||||||
|
.anyMatch(Boolean::booleanValue);
|
||||||
|
|
||||||
UUID group = groups.get(current);
|
UUID group = groups.get(current);
|
||||||
if (Objects.equal(group, groups.get(!current))) {
|
if (Objects.equal(group, groups.get(!current))) {
|
||||||
cachedStates.set(current, SignalState.INVALID);
|
cachedStates.set(current, SignalState.INVALID);
|
||||||
|
@ -194,11 +204,22 @@ public class SignalBoundary extends TrackEdgePoint {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean occupiedUnlessBySelf = signalEdgeGroup.isOccupiedUnless(this);
|
boolean occupiedUnlessBySelf = forcedRed || signalEdgeGroup.isOccupiedUnless(this);
|
||||||
cachedStates.set(current, occupiedUnlessBySelf ? SignalState.RED : resolveSignalChain(graph, current));
|
cachedStates.set(current, occupiedUnlessBySelf ? SignalState.RED : resolveSignalChain(graph, current));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isForcedRed(TrackNode side) {
|
||||||
|
return isForcedRed(isPrimary(side));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isForcedRed(boolean primary) {
|
||||||
|
return blockEntities.get(primary)
|
||||||
|
.values()
|
||||||
|
.stream()
|
||||||
|
.anyMatch(Boolean::booleanValue);
|
||||||
|
}
|
||||||
|
|
||||||
private SignalState resolveSignalChain(TrackGraph graph, boolean side) {
|
private SignalState resolveSignalChain(TrackGraph graph, boolean side) {
|
||||||
if (types.get(side) != SignalType.CROSS_SIGNAL)
|
if (types.get(side) != SignalType.CROSS_SIGNAL)
|
||||||
return SignalState.GREEN;
|
return SignalState.GREEN;
|
||||||
|
@ -244,14 +265,14 @@ public class SignalBoundary extends TrackEdgePoint {
|
||||||
if (migration)
|
if (migration)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
blockEntities = Couple.create(HashSet::new);
|
blockEntities = Couple.create(HashMap::new);
|
||||||
groups = Couple.create(null, null);
|
groups = Couple.create(null, null);
|
||||||
|
|
||||||
for (int i = 1; i <= 2; i++)
|
for (int i = 1; i <= 2; i++)
|
||||||
if (nbt.contains("Tiles" + i)) {
|
if (nbt.contains("Tiles" + i)) {
|
||||||
boolean first = i == 1;
|
boolean first = i == 1;
|
||||||
NBTHelper.iterateCompoundList(nbt.getList("Tiles" + i, Tag.TAG_COMPOUND), c -> blockEntities.get(first)
|
NBTHelper.iterateCompoundList(nbt.getList("Tiles" + i, Tag.TAG_COMPOUND), c -> blockEntities.get(first)
|
||||||
.add(NbtUtils.readBlockPos(c)));
|
.put(NbtUtils.readBlockPos(c), c.getBoolean("Power")));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; i <= 2; i++)
|
for (int i = 1; i <= 2; i++)
|
||||||
|
@ -280,7 +301,12 @@ public class SignalBoundary extends TrackEdgePoint {
|
||||||
for (int i = 1; i <= 2; i++)
|
for (int i = 1; i <= 2; i++)
|
||||||
if (!blockEntities.get(i == 1)
|
if (!blockEntities.get(i == 1)
|
||||||
.isEmpty())
|
.isEmpty())
|
||||||
nbt.put("Tiles" + i, NBTHelper.writeCompoundList(blockEntities.get(i == 1), NbtUtils::writeBlockPos));
|
nbt.put("Tiles" + i, NBTHelper.writeCompoundList(blockEntities.get(i == 1)
|
||||||
|
.entrySet(), e -> {
|
||||||
|
CompoundTag c = NbtUtils.writeBlockPos(e.getKey());
|
||||||
|
c.putBoolean("Power", e.getValue());
|
||||||
|
return c;
|
||||||
|
}));
|
||||||
for (int i = 1; i <= 2; i++)
|
for (int i = 1; i <= 2; i++)
|
||||||
if (groups.get(i == 1) != null)
|
if (groups.get(i == 1) != null)
|
||||||
nbt.putUUID("Group" + i, groups.get(i == 1));
|
nbt.putUUID("Group" + i, groups.get(i == 1));
|
||||||
|
@ -306,7 +332,7 @@ public class SignalBoundary extends TrackEdgePoint {
|
||||||
|
|
||||||
public void cycleSignalType(BlockPos pos) {
|
public void cycleSignalType(BlockPos pos) {
|
||||||
types.set(blockEntities.getFirst()
|
types.set(blockEntities.getFirst()
|
||||||
.contains(pos), SignalType.values()[(getTypeFor(pos).ordinal() + 1) % SignalType.values().length]);
|
.containsKey(pos), SignalType.values()[(getTypeFor(pos).ordinal() + 1) % SignalType.values().length]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,9 @@ import com.simibubi.create.foundation.utility.NBTHelper;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
import net.minecraft.world.ticks.TickPriority;
|
|
||||||
|
|
||||||
public class SignalTileEntity extends SmartTileEntity implements ITransformableTE {
|
public class SignalTileEntity extends SmartTileEntity implements ITransformableTE {
|
||||||
|
|
||||||
|
@ -48,11 +46,13 @@ public class SignalTileEntity extends SmartTileEntity implements ITransformableT
|
||||||
private SignalState state;
|
private SignalState state;
|
||||||
private OverlayState overlay;
|
private OverlayState overlay;
|
||||||
private int switchToRedAfterTrainEntered;
|
private int switchToRedAfterTrainEntered;
|
||||||
|
private boolean lastReportedPower;
|
||||||
|
|
||||||
public SignalTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
public SignalTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||||
super(type, pos, state);
|
super(type, pos, state);
|
||||||
this.state = SignalState.INVALID;
|
this.state = SignalState.INVALID;
|
||||||
this.overlay = OverlayState.SKIP;
|
this.overlay = OverlayState.SKIP;
|
||||||
|
this.lastReportedPower = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -60,6 +60,7 @@ public class SignalTileEntity extends SmartTileEntity implements ITransformableT
|
||||||
super.write(tag, clientPacket);
|
super.write(tag, clientPacket);
|
||||||
NBTHelper.writeEnum(tag, "State", state);
|
NBTHelper.writeEnum(tag, "State", state);
|
||||||
NBTHelper.writeEnum(tag, "Overlay", overlay);
|
NBTHelper.writeEnum(tag, "Overlay", overlay);
|
||||||
|
tag.putBoolean("Power", lastReportedPower);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,6 +68,7 @@ public class SignalTileEntity extends SmartTileEntity implements ITransformableT
|
||||||
super.read(tag, clientPacket);
|
super.read(tag, clientPacket);
|
||||||
state = NBTHelper.readEnum(tag, "State", SignalState.class);
|
state = NBTHelper.readEnum(tag, "State", SignalState.class);
|
||||||
overlay = NBTHelper.readEnum(tag, "Overlay", OverlayState.class);
|
overlay = NBTHelper.readEnum(tag, "Overlay", OverlayState.class);
|
||||||
|
lastReportedPower = tag.getBoolean("Power");
|
||||||
invalidateRenderBoundingBox();
|
invalidateRenderBoundingBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,17 +81,6 @@ public class SignalTileEntity extends SmartTileEntity implements ITransformableT
|
||||||
return state == SignalState.RED;
|
return state == SignalState.RED;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void scheduleBlockTick() {
|
|
||||||
Block block = getBlockState().getBlock();
|
|
||||||
if (!level.getBlockTicks()
|
|
||||||
.willTickThisTick(worldPosition, block))
|
|
||||||
level.scheduleTick(worldPosition, block, 2, TickPriority.NORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updatePowerAfterDelay() {
|
|
||||||
level.blockUpdated(worldPosition, getBlockState().getBlock());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||||
edgePoint = new TrackTargetingBehaviour<>(this, EdgePointType.SIGNAL);
|
edgePoint = new TrackTargetingBehaviour<>(this, EdgePointType.SIGNAL);
|
||||||
|
@ -109,11 +100,21 @@ public class SignalTileEntity extends SmartTileEntity implements ITransformableT
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
getBlockState().getOptionalValue(SignalBlock.TYPE)
|
BlockState blockState = getBlockState();
|
||||||
|
|
||||||
|
blockState.getOptionalValue(SignalBlock.POWERED).ifPresent(powered -> {
|
||||||
|
if (lastReportedPower == powered)
|
||||||
|
return;
|
||||||
|
lastReportedPower = powered;
|
||||||
|
boundary.updateTilePower(this);
|
||||||
|
notifyUpdate();
|
||||||
|
});
|
||||||
|
|
||||||
|
blockState.getOptionalValue(SignalBlock.TYPE)
|
||||||
.ifPresent(stateType -> {
|
.ifPresent(stateType -> {
|
||||||
SignalType targetType = boundary.getTypeFor(worldPosition);
|
SignalType targetType = boundary.getTypeFor(worldPosition);
|
||||||
if (stateType != targetType) {
|
if (stateType != targetType) {
|
||||||
level.setBlock(worldPosition, getBlockState().setValue(SignalBlock.TYPE, targetType), 3);
|
level.setBlock(worldPosition, blockState.setValue(SignalBlock.TYPE, targetType), 3);
|
||||||
refreshBlockState();
|
refreshBlockState();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -122,6 +123,10 @@ public class SignalTileEntity extends SmartTileEntity implements ITransformableT
|
||||||
setOverlay(boundary.getOverlayFor(worldPosition));
|
setOverlay(boundary.getOverlayFor(worldPosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getReportedPower() {
|
||||||
|
return lastReportedPower;
|
||||||
|
}
|
||||||
|
|
||||||
public SignalState getState() {
|
public SignalState getState() {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -147,7 +152,6 @@ public class SignalTileEntity extends SmartTileEntity implements ITransformableT
|
||||||
this.state = state;
|
this.state = state;
|
||||||
switchToRedAfterTrainEntered = state == SignalState.GREEN || state == SignalState.YELLOW ? 15 : 0;
|
switchToRedAfterTrainEntered = state == SignalState.GREEN || state == SignalState.YELLOW ? 15 : 0;
|
||||||
notifyUpdate();
|
notifyUpdate();
|
||||||
scheduleBlockTick();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in a new issue