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

CyclopsMC / IntegratedDynamics / 13739195914

08 Mar 2025 03:58PM UTC coverage: 39.059% (+0.06%) from 39.002%
13739195914

push

github

rubensworks
Merge remote-tracking branch 'origin/master-1.21-lts' into master-1.21

1966 of 8373 branches covered (23.48%)

Branch coverage included in aggregate %.

10307 of 23049 relevant lines covered (44.72%)

2.1 hits per line

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

76.89
/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.Sets;
5
import net.minecraft.core.BlockPos;
6
import net.minecraft.core.Direction;
7
import net.minecraft.world.InteractionResult;
8
import net.minecraft.world.entity.LivingEntity;
9
import net.minecraft.world.entity.player.Player;
10
import net.minecraft.world.item.ItemStack;
11
import net.minecraft.world.level.Level;
12
import net.minecraft.world.level.block.Block;
13
import net.minecraft.world.level.block.state.BlockState;
14
import net.neoforged.neoforge.common.NeoForge;
15
import net.neoforged.neoforge.common.extensions.ILevelExtension;
16
import org.cyclops.cyclopscore.helper.IModHelpers;
17
import org.cyclops.cyclopscore.helper.IModHelpersNeoForge;
18
import org.cyclops.integrateddynamics.Capabilities;
19
import org.cyclops.integrateddynamics.api.block.IFacadeable;
20
import org.cyclops.integrateddynamics.api.block.cable.ICable;
21
import org.cyclops.integrateddynamics.api.block.cable.ICableFakeable;
22
import org.cyclops.integrateddynamics.api.network.INetwork;
23
import org.cyclops.integrateddynamics.api.network.INetworkCarrier;
24
import org.cyclops.integrateddynamics.api.network.INetworkElement;
25
import org.cyclops.integrateddynamics.api.network.INetworkElementProvider;
26
import org.cyclops.integrateddynamics.api.part.IPartContainer;
27
import org.cyclops.integrateddynamics.api.part.IPartType;
28
import org.cyclops.integrateddynamics.api.path.IPathElement;
29
import org.cyclops.integrateddynamics.core.network.event.NetworkInitializedEvent;
30
import org.cyclops.integrateddynamics.item.ItemBlockCable;
31

32
import javax.annotation.Nullable;
33
import java.lang.ref.WeakReference;
34
import java.util.Collection;
35
import java.util.List;
36
import java.util.Map;
37
import java.util.Optional;
38

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

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

52
    /**
53
     * Get the cable capability at the given position.
54
     * @param world The world.
55
     * @param pos The position.
56
     * @param side The side.
57
     * @return The optional cable capability.
58
     */
59
    @Deprecated // TODO: attempt to migrate all calls to method with BlockState param
60
    public static Optional<ICable> getCable(ILevelExtension world, BlockPos pos, @Nullable Direction side) {
61
        return IModHelpersNeoForge.get().getCapabilityHelpers().getCapability(world, pos, side, Capabilities.Cable.BLOCK);
8✔
62
    }
63

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

76
    /**
77
     * Get the fakeable cable capability at the given position.
78
     * @param world The world.
79
     * @param pos The position.
80
     * @param side The side.
81
     * @return The optional fakeable cable capability.
82
     */
83
    @Deprecated // TODO: attempt to migrate all calls to method with BlockState param
84
    public static Optional<ICableFakeable> getCableFakeable(ILevelExtension world, BlockPos pos, @Nullable Direction side) {
85
        return IModHelpersNeoForge.get().getCapabilityHelpers().getCapability(world, pos, side, Capabilities.CableFakeable.BLOCK);
8✔
86
    }
87

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

100
    /**
101
     * Get the path element capability at the given position.
102
     * @param world The world.
103
     * @param pos The position.
104
     * @param side The side.
105
     * @return The optional path element capability.
106
     */
107
    @Deprecated // TODO: attempt to migrate all calls to method with BlockState param
108
    public static Optional<IPathElement> getPathElement(ILevelExtension world, BlockPos pos, @Nullable Direction side) {
109
        return IModHelpersNeoForge.get().getCapabilityHelpers().getCapability(world, pos, side, Capabilities.PathElement.BLOCK);
×
110
    }
111

112
    /**
113
     * Get the path element capability at the given position.
114
     * @param world The world.
115
     * @param pos The position.
116
     * @param side The side.
117
     * @return The optional path element capability.
118
     */
119
    public static Optional<IPathElement> getPathElement(ILevelExtension world, BlockPos pos, @Nullable Direction side, BlockState blockState) {
120
        return Optional.ofNullable(world.getCapability(Capabilities.PathElement.BLOCK, pos, blockState, null, side));
10✔
121
    }
122

123
    /**
124
     * Request to update the cable connections of all neighbours of the given position.
125
     * @param world The world.
126
     * @param pos The center position.
127
     * @param sides The sides to update connections for.
128
     */
129
    public static void updateConnectionsNeighbours(ILevelExtension world, BlockPos pos, Collection<Direction> sides) {
130
        for(Direction side : sides) {
10✔
131
            updateConnections(world, pos.relative(side), side.getOpposite());
7✔
132
        }
1✔
133
    }
1✔
134

135
    /**
136
     * Request to update the cable connections at the given position.
137
     * @param world The world.
138
     * @param pos The position.
139
     * @param side The side.
140
     */
141
    public static void updateConnections(ILevelExtension world, BlockPos pos, @Nullable Direction side) {
142
        getCable(world, pos, side)
5✔
143
                .ifPresent(ICable::updateConnections);
1✔
144
    }
1✔
145

146
    /**
147
     * Check if there is a cable at the given position AND if it is connected for the given side.
148
     * @param world The world.
149
     * @param pos The position.
150
     * @param side The side to check a connection for.
151
     * @return If there is a cable that is connected.
152
     */
153
    @Deprecated // TODO: attempt to migrate all calls to method with BlockState param
154
    public static boolean isCableConnected(ILevelExtension world, BlockPos pos, Direction side) {
155
        return getCable(world, pos, side)
×
156
                .map(cable -> cable.isConnected(side))
×
157
                .orElse(false);
×
158
    }
159

160
    /**
161
     * Check if there is a cable at the given position AND if it is connected for the given side.
162
     * @param world The world.
163
     * @param pos The position.
164
     * @param side The side to check a connection for.
165
     * @param blockState The block state.
166
     * @return If there is a cable that is connected.
167
     */
168
    public static boolean isCableConnected(ILevelExtension world, BlockPos pos, Direction side, BlockState blockState) {
169
        return getCable(world, pos, side, blockState)
8✔
170
                .map(cable -> cable.isConnected(side))
7✔
171
                .orElse(false);
4✔
172
    }
173

174
    /**
175
     * Check if one side of the given cable at the given position can connect to the given side.
176
     * To be used when the cable connections are being updated.
177
     * This will check if the origin cable can connect to that side,
178
     * if there is a cable at the target side and if that cable can connect with this side.
179
     * This ignores any current cable connections.
180
     * @param world The world.
181
     * @param pos The center position.
182
     * @param side The side from the center position to check.
183
     * @param originCable The cable at the center position.
184
     * @return If it can connect.
185
     */
186
    public static boolean canCableConnectTo(ILevelExtension world, BlockPos pos, Direction side, ICable originCable) {
187
        BlockPos neighbourPos = pos.relative(side);
4✔
188
        return getCable(world, neighbourPos, side.getOpposite())
9✔
189
                .map(neighbourCable -> originCable.canConnect(neighbourCable, side)
12✔
190
                        && neighbourCable.canConnect(originCable, side.getOpposite()))
6✔
191
                .orElse(false);
4✔
192
    }
193

194
    /**
195
     * Check if the given position is not a fake cable.
196
     * This can mean that there is no cable at all!
197
     * But if there is a cable, this method will return true only if it is a real cable.
198
     * @param world The world.
199
     * @param pos The position.
200
     * @param side The side.
201
     * @return If there is no fake cable.
202
     */
203
    @Deprecated // TODO: attempt to migrate all calls to method with BlockState param
204
    public static boolean isNoFakeCable(ILevelExtension world, BlockPos pos, @Nullable Direction side) {
205
        return getCableFakeable(world, pos, side)
6✔
206
                .map(ICableFakeable::isRealCable)
2✔
207
                .orElse(true);
4✔
208
    }
209

210
    /**
211
     * Check if the given position is not a fake cable.
212
     * This can mean that there is no cable at all!
213
     * But if there is a cable, this method will return true only if it is a real cable.
214
     * @param world The world.
215
     * @param pos The position.
216
     * @param side The side.
217
     * @param blockState The block state.
218
     * @return If there is no fake cable.
219
     */
220
    public static boolean isNoFakeCable(ILevelExtension world, BlockPos pos, @Nullable Direction side, BlockState blockState) {
221
        return getCableFakeable(world, pos, side, blockState)
7✔
222
                .map(ICableFakeable::isRealCable)
2✔
223
                .orElse(true);
4✔
224
    }
225

226
    /**
227
     * Disconnect a cable's side.
228
     * @param world The cable world.
229
     * @param pos The cable position.
230
     * @param side The cable side.
231
     * @param cable The cable to disconnect.
232
     * @param disconnectSide The side to disconnect.
233
     */
234
    public static void disconnectCable(Level world, BlockPos pos, Direction side, ICable cable, Direction disconnectSide) {
235
        // Store the disconnection in the part entity
236
        cable.disconnect(disconnectSide);
3✔
237

238
        // Signal changes
239
        cable.updateConnections();
2✔
240
        Collection<Direction> sidesToUpdate = getCableConnections(cable);
3✔
241
        sidesToUpdate.add(disconnectSide);
4✔
242
        CableHelpers.updateConnectionsNeighbours(world, pos, sidesToUpdate);
4✔
243

244
        // Reinit the networks for this block and the disconnected neighbour.
245
        NetworkHelpers.initNetwork(world, pos, side);
5✔
246
        NetworkHelpers.initNetwork(world, pos.relative(disconnectSide), side.getOpposite());
8✔
247
    }
1✔
248

249
    /**
250
     * Actions to be performed when a player right clicks on a cable.
251
     * @param world The world  of the cable.
252
     * @param pos The position of the cable.
253
     * @param state The blockstate of the cable.
254
     * @param player The player activating the cable.
255
     * @param heldItem The item with which the player is right-clicking.
256
     * @param side The side of the block the player right-clicked on.
257
     * @param cableConnectionHit The side identifying the cable connection that is being activated,
258
     *                           this will be null if the center part of the cable is activated.
259
     * @return Action result.
260
     */
261
    public static InteractionResult onCableActivated(Level world, BlockPos pos, BlockState state, Player player,
262
                                                    ItemStack heldItem, Direction side, @Nullable Direction cableConnectionHit) {
263
        ICable cable = CableHelpers.getCable(world, pos, side).orElse(null);
8✔
264
        if (cable == null) {
2!
265
            return InteractionResult.PASS;
×
266
        }
267

268
        if(WrenchHelpers.isWrench(player, heldItem, world, pos, side)) {
7!
269
            if (world.isClientSide()) {
3!
270
                return InteractionResult.SUCCESS; // Don't do anything client-side
×
271
            }
272
            if (player.isSecondaryUseActive()) {
3✔
273
                removeCable(world, pos, player);
5✔
274
            } else if (cableConnectionHit != null) {
2✔
275
                disconnectCable(world, pos, side, cable, cableConnectionHit);
7✔
276
            } else if (cableConnectionHit == null) {
2!
277
                // Reconnect cable side
278
                BlockPos neighbourPos = pos.relative(side);
4✔
279
                ICable neighbourCable = CableHelpers.getCable(world, neighbourPos, side.getOpposite()).orElse(null);
9✔
280
                if(neighbourCable != null && !cable.isConnected(side) &&
9!
281
                        (cable.canConnect(neighbourCable, side) || neighbourCable.canConnect(cable, side.getOpposite()))
8!
282
                        ) {
283
                    // Notify the reconnection in the part entity of this and the neighbour block,
284
                    // since we don't know in which one the disconnection was made.
285
                    cable.reconnect(side);
3✔
286
                    neighbourCable.reconnect(side.getOpposite());
4✔
287

288
                    // Signal changes
289
                    cable.updateConnections();
2✔
290
                    Collection<Direction> sidesToUpdate = getCableConnections(cable);
3✔
291
                    sidesToUpdate.add(side);
4✔
292
                    CableHelpers.updateConnectionsNeighbours(world, pos, sidesToUpdate);
4✔
293

294
                    // Reinit the networks for this block and the connected neighbour.
295
                    NetworkHelpers.initNetwork(world, pos, side);
5✔
296
                    NetworkHelpers.initNetwork(world, neighbourPos, side.getOpposite());
6✔
297
                }
298
            }
299
            return InteractionResult.SUCCESS;
2✔
300
        }
301
        return InteractionResult.PASS;
×
302
    }
303

304
    private static WeakReference<LivingEntity> CABLE_PLACER_SNAPSHOT = new WeakReference<>(null);
5✔
305

306
    /**
307
     * This should be called when a cable is added.
308
     * This method automatically notifies the neighbours and (re-)initializes the network if this cable carries one.
309
     * This should in most cases only be called server-side.
310
     * @param world The world.
311
     * @param pos The position.
312
     */
313
    public static void onCableAdded(Level world, BlockPos pos) {
314
        LivingEntity placer = CABLE_PLACER_SNAPSHOT.get();
4✔
315
        if (placer != null) {
2✔
316
            CableHelpers.onCableAddedByPlayer(world, pos, placer);
4✔
317
            CABLE_PLACER_SNAPSHOT = new WeakReference<>(null);
6✔
318
        } else {
319
            onCableAddedByPlayerActual(world, pos, null);
4✔
320
        }
321
    }
1✔
322

323
    /**
324
     * This should be called when a cable was added by a player.
325
     * This should be called after {@link CableHelpers#onCableAdded(Level, BlockPos)}.
326
     * It simply emits an player-sensitive init event on the network bus.
327
     * @param world The world.
328
     * @param pos The position.
329
     * @param placer The entity who placed the cable.
330
     */
331
    public static void onCableAddedByPlayer(Level world, BlockPos pos, @Nullable LivingEntity placer) {
332
        if (world.captureBlockSnapshots) {
3✔
333
            CABLE_PLACER_SNAPSHOT = new WeakReference<>(placer);
6✔
334
        } else {
335
            onCableAddedByPlayerActual(world, pos, placer);
4✔
336
        }
337
    }
1✔
338

339
    /**
340
     * This should be called when a cable was added by a player.
341
     * This should be called after {@link CableHelpers#onCableAdded(Level, BlockPos)}.
342
     * It simply emits an player-sensitive init event on the network bus.
343
     * @param world The world.
344
     * @param pos The position.
345
     * @param placer The entity who placed the cable.
346
     */
347
    public static void onCableAddedByPlayerActual(Level world, BlockPos pos, @Nullable LivingEntity placer) {
348
        CableHelpers.updateConnectionsNeighbours(world, pos, CableHelpers.ALL_SIDES);
4✔
349
        if(!world.isClientSide()) {
3!
350
            NetworkHelpers.initNetwork(world, pos, null)
8✔
351
                    .ifPresent(network -> NeoForge.EVENT_BUS.post(new NetworkInitializedEvent(network, world, pos, placer)));
12✔
352
        }
353
    }
1✔
354

355
    /**
356
     * This should be called when a cable is being removed, while the part entity is still present.
357
     * This method won't do anything when called client-side.
358
     * @param world The world.
359
     * @param pos The position.
360
     * @param dropMainElement If the main part element should be dropped.
361
     * @param saveState If the element state should be saved in the item.
362
     * @return If the cable was removed from the network.
363
     */
364
    public static boolean onCableRemoving(Level world, BlockPos pos, boolean dropMainElement, boolean saveState, BlockState blockState) {
365
        if (!world.isClientSide() && CableHelpers.isNoFakeCable(world, pos, null)) {
8!
366
            INetworkCarrier networkCarrier = NetworkHelpers.getNetworkCarrier(world, pos, null, blockState).orElse(null);
9✔
367

368
            // Get all drops from the network elements this cable provides.
369
            List<ItemStack> itemStacks = Lists.newLinkedList();
2✔
370
            INetworkElementProvider networkElementProvider = NetworkHelpers.getNetworkElementProvider(world, pos, null, blockState).orElse(null);
9✔
371
            if (networkElementProvider != null) {
2!
372
                for (INetworkElement networkElement : networkElementProvider.createNetworkElements(world, pos)) {
13✔
373
                    networkElement.addDrops(blockState, itemStacks, dropMainElement, saveState);
6✔
374
                }
1✔
375
                for (ItemStack itemStack : itemStacks) {
10✔
376
                    Block.popResource(world, pos, itemStack);
4✔
377
                }
1✔
378
            }
379

380
            // If the cable has a network, remove it from the network.
381
            if(networkCarrier != null && networkCarrier.getNetwork() != null) {
5!
382
                IPathElement pathElement = getPathElement(world, pos, null, blockState)
6✔
383
                        .orElseThrow(() -> new IllegalStateException("Could not find a valid path element capability"));
3✔
384
                INetwork network = networkCarrier.getNetwork();
3✔
385
                networkCarrier.setNetwork(null);
3✔
386
                return network.removePathElement(pathElement, null, blockState);
6✔
387
            }
388
        }
389
        return true;
2✔
390
    }
391

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

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

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

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

461
        ItemBlockCable.playBreakSound(world, pos, blockState);
4✔
462

463
        removingCable = false;
2✔
464
    }
1✔
465

466
    /**
467
     * Check if the target has a facade.
468
     * @param world The world.
469
     * @param pos The position.
470
     * @return If it has a facade.
471
     */
472
    @Deprecated // TODO: attempt to migrate all calls to method with BlockState param
473
    public static boolean hasFacade(ILevelExtension world, BlockPos pos) {
474
        return IModHelpersNeoForge.get().getCapabilityHelpers().getCapability(world, pos, null, Capabilities.Facadeable.BLOCK)
×
475
                .map(IFacadeable::hasFacade)
×
476
                .orElse(false);
×
477
    }
478

479
    /**
480
     * Check if the target has a facade.
481
     * @param world The world.
482
     * @param pos The position.
483
     * @param blockState The block state.
484
     * @return If it has a facade.
485
     */
486
    public static boolean hasFacade(ILevelExtension world, BlockPos pos, BlockState blockState) {
487
        return Optional.ofNullable(world.getCapability(Capabilities.Facadeable.BLOCK, pos, blockState, null, null))
11✔
488
                .map(IFacadeable::hasFacade)
2✔
489
                .orElse(false);
4✔
490
    }
491

492
    /**
493
     * Get the target's facade
494
     * @param world The world.
495
     * @param pos The position.
496
     * @return The optional facade.
497
     */
498
    @Deprecated // TODO: attempt to migrate all calls to method with BlockState param
499
    public static Optional<BlockState> getFacade(ILevelExtension world, BlockPos pos) {
500
        return IModHelpersNeoForge.get().getCapabilityHelpers().getCapability(world, pos, null, Capabilities.Facadeable.BLOCK)
9✔
501
                .flatMap(facadeable -> Optional.ofNullable(facadeable.getFacade()));
5✔
502
    }
503

504
    /**
505
     * Get the target's facade
506
     * @param world The world.
507
     * @param pos The position.
508
     * @param blockState The block state.
509
     * @return The optional facade.
510
     */
511
    public static Optional<BlockState> getFacade(ILevelExtension world, BlockPos pos, BlockState blockState) {
512
        return Optional.ofNullable(world.getCapability(Capabilities.Facadeable.BLOCK, pos, blockState, null, null))
11✔
513
                .flatMap(facadeable -> Optional.ofNullable(facadeable.getFacade()));
5✔
514
    }
515

516
    @Deprecated // TODO: attempt to migrate all calls to method with BlockState param
517
    public static boolean isLightTransparent(Level world, BlockPos pos, @Nullable Direction side) {
518
        return PartHelpers.getPartContainer(world, pos, side)
×
519
                .map(partContainer -> {
×
520
                    for (Map.Entry<Direction, IPartType<?, ?>> entry : partContainer.getParts().entrySet()) {
×
521
                        IPartType part = entry.getValue();
×
522
                        if (part.forceLightTransparency(partContainer.getPartState(entry.getKey()))) {
×
523
                            return true;
×
524
                        }
525
                    }
×
526
                    return false;
×
527
                })
528
                .orElse(false);
×
529
    }
530

531
    public static boolean isLightTransparent(Level world, BlockPos pos, @Nullable Direction side, BlockState blockState) {
532
        return PartHelpers.getPartContainer(world, pos, side, blockState)
×
533
                .map(partContainer -> {
×
534
                    for (Map.Entry<Direction, IPartType<?, ?>> entry : partContainer.getParts().entrySet()) {
×
535
                        IPartType part = entry.getValue();
×
536
                        if (part.forceLightTransparency(partContainer.getPartState(entry.getKey()))) {
×
537
                            return true;
×
538
                        }
539
                    }
×
540
                    return false;
×
541
                })
542
                .orElse(false);
×
543
    }
544

545
    /**
546
     * Get the sides the cable is currently connected to.
547
     * @param cable A cable.
548
     * @return The cable connections.
549
     */
550
    public static Collection<Direction> getCableConnections(ICable cable) {
551
        Collection<Direction> sides = Sets.newIdentityHashSet();
2✔
552
        for (Direction side : Direction.values()) {
16✔
553
            if (cable.isConnected(side)) {
4✔
554
                sides.add(side);
4✔
555
            }
556
        }
557
        return sides;
2✔
558
    }
559

560
    /**
561
     * Get the sides that are externally connected to the given position.
562
     * @param world The world.
563
     * @param pos The position.
564
     * @return The sides.
565
     */
566
    public static Collection<Direction> getExternallyConnectedCables(Level world, BlockPos pos) {
567
        Collection<Direction> sides = Sets.newIdentityHashSet();
2✔
568
        for (Direction side : Direction.values()) {
16✔
569
            if (CableHelpers.isCableConnected(world, pos.relative(side), side.getOpposite(), null)) {
9✔
570
                sides.add(side);
4✔
571
            }
572
        }
573
        return sides;
2✔
574
    }
575
}
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