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

CyclopsMC / IntegratedDynamics / 22186773560

19 Feb 2026 02:52PM UTC coverage: 52.603% (+0.2%) from 52.363%
22186773560

push

github

web-flow
Remove Lombok dependency (#1604)

2911 of 8664 branches covered (33.6%)

Branch coverage included in aggregate %.

17683 of 30486 relevant lines covered (58.0%)

3.01 hits per line

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

50.83
/src/main/java/org/cyclops/integrateddynamics/core/part/PartTypeBase.java
1
package org.cyclops.integrateddynamics.core.part;
2

3
import net.minecraft.core.BlockPos;
4
import net.minecraft.core.Direction;
5
import net.minecraft.nbt.CompoundTag;
6
import net.minecraft.network.RegistryFriendlyByteBuf;
7
import net.minecraft.network.chat.Component;
8
import net.minecraft.resources.Identifier;
9
import net.minecraft.server.level.ServerPlayer;
10
import net.minecraft.world.InteractionHand;
11
import net.minecraft.world.InteractionResult;
12
import net.minecraft.world.entity.player.Player;
13
import net.minecraft.world.item.Item;
14
import net.minecraft.world.item.ItemStack;
15
import net.minecraft.world.level.Level;
16
import net.minecraft.world.level.block.Block;
17
import net.minecraft.world.level.block.state.BlockBehaviour;
18
import net.minecraft.world.level.block.state.BlockState;
19
import net.minecraft.world.phys.BlockHitResult;
20
import org.cyclops.cyclopscore.config.extendedconfig.BlockConfigCommon;
21
import org.cyclops.cyclopscore.datastructure.DimPos;
22
import org.cyclops.cyclopscore.init.ModBaseNeoForge;
23
import org.cyclops.integrateddynamics.GeneralConfig;
24
import org.cyclops.integrateddynamics.IntegratedDynamics;
25
import org.cyclops.integrateddynamics.RegistryEntries;
26
import org.cyclops.integrateddynamics.api.network.INetwork;
27
import org.cyclops.integrateddynamics.api.network.INetworkElement;
28
import org.cyclops.integrateddynamics.api.network.IPartNetworkElement;
29
import org.cyclops.integrateddynamics.api.network.event.INetworkEvent;
30
import org.cyclops.integrateddynamics.api.part.*;
31
import org.cyclops.integrateddynamics.core.block.IgnoredBlock;
32
import org.cyclops.integrateddynamics.core.helper.L10NValues;
33
import org.cyclops.integrateddynamics.core.helper.PartHelpers;
34
import org.cyclops.integrateddynamics.core.item.ItemPart;
35
import org.cyclops.integrateddynamics.core.network.PartNetworkElement;
36
import org.cyclops.integrateddynamics.item.ItemEnhancement;
37
import org.cyclops.integrateddynamics.item.ItemWrench;
38

39
import java.util.*;
40
import java.util.function.Consumer;
41

42
/**
43
 * An abstract {@link IPartType} with a default implementation for creating
44
 * network elements.
45
 * @author rubensworks
46
 */
47
public abstract class PartTypeBase<P extends IPartType<P, S>, S extends IPartState<P>>
48
        extends PartTypeAdapter<P, S> {
49

50
    private Item item;
51
    private Block block;
52
    private final String name;
53
    private final PartRenderPosition partRenderPosition;
54
    private final Map<Class<? extends INetworkEvent>, IEventAction> networkEventActions;
55

56
    public Item getItem() {
57
        return item;
3✔
58
    }
59

60
    public Block getBlock() {
61
        return block;
3✔
62
    }
63

64
    public PartRenderPosition getPartRenderPosition() {
65
        return partRenderPosition;
3✔
66
    }
67

68
    public PartTypeBase(String name, PartRenderPosition partRenderPosition) {
2✔
69
        this.name = name;
3✔
70
        this.partRenderPosition = partRenderPosition;
3✔
71

72
        networkEventActions = constructNetworkEventActions();
4✔
73

74
        registerBlock();
2✔
75
    }
1✔
76

77
    @Override
78
    public Identifier getUniqueName() {
79
        return Identifier.fromNamespaceAndPath(getModId(), this.name);
6✔
80
    }
81

82
    protected ModBaseNeoForge getMod() {
83
        return IntegratedDynamics._instance;
2✔
84
    }
85

86
    protected String getModId() {
87
        return getMod().getModId();
4✔
88
    }
89

90
    /**
91
     * Creates and registers a block instance for this part type.
92
     * This is mainly used for the block facadeModel.
93
     */
94
    protected void registerBlock() {
95
        BlockConfigCommon blockConfig = new BlockConfigCommon<>(getMod(), "part_" + this.name,
14✔
96
                (eConfig, properties) -> block = createBlock(eConfig, properties),
8✔
97
                (eConfig, block) -> item  = createItem(eConfig, block)) {
18✔
98
            @Override
99
            public String getFullTranslationKey() {
100
                return PartTypeBase.this.getTranslationKey();
×
101
            }
102

103
            @Override
104
            public Collection<ItemStack> getDefaultCreativeTabEntries() {
105
                return Collections.singleton(new ItemStack(getItemInstance()));
7✔
106
            }
107
        };
108
        getMod().getConfigHandler().addConfigurable(blockConfig);
6✔
109
    }
1✔
110

111
    /**
112
     * Factory method for creating a block instance.
113
     *
114
     * @param blockConfig The config to register the block for.
115
     * @param properties
116
     * @return The block instance.
117
     */
118
    protected Block createBlock(BlockConfigCommon<?> blockConfig, BlockBehaviour.Properties properties) {
119
        return new IgnoredBlock(properties);
5✔
120
    }
121

122
    /**
123
     * Factory method for creating a item instance.
124
     * @param blockConfig The block config to register the item for.
125
     * @param block The block corresponding to the item.
126
     * @return The item instance.
127
     */
128
    protected Item createItem(BlockConfigCommon<?> blockConfig, Block block) {
129
        return new ItemPart<>(blockConfig.createDefaultItemProperties()
6✔
130
                .overrideDescription(this.getTranslationKey()), this);
4✔
131
    }
132

133
    @Override
134
    public Identifier getBlockModelPath() {
135
        return Identifier.fromNamespaceAndPath(getModId(), "part_" + this.name);
×
136
    }
137

138
    @Override
139
    protected String createTranslationKey() {
140
        return "parttype." + getModId() + "." + this.name;
6✔
141
    }
142

143
    @SuppressWarnings("unchecked")
144
    @Override
145
    public INetworkElement createNetworkElement(IPartContainer partContainer, DimPos pos, Direction side) {
146
        return new PartNetworkElement(this, PartPos.of(pos, side));
8✔
147
    }
148

149
    @Override
150
    public InteractionResult onPartActivated(S partState, BlockPos pos, Level world, Player player, InteractionHand hand,
151
                                            ItemStack heldItem, BlockHitResult hit) {
152
        // Drop through if the player is sneaking
153
        if(player.isSecondaryUseActive()) {
3!
154
            return InteractionResult.PASS;
×
155
        }
156

157
        // Consume enhancement
158
        if (heldItem.getItem() instanceof ItemEnhancement itemEnhancement) {
9!
159
            InteractionResult result = itemEnhancement.applyEnhancement(this, partState, heldItem, player, hand);
8✔
160
            if (result.consumesAction()) {
3!
161
                return result;
2✔
162
            }
163
        }
164

165
        // Set offset and side
166
        PartPos partPos = PartPos.of(world, pos, hit.getDirection());
×
167
        if (heldItem.getItem() instanceof ItemWrench itemWrench) {
×
168
            InteractionResult result = itemWrench.performPartAction(hit, this, partState, heldItem, player, hand, partPos);
×
169
            if (result.consumesAction()) {
×
170
                return result;
×
171
            }
172
        }
173

174
        if(getContainerProvider(partPos).isPresent()) {
×
175
            if (!world.isClientSide()) {
×
176
                return PartHelpers.openContainerPart((ServerPlayer) player, partPos, this);
×
177
            }
178
            return InteractionResult.SUCCESS;
×
179
        }
180
        return InteractionResult.PASS;
×
181
    }
182

183
    @Override
184
    public void addDrops(PartTarget target, S state, List<ItemStack> itemStacks, boolean dropMainElement, boolean saveState) {
185
        super.addDrops(target, state, itemStacks, dropMainElement, saveState);
7✔
186

187
        // Save enhancements
188
        if (!saveState && state.getMaxOffset() > 0) {
5✔
189
            // Drop Part Offset items each with as maximum the GeneralConfig.enchancementOffsetPartDropValue offset value.
190
            int remainingOffset = state.getMaxOffset();
3✔
191
            while (remainingOffset > 0) {
2✔
192
                int offset;
193
                if (remainingOffset < GeneralConfig.enchancementOffsetPartDropValue) {
3!
194
                    offset = remainingOffset;
×
195
                } else {
196
                    offset = GeneralConfig.enchancementOffsetPartDropValue;
2✔
197
                }
198
                remainingOffset -= offset;
4✔
199

200
                ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_ENHANCEMENT_OFFSET);
5✔
201
                RegistryEntries.ITEM_ENHANCEMENT_OFFSET.get().setEnhancementValue(itemStack, offset);
6✔
202
                itemStacks.add(itemStack);
4✔
203
            }
1✔
204
            state.setMaxOffset(0);
3✔
205
        }
206
    }
1✔
207

208
    @Override
209
    public BlockState getBlockState(IPartContainer partContainer, Direction side) {
210
        return getBlock().defaultBlockState()
×
211
                .setValue(IgnoredBlock.FACING, side);
×
212
    }
213

214
    @Override
215
    public BlockState getBaseBlockState() {
216
        return getBlock().defaultBlockState();
×
217
    }
218

219
    @Override
220
    public void loadTooltip(S state, List<Component> lines) {
221
        if(!state.isEnabled()) {
×
222
            lines.add(Component.translatable(L10NValues.PART_TOOLTIP_DISABLED));
×
223
        }
224
        lines.add(Component.translatable(L10NValues.GENERAL_ITEM_ID, state.getId()));
×
225

226
        if (state.getMaxOffset() > 0) {
×
227
            lines.add(Component.translatable(L10NValues.PART_TOOLTIP_MAXOFFSET, state.getMaxOffset()));
×
228
        }
229
    }
×
230

231
    @Override
232
    public void loadTooltip(ItemStack itemStack, Consumer<Component> tooltipAdder) {
233
        if(itemStack.has(RegistryEntries.DATACOMPONENT_PART_STATE)) {
×
234
            CompoundTag tag = itemStack.get(RegistryEntries.DATACOMPONENT_PART_STATE);
×
235
            if(tag.contains("id")) {
×
236
                int id = tag.getInt("id").orElseThrow();
×
237
                tooltipAdder.accept(Component.translatable(L10NValues.GENERAL_ITEM_ID, id));
×
238
            }
239
            if(tag.contains("maxOffset")) {
×
240
                int maxOffset = tag.getInt("maxOffset").orElseThrow();
×
241
                tooltipAdder.accept(Component.translatable(L10NValues.PART_TOOLTIP_MAXOFFSET, maxOffset));
×
242
            }
243
        }
244

245
        super.loadTooltip(itemStack, tooltipAdder);
×
246
    }
×
247

248
    /**
249
     * Override this to register your network event actions.
250
     * @return The event actions.
251
     */
252
    protected Map<Class<? extends INetworkEvent>, IEventAction> constructNetworkEventActions() {
253
        return new IdentityHashMap<>();
4✔
254
    }
255

256
    @Override
257
    public final boolean hasEventSubscriptions() {
258
        return !networkEventActions.isEmpty();
8✔
259
    }
260

261
    @Override
262
    public final Set<Class<? extends INetworkEvent>> getSubscribedEvents() {
263
        return networkEventActions.keySet();
4✔
264
    }
265

266
    @SuppressWarnings("unchecked")
267
    @Override
268
    public final void onEvent(INetworkEvent event, IPartNetworkElement<P, S> networkElement) {
269
        if (networkElement.getTarget().getCenter().getPos().isLoaded()) {
6!
270
            networkEventActions.get(event.getClass()).onAction(event.getNetwork(), networkElement.getTarget(),
12✔
271
                    networkElement.getPartState(), event);
2✔
272
        }
273
    }
1✔
274

275
    @Override
276
    public boolean forceLightTransparency(S state) {
277
        return false;
×
278
    }
279

280
    @Override
281
    public void writeExtraGuiData(RegistryFriendlyByteBuf packetBuffer, PartPos pos, ServerPlayer player) {
282
        packetBuffer.writeUtf(this.getUniqueName().toString());
×
283
    }
×
284

285
    public interface IEventAction<P extends IPartType<P, S>, S extends IPartState<P>, E extends INetworkEvent> {
286

287
        public void onAction(INetwork network, PartTarget target, S state, E event);
288

289
    }
290

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