• 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

68.37
/src/main/java/org/cyclops/integrateddynamics/item/ItemBlockCable.java
1
package org.cyclops.integrateddynamics.item;
2

3
import com.google.common.collect.Lists;
4
import net.minecraft.core.BlockPos;
5
import net.minecraft.core.Direction;
6
import net.minecraft.sounds.SoundSource;
7
import net.minecraft.world.InteractionResult;
8
import net.minecraft.world.item.BlockItem;
9
import net.minecraft.world.item.Item;
10
import net.minecraft.world.item.ItemStack;
11
import net.minecraft.world.item.context.BlockPlaceContext;
12
import net.minecraft.world.item.context.UseOnContext;
13
import net.minecraft.world.level.Level;
14
import net.minecraft.world.level.block.Block;
15
import net.minecraft.world.level.block.SoundType;
16
import net.minecraft.world.level.block.state.BlockState;
17
import org.cyclops.integrateddynamics.RegistryEntries;
18
import org.cyclops.integrateddynamics.api.block.cable.ICableFakeable;
19
import org.cyclops.integrateddynamics.block.BlockCable;
20
import org.cyclops.integrateddynamics.core.helper.CableHelpers;
21

22
import javax.annotation.Nullable;
23
import java.util.List;
24

25
/**
26
 * The item for the cable.
27
 * @author rubensworks
28
 */
29
public class ItemBlockCable extends BlockItem {
30

31
    private static final List<IUseAction> USE_ACTIONS = Lists.newArrayList();
3✔
32

33
    public ItemBlockCable(Block block, Item.Properties builder) {
34
        super(block, builder);
4✔
35
    }
1✔
36

37
    /**
38
     * Register a use action for the cable item.
39
     * @param useAction The use action.
40
     */
41
    public static void addUseAction(IUseAction useAction) {
42
        USE_ACTIONS.add(useAction);
×
43
    }
×
44

45
    protected boolean checkCableAt(Level world, BlockPos pos, @Nullable Direction side) {
46
        if (!CableHelpers.isNoFakeCable(world, pos, side) && CableHelpers.getCable(world, pos, side) != null) {
5!
47
            return true;
×
48
        }
49
        for (IUseAction useAction : USE_ACTIONS) {
6!
50
            if (useAction.canPlaceAt(world, pos)) {
×
51
                return true;
×
52
            }
53
        }
×
54
        return false;
2✔
55
    }
56

57
    @Override
58
    protected boolean canPlace(BlockPlaceContext context, BlockState blockState) {
59
        Level world = context.getLevel();
3✔
60
        BlockPos pos = context.getClickedPos();
3✔
61
        Direction side = context.getClickedFace();
3✔
62
        BlockPos target = pos.relative(side);
4✔
63
        // First check if the target is an unreal cable.
64
        if(checkCableAt(world, pos, side)) return true;
6!
65
        // Then check if the target is covered by an unreal cable at the given side.
66
        if(checkCableAt(world, target, side.getOpposite())) return true;
7!
67
        // Skips client-side entity collision detection for placing cables.
68
        return (!this.mustSurvive() || blockState.canSurvive(context.getLevel(), target));
12!
69
    }
70

71
    protected boolean attempItemUseTarget(UseOnContext context, BlockPos pos, Direction side, BlockCable blockCable, boolean offsetAdded) {
72
        BlockState blockState = context.getLevel().getBlockState(pos);
5✔
73
        if(!context.getLevel().isEmptyBlock(pos)) {
5✔
74
            ICableFakeable cable = CableHelpers.getCableFakeable(context.getLevel(), pos, side).orElse(null);
9✔
75
            if (cable != null && !cable.isRealCable()) {
5!
76
                if (!context.getLevel().isClientSide()) {
4!
77
                    cable.setRealCable(true);
3✔
78
                    CableHelpers.updateConnections(context.getLevel(), pos, side);
5✔
79
                    CableHelpers.onCableAddedByPlayerActual(context.getLevel(), pos, context.getPlayer());
6✔
80
                }
81
                return true;
2✔
82
            }
83
            if(!offsetAdded){
2!
84
                for (IUseAction useAction : USE_ACTIONS) {
×
85
                    if (useAction.attempItemUseTarget(context.getItemInHand(), context.getLevel(), pos, blockCable)) {
×
86
                        return true;
×
87
                    }
88
                }
×
89
            }
90
        }
91
        return false;
2✔
92
    }
93

94
    protected void afterItemUse(UseOnContext context, BlockPos pos, BlockCable blockCable, boolean calledSuper) {
95
        if(!calledSuper) {
2✔
96
            playPlaceSound(context.getLevel(), pos);
4✔
97
            if (context.getItemInHand().getItem() == RegistryEntries.ITEM_CABLE.get()) {
6!
98
                context.getItemInHand().shrink(1);
4✔
99
            }
100
        }
101
        blockCable.setDisableCollisionBox(false);
3✔
102
    }
1✔
103

104
    @SuppressWarnings("deprecation")
105
    public static void playPlaceSound(Level world, BlockPos pos) {
106
        Block block = RegistryEntries.BLOCK_CABLE.get();
4✔
107
        SoundType soundType = block.defaultBlockState().getSoundType();
4✔
108
        world.playLocalSound((double) ((float) pos.getX() + 0.5F), (double) ((float) pos.getY() + 0.5F), (double) ((float) pos.getZ() + 0.5F),
21✔
109
                soundType.getPlaceSound(), SoundSource.BLOCKS, (soundType.getVolume() + 1.0F) / 2.0F, soundType.getPitch() * 0.8F, false);
13✔
110
    }
1✔
111

112
    public static void playBreakSound(Level world, BlockPos pos, BlockState blockState) {
113
        world.globalLevelEvent(2001, pos, Block.getId(blockState));
6✔
114
    }
1✔
115

116
    @Override
117
    public InteractionResult useOn(UseOnContext context) {
118
        ItemStack itemStack = context.getItemInHand();
3✔
119
        // Skips server-side entity collision detection for placing cables.
120
        // We temporary disable the collision box of the cable so that it can be placed even if an entity is in the way.
121
        BlockCable blockCable = (BlockCable) getBlock();
4✔
122
        blockCable.setDisableCollisionBox(true);
3✔
123

124
        // Avoid regular block placement when the target is an unreal cable.
125
        if(attempItemUseTarget(context, context.getClickedPos(), context.getClickedFace(), blockCable, false)) {
10!
126
            afterItemUse(context, context.getClickedPos(), blockCable, false);
×
127
            return InteractionResult.SUCCESS;
×
128
        }
129

130
        // Change pos and side when we are targeting a block that is blocked by an unreal cable, so we want to target
131
        // the unreal cable.
132
        BlockPos posOffset = context.getClickedPos().relative(context.getClickedFace());
6✔
133
        if(attempItemUseTarget(context, posOffset, context.getClickedFace().getOpposite(), blockCable, true)) {
10✔
134
            afterItemUse(context, posOffset, blockCable, false);
6✔
135
            return InteractionResult.SUCCESS;
2✔
136
        }
137

138
        InteractionResult ret = super.useOn(context);
4✔
139
        afterItemUse(context, context.getClickedPos(), blockCable, true);
7✔
140
        return ret;
2✔
141
    }
142

143
    public static interface IUseAction {
144

145
        /**
146
         * Attempt to use the given item.
147
         * @param itemStack The item stack that is being used.
148
         * @param world The world.
149
         * @param pos The position.
150
         * @param blockCable The cable block instance.
151
         * @return If the use action was applied.
152
         */
153
        public boolean attempItemUseTarget(ItemStack itemStack, Level world, BlockPos pos, BlockCable blockCable);
154

155
        /**
156
         * If the block can be placed at the given position.
157
         * @param world The world.
158
         * @param pos The position.
159
         * @return If the block can be placed.
160
         */
161
        public boolean canPlaceAt(Level world, BlockPos pos);
162

163
    }
164

165
}
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