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

CyclopsMC / IntegratedDynamics / 16552051255

27 Jul 2025 01:58PM UTC coverage: 53.206% (+8.0%) from 45.161%
16552051255

push

github

rubensworks
Resolve minor TODOs

2888 of 8740 branches covered (33.04%)

Branch coverage included in aggregate %.

17341 of 29280 relevant lines covered (59.22%)

3.08 hits per line

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

77.01
/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
     * @param world The world.
56
     * @param pos The position.
57
     * @param side The side.
58
     * @return The optional cable capability.
59
     */
60
    @Deprecated // TODO: attempt to migrate all calls to method with BlockState param
61
    public static Optional<ICable> getCable(ILevelExtension world, BlockPos pos, @Nullable Direction side) {
62
        return IModHelpersNeoForge.get().getCapabilityHelpers().getCapability(world, pos, side, Capabilities.Cable.BLOCK);
8✔
63
    }
64

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

358
    public static void overrideCableRemovingConnections(Level level, BlockPos pos, Collection<Direction> sides) {
359
        CABLE_REMOVING_CONNECTIONS.put(Pair.of(level.dimension(), pos), sides);
8✔
360
    }
1✔
361

362
    /**
363
     * This should be called when a cable is being removed, while the part entity is still present.
364
     * This method won't do anything when called client-side.
365
     *
366
     * @param world           The world.
367
     * @param pos             The position.
368
     * @param dropMainElement If the main part element should be dropped.
369
     * @param saveState       If the element state should be saved in the item.
370
     * @param blockState      The block state.
371
     * @param blockEntity     The block entity.
372
     * @return If the cable was removed from the network.
373
     */
374
    public static boolean onCableRemoving(Level world, BlockPos pos, boolean dropMainElement, boolean saveState, BlockState blockState, BlockEntity blockEntity) {
375
        CABLE_REMOVING_CONNECTIONS.put(Pair.of(world.dimension(), pos), CableHelpers.getExternallyConnectedCables(world, pos));
10✔
376
        if (!world.isClientSide() && CableHelpers.isNoFakeCable(world, pos, null)) {
8!
377
            INetworkCarrier networkCarrier = NetworkHelpers.getNetworkCarrier(world, pos, null, blockState).orElse(null);
9✔
378

379
            // Get all drops from the network elements this cable provides.
380
            List<ItemStack> itemStacks = Lists.newLinkedList();
2✔
381
            INetworkElementProvider networkElementProvider = NetworkHelpers.getNetworkElementProvider(world, pos, null, blockState).orElse(null);
9✔
382
            if (networkElementProvider != null) {
2!
383
                for (INetworkElement networkElement : networkElementProvider.createNetworkElements(world, pos)) {
13✔
384
                    networkElement.addDrops(blockState, blockEntity, itemStacks, dropMainElement, saveState);
7✔
385
                }
1✔
386
                for (ItemStack itemStack : itemStacks) {
10✔
387
                    Block.popResource(world, pos, itemStack);
4✔
388
                }
1✔
389
            }
390

391
            // If the cable has a network, remove it from the network.
392
            if(networkCarrier != null && networkCarrier.getNetwork() != null) {
5!
393
                IPathElement pathElement = getPathElement(world, pos, null, blockState)
6✔
394
                        .orElseThrow(() -> new IllegalStateException("Could not find a valid path element capability"));
3✔
395
                return onCableRemovingNetwork(blockState, blockEntity, networkCarrier, pathElement);
6✔
396
            }
397
        }
398
        return true;
2✔
399
    }
400

401
    public static boolean onCableRemovingNetwork(BlockState blockState, BlockEntity blockEntity, INetworkCarrier networkCarrier, IPathElement pathElement) {
402
        INetwork network = networkCarrier.getNetwork();
3✔
403
        networkCarrier.setNetwork(null);
3✔
404
        return network.removePathElement(pathElement, null, blockState, blockEntity);
7✔
405
    }
406

407
    /**
408
     * This should be called AFTER a cable is removed, at this stage the part entity will not exist anymore.
409
     * This method won't do anything when called client-side.
410
     * @param world The world.
411
     * @param pos The position.
412
     * @return If the cable was removed from the network.
413
     */
414
    public static boolean onCableRemoved(Level world, BlockPos pos) {
415
        Collection<Direction> sides = CABLE_REMOVING_CONNECTIONS.remove(Pair.of(world.dimension(), pos));
8✔
416
        if (sides == null) {
2!
417
            sides = Collections.emptyList();
×
418
        }
419
        updateConnectionsNeighbours(world, pos, sides);
4✔
420
        if (!world.isClientSide()) {
3!
421
            // Reinit neighbouring networks.
422
            for(Direction side : sides) {
10✔
423
                BlockPos sidePos = pos.relative(side);
4✔
424
                NetworkHelpers.initNetwork(world, sidePos, side.getOpposite());
6✔
425
            }
1✔
426
        }
427
        return true;
2✔
428
    }
429

430
    private static boolean removingCable = false;
3✔
431
    /**
432
     * @return If {@link #removeCable} is currently being called.
433
     */
434
    public static boolean isRemovingCable() {
435
        return removingCable;
2✔
436
    }
437
    /**
438
     * @param removingCable If the removing cable flag should be set
439
     */
440
    public static void setRemovingCable(boolean removingCable) {
441
        CableHelpers.removingCable = removingCable;
2✔
442
    }
1✔
443

444
    /**
445
     * Remove a cable.
446
     * This will automatically handle sounds, drops,
447
     * fakeable cables, network element removal and network (re)intialization.
448
     * @param world The world.
449
     * @param pos The position.
450
     * @param player The player removing the cable or null.
451
     */
452
    public static void removeCable(Level world, BlockPos pos, @Nullable Player player) {
453
        removingCable = true;
2✔
454
        ICable cable = getCable(world, pos, null).orElse(null);
8✔
455
        ICableFakeable cableFakeable = getCableFakeable(world, pos, null).orElse(null);
8✔
456
        IPartContainer partContainer = PartHelpers.getPartContainer(world, pos, null).orElse(null);
8✔
457
        BlockState blockState = world.getBlockState(pos);
4✔
458
        BlockEntity blockEntity = world.getBlockEntity(pos);
4✔
459
        if (cable == null) {
2!
460
            removingCable = false;
×
461
            return;
×
462
        }
463

464
        CableHelpers.onCableRemoving(world, pos, false, false, blockState, blockEntity);
8✔
465
        // If the cable has no parts or is not fakeable, remove the block,
466
        // otherwise mark the cable as being fake.
467
        if (cableFakeable == null || partContainer == null || !partContainer.hasParts()) {
7!
468
            cable.destroy();
3✔
469
        } else {
470
            cableFakeable.setRealCable(false);
3✔
471
        }
472
        if (player == null) {
2!
473
            IModHelpers.get().getItemStackHelpers().spawnItemStack(world, pos, cable.getItemStack());
×
474
        } else if (!player.isCreative()) {
3!
475
            IModHelpers.get().getItemStackHelpers().spawnItemStackToPlayer(world, pos, cable.getItemStack(), player);
8✔
476
        }
477
        CableHelpers.onCableRemoved(world, pos);
4✔
478

479
        ItemBlockCable.playBreakSound(world, pos, blockState);
4✔
480

481
        removingCable = false;
2✔
482
    }
1✔
483

484
    /**
485
     * Check if the target has a facade.
486
     * @param world The world.
487
     * @param pos The position.
488
     * @return If it has a facade.
489
     */
490
    @Deprecated // TODO: attempt to migrate all calls to method with BlockState param
491
    public static boolean hasFacade(ILevelExtension world, BlockPos pos) {
492
        return IModHelpersNeoForge.get().getCapabilityHelpers().getCapability(world, pos, null, Capabilities.Facadeable.BLOCK)
×
493
                .map(IFacadeable::hasFacade)
×
494
                .orElse(false);
×
495
    }
496

497
    /**
498
     * Check if the target has a facade.
499
     * @param world The world.
500
     * @param pos The position.
501
     * @param blockState The block state.
502
     * @return If it has a facade.
503
     */
504
    public static boolean hasFacade(ILevelExtension world, BlockPos pos, BlockState blockState) {
505
        return Optional.ofNullable(world.getCapability(Capabilities.Facadeable.BLOCK, pos, blockState, null, null))
11✔
506
                .map(IFacadeable::hasFacade)
2✔
507
                .orElse(false);
4✔
508
    }
509

510
    /**
511
     * Get the target's facade
512
     * @param world The world.
513
     * @param pos The position.
514
     * @return The optional facade.
515
     */
516
    @Deprecated // TODO: attempt to migrate all calls to method with BlockState param
517
    public static Optional<BlockState> getFacade(ILevelExtension world, BlockPos pos) {
518
        return IModHelpersNeoForge.get().getCapabilityHelpers().getCapability(world, pos, null, Capabilities.Facadeable.BLOCK)
9✔
519
                .flatMap(facadeable -> Optional.ofNullable(facadeable.getFacade()));
5✔
520
    }
521

522
    /**
523
     * Get the target's facade
524
     * @param world The world.
525
     * @param pos The position.
526
     * @param blockState The block state.
527
     * @return The optional facade.
528
     */
529
    public static Optional<BlockState> getFacade(ILevelExtension world, BlockPos pos, BlockState blockState) {
530
        return Optional.ofNullable(world.getCapability(Capabilities.Facadeable.BLOCK, pos, blockState, null, null))
11✔
531
                .flatMap(facadeable -> Optional.ofNullable(facadeable.getFacade()));
5✔
532
    }
533

534
    @Deprecated // TODO: attempt to migrate all calls to method with BlockState param
535
    public static boolean isLightTransparent(Level world, BlockPos pos, @Nullable Direction side) {
536
        return PartHelpers.getPartContainer(world, pos, side)
×
537
                .map(partContainer -> {
×
538
                    for (Map.Entry<Direction, IPartType<?, ?>> entry : partContainer.getParts().entrySet()) {
×
539
                        IPartType part = entry.getValue();
×
540
                        if (part.forceLightTransparency(partContainer.getPartState(entry.getKey()))) {
×
541
                            return true;
×
542
                        }
543
                    }
×
544
                    return false;
×
545
                })
546
                .orElse(false);
×
547
    }
548

549
    public static boolean isLightTransparent(Level world, BlockPos pos, @Nullable Direction side, BlockState blockState) {
550
        return PartHelpers.getPartContainer(world, pos, side, blockState)
×
551
                .map(partContainer -> {
×
552
                    for (Map.Entry<Direction, IPartType<?, ?>> entry : partContainer.getParts().entrySet()) {
×
553
                        IPartType part = entry.getValue();
×
554
                        if (part.forceLightTransparency(partContainer.getPartState(entry.getKey()))) {
×
555
                            return true;
×
556
                        }
557
                    }
×
558
                    return false;
×
559
                })
560
                .orElse(false);
×
561
    }
562

563
    /**
564
     * Get the sides the cable is currently connected to.
565
     * @param cable A cable.
566
     * @return The cable connections.
567
     */
568
    public static Collection<Direction> getCableConnections(ICable cable) {
569
        Collection<Direction> sides = Sets.newIdentityHashSet();
2✔
570
        for (Direction side : Direction.values()) {
16✔
571
            if (cable.isConnected(side)) {
4✔
572
                sides.add(side);
4✔
573
            }
574
        }
575
        return sides;
2✔
576
    }
577

578
    /**
579
     * Get the sides that are externally connected to the given position.
580
     * @param world The world.
581
     * @param pos The position.
582
     * @return The sides.
583
     */
584
    public static Collection<Direction> getExternallyConnectedCables(Level world, BlockPos pos) {
585
        Collection<Direction> sides = Sets.newIdentityHashSet();
2✔
586
        for (Direction side : Direction.values()) {
16✔
587
            if (CableHelpers.isCableConnected(world, pos.relative(side), side.getOpposite(), null)) {
9✔
588
                sides.add(side);
4✔
589
            }
590
        }
591
        return sides;
2✔
592
    }
593
}
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