Skip to content

Commit 7ef33d3

Browse files
committed
Tunnel removal bugfixes
1 parent dfb5fb2 commit 7ef33d3

File tree

4 files changed

+114
-10
lines changed

4 files changed

+114
-10
lines changed

src/main/java/dev/compactmods/machines/machine/CompactMachineBlockEntity.java

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import dev.compactmods.machines.machine.data.CompactMachineData;
1212
import dev.compactmods.machines.machine.data.MachineToRoomConnections;
1313
import dev.compactmods.machines.room.data.CompactRoomData;
14+
import dev.compactmods.machines.tunnel.TunnelWallEntity;
15+
import dev.compactmods.machines.tunnel.data.RoomTunnelData;
1416
import net.minecraft.core.BlockPos;
1517
import net.minecraft.core.Direction;
1618
import net.minecraft.nbt.CompoundTag;
@@ -49,18 +51,51 @@ public CompactMachineBlockEntity(BlockPos pos, BlockState state) {
4951
@Override
5052
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
5153
if (cap == Capabilities.ROOM) return room.cast();
52-
if (cap == Capabilities.ROOM_CAPS) return caps.cast();
5354

54-
return caps.lazyMap(c -> c.getCapability(cap, side))
55-
.orElse(super.getCapability(cap, side));
55+
if(level instanceof ServerLevel sl) {
56+
return room.map(r -> {
57+
var roomId = r.getChunk();
58+
try {
59+
final var serv = sl.getServer();
60+
61+
final var tunnels = RoomTunnelData.get(serv, roomId);
62+
final var graph = tunnels.getGraph();
63+
64+
final var supportingTunnels = graph.getTunnelsSupporting(machineId, side, cap);
65+
final var firstSupported = supportingTunnels.findFirst();
66+
if (firstSupported.isEmpty())
67+
return super.getCapability(cap, side);
68+
69+
final var compact = serv.getLevel(Registration.COMPACT_DIMENSION);
70+
if(compact == null)
71+
throw new MissingDimensionException();
72+
73+
if(compact.getBlockEntity(firstSupported.get()) instanceof TunnelWallEntity tunnel) {
74+
return tunnel.getCapability(cap, side);
75+
} else {
76+
return super.getCapability(cap, side);
77+
}
78+
} catch (MissingDimensionException e) {
79+
CompactMachines.LOGGER.fatal(e);
80+
return super.getCapability(cap, side);
81+
}
82+
}).orElse(super.getCapability(cap, side));
83+
}
84+
85+
return super.getCapability(cap, side);
5686
}
5787

5888
@Nullable
5989
private IMachineRoom getRoom() {
6090
if (level instanceof ServerLevel sl) {
6191
return getInternalChunkPos().map(c -> {
62-
var inChunk = sl.getChunk(c.x, c.z);
63-
return inChunk.getCapability(Capabilities.ROOM).orElseThrow(RuntimeException::new);
92+
final var compact = sl.getServer().getLevel(Registration.COMPACT_DIMENSION);
93+
if(compact != null) {
94+
var inChunk = compact.getChunk(c.x, c.z);
95+
return inChunk.getCapability(Capabilities.ROOM).orElseThrow(RuntimeException::new);
96+
}
97+
98+
return null;
6499
}).orElse(null);
65100
}
66101

@@ -70,9 +105,12 @@ private IMachineRoom getRoom() {
70105
@Nullable
71106
private IRoomCapabilities getRoomCapabilities() {
72107
if (level instanceof ServerLevel sl) {
73-
return getInternalChunkPos().map(c -> {
108+
getInternalChunkPos().map(c -> {
74109
var inChunk = sl.getChunk(c.x, c.z);
75-
return inChunk.getCapability(Capabilities.ROOM_CAPS).orElseThrow(RuntimeException::new);
110+
111+
CompactMachines.LOGGER.debug(inChunk.toString());
112+
113+
return null;
76114
}).orElse(null);
77115
}
78116

src/main/java/dev/compactmods/machines/tunnel/TunnelWallBlock.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.compactmods.machines.tunnel;
22

3+
import dev.compactmods.machines.CompactMachines;
34
import dev.compactmods.machines.api.core.Messages;
45
import dev.compactmods.machines.api.tunnels.TunnelDefinition;
56
import dev.compactmods.machines.api.tunnels.lifecycle.ITunnelTeardown;
@@ -58,7 +59,7 @@ public static Optional<TunnelDefinition> getTunnelInfo(BlockGetter world, BlockP
5859
if (tile == null)
5960
return Optional.empty();
6061

61-
return Optional.of(tile.getTunnelType());
62+
return Optional.ofNullable(tile.getTunnelType());
6263
}
6364

6465
@Override
@@ -129,7 +130,14 @@ public InteractionResult use(BlockState state, Level level, BlockPos pos, Player
129130
teardown.teardown(new TunnelPosition(serverLevel, pos, tunnelWallSide), tunnel.getTunnel(), TeardownReason.REMOVED);
130131
}
131132

132-
// todo tunnels.ifPresent(t -> t.unregister(pos));
133+
try {
134+
final var tunnels = RoomTunnelData.get(serverLevel.getServer(), new ChunkPos(pos));
135+
final var tunnelGraph = tunnels.getGraph();
136+
137+
tunnelGraph.unregister(pos);
138+
} catch (MissingDimensionException e) {
139+
CompactMachines.LOGGER.fatal(e);
140+
}
133141
} else {
134142
// Rotate tunnel
135143
Direction dir = state.getValue(CONNECTED_SIDE);
@@ -170,4 +178,6 @@ public InteractionResult use(BlockState state, Level level, BlockPos pos, Player
170178

171179
return InteractionResult.SUCCESS;
172180
}
181+
182+
// todo - breaking block unregisters tunnel info
173183
}

src/main/java/dev/compactmods/machines/tunnel/TunnelWallEntity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable D
156156
if (level == null || level.isClientSide)
157157
return super.getCapability(cap, side);
158158

159-
if (side != null && side != getTunnelSide())
159+
if (side != null && side != getConnectedSide())
160160
return super.getCapability(cap, side);
161161

162162
if (cap == Capabilities.TUNNEL_CONNECTION)

src/main/java/dev/compactmods/machines/tunnel/graph/TunnelConnectionGraph.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@ public Stream<IGraphNode> nodes() {
228228

229229
@Override
230230
public CompoundTag serializeNBT() {
231+
cleanupOrphans();
232+
231233
CompoundTag tag = new CompoundTag();
232234

233235
HashMap<IGraphNode, UUID> nodeIds = new HashMap<>();
@@ -454,4 +456,58 @@ public Stream<BlockPos> getMachineTunnels(int machine, TunnelDefinition type) {
454456
.filter(position -> connectedMachine(position).map(m -> m == machine).orElse(false))
455457
.map(BlockPos::immutable);
456458
}
459+
460+
public void unregister(BlockPos pos) {
461+
if(!hasTunnel(pos))
462+
return;
463+
464+
final var existing = tunnels.get(pos);
465+
graph.removeNode(existing);
466+
tunnels.remove(pos);
467+
468+
cleanupOrphanedTypes();
469+
cleanupOrphanedMachines();
470+
}
471+
472+
private void cleanupOrphans() {
473+
cleanupOrphanedTunnels();
474+
cleanupOrphanedTypes();
475+
cleanupOrphanedMachines();
476+
}
477+
478+
private void cleanupOrphanedTypes() {
479+
HashSet<ResourceLocation> removedTypes = new HashSet<>();
480+
tunnelTypes.forEach((type, node) -> {
481+
if(graph.degree(node) == 0) {
482+
graph.removeNode(node);
483+
removedTypes.add(type);
484+
}
485+
});
486+
487+
removedTypes.forEach(tunnelTypes::remove);
488+
}
489+
490+
private void cleanupOrphanedTunnels() {
491+
HashSet<BlockPos> removed = new HashSet<>();
492+
tunnels.forEach((pos, node) -> {
493+
if(graph.degree(node) == 0) {
494+
graph.removeNode(node);
495+
removed.add(pos);
496+
}
497+
});
498+
499+
removed.forEach(tunnels::remove);
500+
}
501+
502+
private void cleanupOrphanedMachines() {
503+
HashSet<Integer> removed = new HashSet<>();
504+
machines.forEach((machine, node) -> {
505+
if(graph.degree(node) == 0) {
506+
graph.removeNode(node);
507+
removed.add(machine);
508+
}
509+
});
510+
511+
removed.forEach(machines::remove);
512+
}
457513
}

0 commit comments

Comments
 (0)