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

CyclopsMC / IntegratedDynamics / 19256462200

11 Nov 2025 05:53AM UTC coverage: 44.841% (+0.009%) from 44.832%
19256462200

push

github

rubensworks
Fix Grass Block Facades not having biome tints

Closes #1564

2583 of 8544 branches covered (30.23%)

Branch coverage included in aggregate %.

11777 of 23480 relevant lines covered (50.16%)

2.38 hits per line

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

80.63
/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.BlockGetter;
12
import net.minecraft.world.level.Level;
13
import net.minecraft.world.level.block.Block;
14
import net.minecraft.world.level.block.state.BlockState;
15
import net.neoforged.neoforge.common.NeoForge;
16
import net.neoforged.neoforge.common.extensions.ILevelExtension;
17
import org.cyclops.cyclopscore.helper.BlockEntityHelpers;
18
import org.cyclops.cyclopscore.helper.IModHelpers;
19
import org.cyclops.cyclopscore.helper.ItemStackHelpers;
20
import org.cyclops.integrateddynamics.Capabilities;
21
import org.cyclops.integrateddynamics.api.block.IFacadeable;
22
import org.cyclops.integrateddynamics.api.block.cable.ICable;
23
import org.cyclops.integrateddynamics.api.block.cable.ICableFakeable;
24
import org.cyclops.integrateddynamics.api.network.INetwork;
25
import org.cyclops.integrateddynamics.api.network.INetworkCarrier;
26
import org.cyclops.integrateddynamics.api.network.INetworkElement;
27
import org.cyclops.integrateddynamics.api.network.INetworkElementProvider;
28
import org.cyclops.integrateddynamics.api.part.IPartContainer;
29
import org.cyclops.integrateddynamics.api.part.IPartType;
30
import org.cyclops.integrateddynamics.api.path.IPathElement;
31
import org.cyclops.integrateddynamics.capability.facadeable.FacadeableTileMultipartTicking;
32
import org.cyclops.integrateddynamics.core.blockentity.BlockEntityMultipartTicking;
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.Collection;
39
import java.util.List;
40
import java.util.Map;
41
import java.util.Optional;
42

43
/**
44
 * Helpers related to cables.
45
 * @author rubensworks
46
 */
47
public class CableHelpers {
×
48

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

308
    private static WeakReference<LivingEntity> CABLE_PLACER_SNAPSHOT = new WeakReference<>(null);
5✔
309

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

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

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

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

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

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

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

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

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

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

465
        ItemBlockCable.playBreakSound(world, pos, blockState);
4✔
466

467
        removingCable = false;
2✔
468
    }
1✔
469

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

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

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

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

520
    /**
521
     * Get the target's facade from {@link BlockEntityMultipartTicking} without going through capabilities.
522
     * This is necessary because some BlockColor's rely on BlockGetter, which do not support capabilities.
523
     * @param world The world.
524
     * @param pos The position.
525
     * @return The optional facade.
526
     */
527
    public static Optional<BlockState> getFacadeMultipartTicking(BlockGetter world, BlockPos pos) {
528
        return IModHelpers.get().getBlockEntityHelpers().get(world, pos, BlockEntityMultipartTicking.class)
×
529
                .flatMap(blockEntity -> Optional.ofNullable(new FacadeableTileMultipartTicking(blockEntity).getFacade()));
×
530
    }
531

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

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

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

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