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

CyclopsMC / IntegratedDynamics / 20210191346

14 Dec 2025 03:32PM UTC coverage: 19.514% (-33.5%) from 53.061%
20210191346

push

github

rubensworks
Remove deprecations

663 of 8728 branches covered (7.6%)

Branch coverage included in aggregate %.

6786 of 29445 relevant lines covered (23.05%)

1.09 hits per line

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

3.31
/src/main/java/org/cyclops/integrateddynamics/core/item/ItemPart.java
1
package org.cyclops.integrateddynamics.core.item;
2

3
import com.google.common.collect.Lists;
4
import lombok.EqualsAndHashCode;
5
import net.minecraft.core.BlockPos;
6
import net.minecraft.core.Direction;
7
import net.minecraft.network.chat.Component;
8
import net.minecraft.world.InteractionHand;
9
import net.minecraft.world.InteractionResult;
10
import net.minecraft.world.entity.player.Player;
11
import net.minecraft.world.item.Item;
12
import net.minecraft.world.item.ItemStack;
13
import net.minecraft.world.item.TooltipFlag;
14
import net.minecraft.world.item.component.TooltipDisplay;
15
import net.minecraft.world.item.context.BlockPlaceContext;
16
import net.minecraft.world.item.context.UseOnContext;
17
import net.minecraft.world.level.Level;
18
import net.minecraft.world.level.block.state.BlockState;
19
import net.minecraft.world.phys.BlockHitResult;
20
import net.minecraft.world.phys.Vec3;
21
import org.cyclops.integrateddynamics.IntegratedDynamics;
22
import org.cyclops.integrateddynamics.RegistryEntries;
23
import org.cyclops.integrateddynamics.api.block.cable.ICableFakeable;
24
import org.cyclops.integrateddynamics.api.part.IPartContainer;
25
import org.cyclops.integrateddynamics.api.part.IPartState;
26
import org.cyclops.integrateddynamics.api.part.IPartType;
27
import org.cyclops.integrateddynamics.api.part.PartPos;
28
import org.cyclops.integrateddynamics.core.helper.CableHelpers;
29
import org.cyclops.integrateddynamics.core.helper.NetworkHelpers;
30
import org.cyclops.integrateddynamics.core.helper.PartHelpers;
31
import org.cyclops.integrateddynamics.item.ItemBlockCable;
32

33
import java.util.List;
34
import java.util.function.Consumer;
35

36
/**
37
 * An item that can place parts.
38
 * @author rubensworks
39
 */
40
@EqualsAndHashCode(callSuper = false)
×
41
public class ItemPart<P extends IPartType<P, S>, S extends IPartState<P>> extends Item {
42

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

45
    private final IPartType<P, S> part;
46

47
    public ItemPart(Item.Properties properties, IPartType<P, S> part) {
48
        super(properties);
3✔
49
        this.part = part;
3✔
50
    }
1✔
51

52
    public IPartType<P, S> getPart() {
53
        return part;
×
54
    }
55

56
    /**
57
     * Register a use action for the cable item.
58
     * @param useAction The use action.
59
     */
60
    public static void addUseAction(IUseAction useAction) {
61
        USE_ACTIONS.add(useAction);
×
62
    }
×
63

64
    @Override
65
    public Component getName(ItemStack p_200295_1_) {
66
        return Component.translatable(getDescriptionId());
×
67
    }
68

69
    @Override
70
    public InteractionResult useOn(UseOnContext context) {
71
        Level world = context.getLevel();
×
72
        Player player = context.getPlayer();
×
73
        InteractionHand hand = context.getHand();
×
74
        BlockPos pos = context.getClickedPos();
×
75
        Direction side = context.getClickedFace();
×
76
        BlockState blockState = world.getBlockState(pos);
×
77

78
        ItemStack itemStack = player.getItemInHand(hand);
×
79
        IPartContainer partContainerFirst = PartHelpers.getPartContainer(world, pos, side, blockState).orElse(null);
×
80
        if(partContainerFirst != null) {
×
81
            // Add part to existing cable
82
            if(PartHelpers.addPart(world, pos, side, getPart(), itemStack)) {
×
83
                if(world.isClientSide()) {
×
84
                    ItemBlockCable.playPlaceSound(world, pos);
×
85
                }
86
                if(!player.isCreative()) {
×
87
                    itemStack.shrink(1);
×
88
                }
89
            }
90
            return InteractionResult.SUCCESS;
×
91
        } else {
92
            // Place part at a new position with an unreal cable
93
            BlockPos target = pos.relative(side);
×
94
            Direction targetSide = side.getOpposite();
×
95
            BlockHitResult targetRayTrace = new BlockHitResult(new Vec3(
×
96
                    (double) target.getX() + 0.5D + (double) targetSide.getStepX() * 0.5D,
×
97
                    (double) target.getY() + 0.5D + (double) targetSide.getStepY() * 0.5D,
×
98
                    (double) target.getZ() + 0.5D + (double) targetSide.getStepZ() * 0.5D),
×
99
                    targetSide, target, false);
100
            if(world.getBlockState(target).canBeReplaced(new BlockPlaceContext(world, player, hand, itemStack, targetRayTrace.withPosition(target)))) {
×
101
                ItemBlockCable itemBlockCable = (ItemBlockCable) Item.byBlock(RegistryEntries.BLOCK_CABLE.get());
×
102
                itemStack.grow(1); // Temporarily grow, because ItemBlock will shrink it.
×
103
                if (itemBlockCable.useOn(new UseOnContext(player, hand, targetRayTrace)).consumesAction()) {
×
104
                    BlockState targetBlockState = world.getBlockState(target);
×
105
                    IPartContainer partContainer = PartHelpers.getPartContainer(world, target, targetSide, targetBlockState).orElse(null);
×
106
                    if (partContainer != null) {
×
107
                        ICableFakeable cableFakeable = CableHelpers.getCableFakeable(world, target, targetSide, targetBlockState).orElse(null);
×
108
                        if(!world.isClientSide()) {
×
109
                            PartHelpers.addPart(world, target, side.getOpposite(), getPart(), itemStack);
×
110
                            if (cableFakeable != null) {
×
111
                                CableHelpers.onCableRemoving(world, target, false, false, world.getBlockState(target), world.getBlockEntity(target));
×
112
                                cableFakeable.setRealCable(false);
×
113
                                CableHelpers.overrideCableRemovingConnections(world, target, CableHelpers.ALL_SIDES);
×
114
                                CableHelpers.onCableRemoved(world, target);
×
115
                            } else {
116
                                IntegratedDynamics.clog(org.apache.logging.log4j.Level.WARN, String.format("Tried to set a fake cable at a block that is not fakeable at %s", target));
×
117
                            }
118
                        } else {
119
                            cableFakeable.setRealCable(false);
×
120
                        }
121
                        itemStack.shrink(1);
×
122
                        return InteractionResult.SUCCESS;
×
123
                    }
124
                }
125
                itemStack.shrink(1); // Shrink manually if failed
×
126
            } else {
×
127
                BlockState targetBlockState = world.getBlockState(target);
×
128
                IPartContainer partContainer = PartHelpers.getPartContainer(world, target, targetSide, targetBlockState).orElse(null);
×
129
                if(partContainer != null) {
×
130
                    // Edge-case: if the pos was a full network block (part of the same network as target), make sure that we disconnect this part of the network first
131
                    if (!world.isClientSide() && NetworkHelpers.getNetwork(PartPos.of(world, pos, side)).isPresent() && partContainer.canAddPart(targetSide, getPart())) {
×
132
                        CableHelpers.getCable(world, target, targetSide)
×
133
                                .ifPresent(cable -> CableHelpers.disconnectCable(world, target, targetSide, cable, targetSide));
×
134
                    }
135

136
                    // Add part to existing cable
137
                    if(PartHelpers.addPart(world, target, side.getOpposite(), getPart(), itemStack)) {
×
138
                        if(world.isClientSide()) {
×
139
                            ItemBlockCable.playPlaceSound(world, target);
×
140
                        }
141
                        if(!player.isCreative()) {
×
142
                            itemStack.shrink(1);
×
143
                        }
144
                    }
145
                    return InteractionResult.SUCCESS;
×
146
                }
147
            }
148

149
            // Check third party actions if all else fails
150
            for (IUseAction useAction : USE_ACTIONS) {
×
151
                if (useAction.attempItemUseTarget(this, itemStack, world, pos, side)) {
×
152
                    return InteractionResult.SUCCESS;
×
153
                }
154
            }
×
155
        }
156
        return super.useOn(context);
×
157
    }
158

159
    @Override
160
    public void appendHoverText(ItemStack itemStack, Item.TooltipContext context, TooltipDisplay tooltipDisplay, Consumer<Component> tooltipAdder, TooltipFlag flag) {
161
        getPart().loadTooltip(itemStack, tooltipAdder);
×
162
        super.appendHoverText(itemStack, context, tooltipDisplay, tooltipAdder, flag);
×
163
    }
×
164

165
    public static interface IUseAction {
166

167
        /**
168
         * Attempt to use the given item.
169
         * @param itemPart The part item instance.
170
         * @param itemStack The item stack that is being used.
171
         * @param world The world.
172
         * @param pos The position.
173
         * @param sideHit The side that is being hit.
174
         * @return If the use action was applied.
175
         */
176
        public boolean attempItemUseTarget(ItemPart itemPart, ItemStack itemStack, Level world, BlockPos pos, Direction sideHit);
177

178
    }
179

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