• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CyclopsMC / IntegratedDynamics / 16574353307

28 Jul 2025 04:15PM UTC coverage: 53.239% (+0.03%) from 53.206%
16574353307

push

github

rubensworks
Bump CommonCaps version

2890 of 8740 branches covered (33.07%)

Branch coverage included in aggregate %.

17352 of 29281 relevant lines covered (59.26%)

3.08 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.26
/src/main/java/org/cyclops/integrateddynamics/core/helper/CableHelpers.java
1
package org.cyclops.integrateddynamics.core.helper;
2

3
import com.google.common.collect.Lists;
4
import com.google.common.collect.Maps;
5
import com.google.common.collect.Sets;
6
import net.minecraft.core.BlockPos;
7
import net.minecraft.core.Direction;
8
import net.minecraft.resources.ResourceKey;
9
import net.minecraft.world.InteractionResult;
10
import net.minecraft.world.entity.LivingEntity;
11
import net.minecraft.world.entity.player.Player;
12
import net.minecraft.world.item.ItemStack;
13
import net.minecraft.world.level.Level;
14
import net.minecraft.world.level.block.Block;
15
import net.minecraft.world.level.block.entity.BlockEntity;
16
import net.minecraft.world.level.block.state.BlockState;
17
import net.neoforged.neoforge.common.NeoForge;
18
import net.neoforged.neoforge.common.extensions.ILevelExtension;
19
import org.apache.commons.lang3.tuple.Pair;
20
import org.cyclops.cyclopscore.helper.IModHelpers;
21
import org.cyclops.cyclopscore.helper.IModHelpersNeoForge;
22
import org.cyclops.integrateddynamics.Capabilities;
23
import org.cyclops.integrateddynamics.api.block.IFacadeable;
24
import org.cyclops.integrateddynamics.api.block.cable.ICable;
25
import org.cyclops.integrateddynamics.api.block.cable.ICableFakeable;
26
import org.cyclops.integrateddynamics.api.network.INetwork;
27
import org.cyclops.integrateddynamics.api.network.INetworkCarrier;
28
import org.cyclops.integrateddynamics.api.network.INetworkElement;
29
import org.cyclops.integrateddynamics.api.network.INetworkElementProvider;
30
import org.cyclops.integrateddynamics.api.part.IPartContainer;
31
import org.cyclops.integrateddynamics.api.part.IPartType;
32
import org.cyclops.integrateddynamics.api.path.IPathElement;
33
import org.cyclops.integrateddynamics.core.network.event.NetworkInitializedEvent;
34
import org.cyclops.integrateddynamics.item.ItemBlockCable;
35

36
import javax.annotation.Nullable;
37
import java.lang.ref.WeakReference;
38
import java.util.*;
39

40
/**
41
 * Helpers related to cables.
42
 * @author rubensworks
43
 */
44
public class CableHelpers {
×
45

46
    public static final Collection<Direction> ALL_SIDES = Sets.newIdentityHashSet();
2✔
47
    static {
48
        for (Direction side : Direction.values()) {
16✔
49
            ALL_SIDES.add(side);
4✔
50
        }
51
    }
52

53
    /**
54
     * Get the cable capability at the given position.
55
     * If possible, prefer the variant with block state.
56
     * @param world The world.
57
     * @param pos The position.
58
     * @param side The side.
59
     * @return The optional cable capability.
60
     */
61
    @Deprecated
62
    public static Optional<ICable> getCable(ILevelExtension world, BlockPos pos, @Nullable Direction side) {
63
        return IModHelpersNeoForge.get().getCapabilityHelpers().getCapability(world, pos, side, Capabilities.Cable.BLOCK);
8✔
64
    }
65

66
    /**
67
     * Get the cable capability at the given position.
68
     * @param world The world.
69
     * @param pos The position.
70
     * @param side The side.
71
     * @param blockState The block state.
72
     * @return The optional cable capability.
73
     */
74
    public static Optional<ICable> getCable(ILevelExtension world, BlockPos pos, @Nullable Direction side, @Nullable BlockState blockState) {
75
        return Optional.ofNullable(world.getCapability(Capabilities.Cable.BLOCK, pos, blockState, null, side));
10✔
76
    }
77

78
    /**
79
     * Get the fakeable cable capability at the given position.
80
     * If possible, prefer the variant with block state.
81
     * @param world The world.
82
     * @param pos The position.
83
     * @param side The side.
84
     * @return The optional fakeable cable capability.
85
     */
86
    @Deprecated
87
    public static Optional<ICableFakeable> getCableFakeable(ILevelExtension world, BlockPos pos, @Nullable Direction side) {
88
        return IModHelpersNeoForge.get().getCapabilityHelpers().getCapability(world, pos, side, Capabilities.CableFakeable.BLOCK);
8✔
89
    }
90

91
    /**
92
     * Get the fakeable cable capability at the given position.
93
     * @param world The world.
94
     * @param pos The position.
95
     * @param side The side.
96
     * @param blockState The block state.
97
     * @return The optional fakeable cable capability.
98
     */
99
    public static Optional<ICableFakeable> getCableFakeable(ILevelExtension world, BlockPos pos, @Nullable Direction side, BlockState blockState) {
100
        return Optional.ofNullable(world.getCapability(Capabilities.CableFakeable.BLOCK, pos, blockState, null, side));
10✔
101
    }
102

103
    /**
104
     * Get the path element capability at the given position.
105
     * @param world The world.
106
     * @param pos The position.
107
     * @param side The side.
108
     * @return The optional path element capability.
109
     */
110
    public static Optional<IPathElement> getPathElement(ILevelExtension world, BlockPos pos, @Nullable Direction side, BlockState blockState) {
111
        return Optional.ofNullable(world.getCapability(Capabilities.PathElement.BLOCK, pos, blockState, null, side));
10✔
112
    }
113

114
    /**
115
     * Request to update the cable connections of all neighbours of the given position.
116
     * @param world The world.
117
     * @param pos The center position.
118
     * @param sides The sides to update connections for.
119
     */
120
    public static void updateConnectionsNeighbours(ILevelExtension world, BlockPos pos, Collection<Direction> sides) {
121
        for(Direction side : sides) {
10✔
122
            updateConnections(world, pos.relative(side), side.getOpposite());
7✔
123
        }
1✔
124
    }
1✔
125

126
    /**
127
     * Request to update the cable connections at the given position.
128
     * @param world The world.
129
     * @param pos The position.
130
     * @param side The side.
131
     */
132
    public static void updateConnections(ILevelExtension world, BlockPos pos, @Nullable Direction side) {
133
        getCable(world, pos, side)
5✔
134
                .ifPresent(ICable::updateConnections);
1✔
135
    }
1✔
136

137
    /**
138
     * Check if there is a cable at the given position AND if it is connected for the given side.
139
     * @param world The world.
140
     * @param pos The position.
141
     * @param side The side to check a connection for.
142
     * @param blockState The block state.
143
     * @return If there is a cable that is connected.
144
     */
145
    public static boolean isCableConnected(ILevelExtension world, BlockPos pos, Direction side, BlockState blockState) {
146
        return getCable(world, pos, side, blockState)
8✔
147
                .map(cable -> cable.isConnected(side))
7✔
148
                .orElse(false);
4✔
149
    }
150

151
    /**
152
     * Check if one side of the given cable at the given position can connect to the given side.
153
     * To be used when the cable connections are being updated.
154
     * This will check if the origin cable can connect to that side,
155
     * if there is a cable at the target side and if that cable can connect with this side.
156
     * This ignores any current cable connections.
157
     * @param world The world.
158
     * @param pos The center position.
159
     * @param side The side from the center position to check.
160
     * @param originCable The cable at the center position.
161
     * @return If it can connect.
162
     */
163
    public static boolean canCableConnectTo(ILevelExtension world, BlockPos pos, Direction side, ICable originCable) {
164
        BlockPos neighbourPos = pos.relative(side);
4✔
165
        return getCable(world, neighbourPos, side.getOpposite())
9✔
166
                .map(neighbourCable -> originCable.canConnect(neighbourCable, side)
12✔
167
                        && neighbourCable.canConnect(originCable, side.getOpposite()))
6✔
168
                .orElse(false);
4✔
169
    }
170

171
    /**
172
     * Check if the given position is not a fake cable.
173
     * This can mean that there is no cable at all!
174
     * But if there is a cable, this method will return true only if it is a real cable.
175
     * If possible, prefer the variant with block state.
176
     *
177
     * @param world The world.
178
     * @param pos The position.
179
     * @param side The side.
180
     * @return If there is no fake cable.
181
     */
182
    @Deprecated
183
    public static boolean isNoFakeCable(ILevelExtension world, BlockPos pos, @Nullable Direction side) {
184
        return getCableFakeable(world, pos, side)
6✔
185
                .map(ICableFakeable::isRealCable)
2✔
186
                .orElse(true);
4✔
187
    }
188

189
    /**
190
     * Check if the given position is not a fake cable.
191
     * This can mean that there is no cable at all!
192
     * But if there is a cable, this method will return true only if it is a real cable.
193
     * @param world The world.
194
     * @param pos The position.
195
     * @param side The side.
196
     * @param blockState The block state.
197
     * @return If there is no fake cable.
198
     */
199
    public static boolean isNoFakeCable(ILevelExtension world, BlockPos pos, @Nullable Direction side, BlockState blockState) {
200
        return getCableFakeable(world, pos, side, blockState)
7✔
201
                .map(ICableFakeable::isRealCable)
2✔
202
                .orElse(true);
4✔
203
    }
204

205
    /**
206
     * Disconnect a cable's side.
207
     * @param world The cable world.
208
     * @param pos The cable position.
209
     * @param side The cable side.
210
     * @param cable The cable to disconnect.
211
     * @param disconnectSide The side to disconnect.
212
     */
213
    public static void disconnectCable(Level world, BlockPos pos, Direction side, ICable cable, Direction disconnectSide) {
214
        // Store the disconnection in the part entity
215
        cable.disconnect(disconnectSide);
3✔
216

217
        // Signal changes
218
        cable.updateConnections();
2✔
219
        Collection<Direction> sidesToUpdate = getCableConnections(cable);
3✔
220
        sidesToUpdate.add(disconnectSide);
4✔
221
        CableHelpers.updateConnectionsNeighbours(world, pos, sidesToUpdate);
4✔
222

223
        // Reinit the networks for this block and the disconnected neighbour.
224
        NetworkHelpers.initNetwork(world, pos, side);
5✔
225
        NetworkHelpers.initNetwork(world, pos.relative(disconnectSide), side.getOpposite());
8✔
226
    }
1✔
227

228
    /**
229
     * Actions to be performed when a player right clicks on a cable.
230
     * @param world The world  of the cable.
231
     * @param pos The position of the cable.
232
     * @param state The blockstate of the cable.
233
     * @param player The player activating the cable.
234
     * @param heldItem The item with which the player is right-clicking.
235
     * @param side The side of the block the player right-clicked on.
236
     * @param cableConnectionHit The side identifying the cable connection that is being activated,
237
     *                           this will be null if the center part of the cable is activated.
238
     * @return Action result.
239
     */
240
    public static InteractionResult onCableActivated(Level world, BlockPos pos, BlockState state, Player player,
241
                                                    ItemStack heldItem, Direction side, @Nullable Direction cableConnectionHit) {
242
        ICable cable = CableHelpers.getCable(world, pos, side).orElse(null);
8✔
243
        if (cable == null) {
2!
244
            return InteractionResult.PASS;
×
245
        }
246

247
        if(WrenchHelpers.isWrench(player, heldItem, world, pos, side)) {
7!
248
            if (world.isClientSide()) {
3!
249
                return InteractionResult.SUCCESS; // Don't do anything client-side
×
250
            }
251
            if (player.isSecondaryUseActive()) {
3✔
252
                removeCable(world, pos, player);
5✔
253
            } else if (cableConnectionHit != null) {
2✔
254
                disconnectCable(world, pos, side, cable, cableConnectionHit);
7✔
255
            } else if (cableConnectionHit == null) {
2!
256
                // Reconnect cable side
257
                BlockPos neighbourPos = pos.relative(side);
4✔
258
                ICable neighbourCable = CableHelpers.getCable(world, neighbourPos, side.getOpposite()).orElse(null);
9✔
259
                if(neighbourCable != null && !cable.isConnected(side) &&
9!
260
                        (cable.canConnect(neighbourCable, side) || neighbourCable.canConnect(cable, side.getOpposite()))
8!
261
                        ) {
262
                    // Notify the reconnection in the part entity of this and the neighbour block,
263
                    // since we don't know in which one the disconnection was made.
264
                    cable.reconnect(side);
3✔
265
                    neighbourCable.reconnect(side.getOpposite());
4✔
266

267
                    // Signal changes
268
                    cable.updateConnections();
2✔
269
                    Collection<Direction> sidesToUpdate = getCableConnections(cable);
3✔
270
                    sidesToUpdate.add(side);
4✔
271
                    CableHelpers.updateConnectionsNeighbours(world, pos, sidesToUpdate);
4✔
272

273
                    // Reinit the networks for this block and the connected neighbour.
274
                    NetworkHelpers.initNetwork(world, pos, side);
5✔
275
                    NetworkHelpers.initNetwork(world, neighbourPos, side.getOpposite());
6✔
276
                }
277
            }
278
            return InteractionResult.SUCCESS;
2✔
279
        }
280
        return InteractionResult.PASS;
×
281
    }
282

283
    private static WeakReference<LivingEntity> CABLE_PLACER_SNAPSHOT = new WeakReference<>(null);
5✔
284

285
    /**
286
     * This should be called when a cable is added.
287
     * This method automatically notifies the neighbours and (re-)initializes the network if this cable carries one.
288
     * This should in most cases only be called server-side.
289
     * @param world The world.
290
     * @param pos The position.
291
     */
292
    public static void onCableAdded(Level world, BlockPos pos) {
293
        LivingEntity placer = CABLE_PLACER_SNAPSHOT.get();
4✔
294
        if (placer != null) {
2✔
295
            CableHelpers.onCableAddedByPlayer(world, pos, placer);
4✔
296
            CABLE_PLACER_SNAPSHOT = new WeakReference<>(null);
6✔
297
        } else {
298
            onCableAddedByPlayerActual(world, pos, null);
4✔
299
        }
300
    }
1✔
301

302
    /**
303
     * This should be called when a cable was added by a player.
304
     * This should be called after {@link CableHelpers#onCableAdded(Level, BlockPos)}.
305
     * It simply emits an player-sensitive init event on the network bus.
306
     * @param world The world.
307
     * @param pos The position.
308
     * @param placer The entity who placed the cable.
309
     */
310
    public static void onCableAddedByPlayer(Level world, BlockPos pos, @Nullable LivingEntity placer) {
311
        if (world.captureBlockSnapshots) {
3✔
312
            CABLE_PLACER_SNAPSHOT = new WeakReference<>(placer);
6✔
313
        } else {
314
            onCableAddedByPlayerActual(world, pos, placer);
4✔
315
        }
316
    }
1✔
317

318
    /**
319
     * This should be called when a cable was added by a player.
320
     * This should be called after {@link CableHelpers#onCableAdded(Level, BlockPos)}.
321
     * It simply emits an player-sensitive init event on the network bus.
322
     * @param world The world.
323
     * @param pos The position.
324
     * @param placer The entity who placed the cable.
325
     */
326
    public static void onCableAddedByPlayerActual(Level world, BlockPos pos, @Nullable LivingEntity placer) {
327
        CableHelpers.updateConnectionsNeighbours(world, pos, CableHelpers.ALL_SIDES);
4✔
328
        if(!world.isClientSide()) {
3!
329
            NetworkHelpers.initNetwork(world, pos, null)
8✔
330
                    .ifPresent(network -> NeoForge.EVENT_BUS.post(new NetworkInitializedEvent(network, world, pos, placer)));
12✔
331
        }
332
    }
1✔
333

334
    private static final Map<Pair<ResourceKey<Level>, BlockPos>, Collection<Direction>> CABLE_REMOVING_CONNECTIONS = Maps.newConcurrentMap();
2✔
335

336
    public static void overrideCableRemovingConnections(Level level, BlockPos pos, Collection<Direction> sides) {
337
        CABLE_REMOVING_CONNECTIONS.put(Pair.of(level.dimension(), pos), sides);
8✔
338
    }
1✔
339

340
    /**
341
     * This should be called when a cable is being removed, while the part entity is still present.
342
     * This method won't do anything when called client-side.
343
     *
344
     * @param world           The world.
345
     * @param pos             The position.
346
     * @param dropMainElement If the main part element should be dropped.
347
     * @param saveState       If the element state should be saved in the item.
348
     * @param blockState      The block state.
349
     * @param blockEntity     The block entity.
350
     * @return If the cable was removed from the network.
351
     */
352
    public static boolean onCableRemoving(Level world, BlockPos pos, boolean dropMainElement, boolean saveState, BlockState blockState, BlockEntity blockEntity) {
353
        CABLE_REMOVING_CONNECTIONS.put(Pair.of(world.dimension(), pos), CableHelpers.getExternallyConnectedCables(world, pos));
10✔
354
        if (!world.isClientSide() && CableHelpers.isNoFakeCable(world, pos, null)) {
8!
355
            INetworkCarrier networkCarrier = NetworkHelpers.getNetworkCarrier(world, pos, null, blockState).orElse(null);
9✔
356

357
            // Get all drops from the network elements this cable provides.
358
            List<ItemStack> itemStacks = Lists.newLinkedList();
2✔
359
            INetworkElementProvider networkElementProvider = NetworkHelpers.getNetworkElementProvider(world, pos, null, blockState).orElse(null);
9✔
360
            if (networkElementProvider != null) {
2!
361
                for (INetworkElement networkElement : networkElementProvider.createNetworkElements(world, pos)) {
13✔
362
                    networkElement.addDrops(blockState, blockEntity, itemStacks, dropMainElement, saveState);
7✔
363
                }
1✔
364
                for (ItemStack itemStack : itemStacks) {
10✔
365
                    Block.popResource(world, pos, itemStack);
4✔
366
                }
1✔
367
            }
368

369
            // If the cable has a network, remove it from the network.
370
            if(networkCarrier != null && networkCarrier.getNetwork() != null) {
5!
371
                IPathElement pathElement = getPathElement(world, pos, null, blockState)
6✔
372
                        .orElseThrow(() -> new IllegalStateException("Could not find a valid path element capability"));
3✔
373
                return onCableRemovingNetwork(blockState, blockEntity, networkCarrier, pathElement);
6✔
374
            }
375
        }
376
        return true;
2✔
377
    }
378

379
    public static boolean onCableRemovingNetwork(BlockState blockState, BlockEntity blockEntity, INetworkCarrier networkCarrier, IPathElement pathElement) {
380
        INetwork network = networkCarrier.getNetwork();
3✔
381
        networkCarrier.setNetwork(null);
3✔
382
        return network.removePathElement(pathElement, null, blockState, blockEntity);
7✔
383
    }
384

385
    /**
386
     * This should be called AFTER a cable is removed, at this stage the part entity will not exist anymore.
387
     * This method won't do anything when called client-side.
388
     * @param world The world.
389
     * @param pos The position.
390
     * @return If the cable was removed from the network.
391
     */
392
    public static boolean onCableRemoved(Level world, BlockPos pos) {
393
        Collection<Direction> sides = CABLE_REMOVING_CONNECTIONS.remove(Pair.of(world.dimension(), pos));
8✔
394
        if (sides == null) {
2!
395
            sides = Collections.emptyList();
×
396
        }
397
        updateConnectionsNeighbours(world, pos, sides);
4✔
398
        if (!world.isClientSide()) {
3!
399
            // Reinit neighbouring networks.
400
            for(Direction side : sides) {
10✔
401
                BlockPos sidePos = pos.relative(side);
4✔
402
                NetworkHelpers.initNetwork(world, sidePos, side.getOpposite());
6✔
403
            }
1✔
404
        }
405
        return true;
2✔
406
    }
407

408
    private static boolean removingCable = false;
3✔
409
    /**
410
     * @return If {@link #removeCable} is currently being called.
411
     */
412
    public static boolean isRemovingCable() {
413
        return removingCable;
2✔
414
    }
415
    /**
416
     * @param removingCable If the removing cable flag should be set
417
     */
418
    public static void setRemovingCable(boolean removingCable) {
419
        CableHelpers.removingCable = removingCable;
2✔
420
    }
1✔
421

422
    /**
423
     * Remove a cable.
424
     * This will automatically handle sounds, drops,
425
     * fakeable cables, network element removal and network (re)intialization.
426
     * @param world The world.
427
     * @param pos The position.
428
     * @param player The player removing the cable or null.
429
     */
430
    public static void removeCable(Level world, BlockPos pos, @Nullable Player player) {
431
        removingCable = true;
2✔
432
        BlockState blockState = world.getBlockState(pos);
4✔
433
        ICable cable = getCable(world, pos, null, blockState).orElse(null);
9✔
434
        ICableFakeable cableFakeable = getCableFakeable(world, pos, null, blockState).orElse(null);
9✔
435
        IPartContainer partContainer = PartHelpers.getPartContainer(world, pos, null, blockState).orElse(null);
9✔
436
        BlockEntity blockEntity = world.getBlockEntity(pos);
4✔
437
        if (cable == null) {
2!
438
            removingCable = false;
×
439
            return;
×
440
        }
441

442
        CableHelpers.onCableRemoving(world, pos, false, false, blockState, blockEntity);
8✔
443
        // If the cable has no parts or is not fakeable, remove the block,
444
        // otherwise mark the cable as being fake.
445
        if (cableFakeable == null || partContainer == null || !partContainer.hasParts()) {
7!
446
            cable.destroy();
3✔
447
        } else {
448
            cableFakeable.setRealCable(false);
3✔
449
        }
450
        if (player == null) {
2!
451
            IModHelpers.get().getItemStackHelpers().spawnItemStack(world, pos, cable.getItemStack());
×
452
        } else if (!player.isCreative()) {
3!
453
            IModHelpers.get().getItemStackHelpers().spawnItemStackToPlayer(world, pos, cable.getItemStack(), player);
8✔
454
        }
455
        CableHelpers.onCableRemoved(world, pos);
4✔
456

457
        ItemBlockCable.playBreakSound(world, pos, blockState);
4✔
458

459
        removingCable = false;
2✔
460
    }
1✔
461

462
    /**
463
     * Check if the target has a facade.
464
     * @param world The world.
465
     * @param pos The position.
466
     * @param blockState The block state.
467
     * @return If it has a facade.
468
     */
469
    public static boolean hasFacade(ILevelExtension world, BlockPos pos, BlockState blockState) {
470
        return Optional.ofNullable(world.getCapability(Capabilities.Facadeable.BLOCK, pos, blockState, null, null))
11✔
471
                .map(IFacadeable::hasFacade)
2✔
472
                .orElse(false);
4✔
473
    }
474

475
    /**
476
     * Get the target's facade
477
     * @param world The world.
478
     * @param pos The position.
479
     * @param blockState The block state.
480
     * @return The optional facade.
481
     */
482
    public static Optional<BlockState> getFacade(ILevelExtension world, BlockPos pos, BlockState blockState) {
483
        return Optional.ofNullable(world.getCapability(Capabilities.Facadeable.BLOCK, pos, blockState, null, null))
11✔
484
                .flatMap(facadeable -> Optional.ofNullable(facadeable.getFacade()));
5✔
485
    }
486

487
    public static boolean isLightTransparent(Level world, BlockPos pos, @Nullable Direction side, BlockState blockState) {
488
        return PartHelpers.getPartContainer(world, pos, side, blockState)
×
489
                .map(partContainer -> {
×
490
                    for (Map.Entry<Direction, IPartType<?, ?>> entry : partContainer.getParts().entrySet()) {
×
491
                        IPartType part = entry.getValue();
×
492
                        if (part.forceLightTransparency(partContainer.getPartState(entry.getKey()))) {
×
493
                            return true;
×
494
                        }
495
                    }
×
496
                    return false;
×
497
                })
498
                .orElse(false);
×
499
    }
500

501
    /**
502
     * Get the sides the cable is currently connected to.
503
     * @param cable A cable.
504
     * @return The cable connections.
505
     */
506
    public static Collection<Direction> getCableConnections(ICable cable) {
507
        Collection<Direction> sides = Sets.newIdentityHashSet();
2✔
508
        for (Direction side : Direction.values()) {
16✔
509
            if (cable.isConnected(side)) {
4✔
510
                sides.add(side);
4✔
511
            }
512
        }
513
        return sides;
2✔
514
    }
515

516
    /**
517
     * Get the sides that are externally connected to the given position.
518
     * @param world The world.
519
     * @param pos The position.
520
     * @return The sides.
521
     */
522
    public static Collection<Direction> getExternallyConnectedCables(Level world, BlockPos pos) {
523
        Collection<Direction> sides = Sets.newIdentityHashSet();
2✔
524
        for (Direction side : Direction.values()) {
16✔
525
            if (CableHelpers.isCableConnected(world, pos.relative(side), side.getOpposite(), null)) {
9✔
526
                sides.add(side);
4✔
527
            }
528
        }
529
        return sides;
2✔
530
    }
531
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc