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

CyclopsMC / IntegratedDynamics / 18042102834

26 Sep 2025 03:25PM UTC coverage: 44.791% (-0.1%) from 44.905%
18042102834

push

github

rubensworks
Merge remote-tracking branch 'origin/master-1.20-lts' into master-1.21-lts

2572 of 8540 branches covered (30.12%)

Branch coverage included in aggregate %.

11761 of 23460 relevant lines covered (50.13%)

2.38 hits per line

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

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

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

40
import java.util.*;
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
    @Getter
3✔
51
    private Item item;
52
    @Getter
3✔
53
    private Block block;
54
    private final String name;
55
    @Getter
3✔
56
    private final PartRenderPosition partRenderPosition;
57
    private final Map<Class<? extends INetworkEvent>, IEventAction> networkEventActions;
58

59
    public PartTypeBase(String name, PartRenderPosition partRenderPosition) {
2✔
60
        this.name = name;
3✔
61
        this.partRenderPosition = partRenderPosition;
3✔
62

63
        networkEventActions = constructNetworkEventActions();
4✔
64

65
        registerBlock();
2✔
66
    }
1✔
67

68
    @Override
69
    public ResourceLocation getUniqueName() {
70
        return ResourceLocation.fromNamespaceAndPath(getModId(), this.name);
6✔
71
    }
72

73
    protected ModBase getMod() {
74
        return IntegratedDynamics._instance;
2✔
75
    }
76

77
    protected String getModId() {
78
        return getMod().getModId();
4✔
79
    }
80

81
    /**
82
     * Creates and registers a block instance for this part type.
83
     * This is mainly used for the block model.
84
     */
85
    protected void registerBlock() {
86
        BlockConfig blockConfig = new BlockConfig(getMod(), "part_" + this.name,
14✔
87
                (eConfig)        -> block = createBlock(eConfig),
7✔
88
                (eConfig, block) -> item  = createItem(eConfig, block)) {
18✔
89
            @Override
90
            public String getFullTranslationKey() {
91
                return PartTypeBase.this.getTranslationKey();
×
92
            }
93

94
            @Override
95
            protected Collection<ItemStack> defaultCreativeTabEntries() {
96
                return Collections.singleton(new ItemStack(getItemInstance()));
7✔
97
            }
98
        };
99
        getMod().getConfigHandler().addConfigurable(blockConfig);
6✔
100
    }
1✔
101

102
    /**
103
     * Factory method for creating a block instance.
104
     * @param blockConfig The config to register the block for.
105
     * @return The block instance.
106
     */
107
    protected Block createBlock(BlockConfig blockConfig) {
108
        return new IgnoredBlock();
4✔
109
    }
110

111
    /**
112
     * Factory method for creating a item instance.
113
     * @param blockConfig The block config to register the item for.
114
     * @param block The block corresponding to the item.
115
     * @return The item instance.
116
     */
117
    protected Item createItem(BlockConfig blockConfig, Block block) {
118
        return new ItemPart<>(new Item.Properties(), this);
8✔
119
    }
120

121
    @Override
122
    public ResourceLocation getBlockModelPath() {
123
        return ResourceLocation.fromNamespaceAndPath(getModId(), "part_" + this.name);
×
124
    }
125

126
    @Override
127
    protected String createTranslationKey() {
128
        return "parttype." + getModId() + "." + this.name;
6✔
129
    }
130

131
    @SuppressWarnings("unchecked")
132
    @Override
133
    public INetworkElement createNetworkElement(IPartContainer partContainer, DimPos pos, Direction side) {
134
        return new PartNetworkElement(this, PartPos.of(pos, side));
8✔
135
    }
136

137
    @Override
138
    public InteractionResult onPartActivated(S partState, BlockPos pos, Level world, Player player, InteractionHand hand,
139
                                            ItemStack heldItem, BlockHitResult hit) {
140
        // Drop through if the player is sneaking
141
        if(player.isSecondaryUseActive()) {
3!
142
            return InteractionResult.PASS;
×
143
        }
144

145
        // Consume enhancement
146
        if (heldItem.getItem() instanceof ItemEnhancement itemEnhancement) {
9!
147
            InteractionResult result = itemEnhancement.applyEnhancement(this, partState, heldItem, player, hand);
8✔
148
            if (result.consumesAction()) {
3!
149
                return result;
2✔
150
            }
151
        }
152

153
        // Set offset and side
154
        PartPos partPos = PartPos.of(world, pos, hit.getDirection());
×
155
        if (heldItem.getItem() instanceof ItemWrench itemWrench) {
×
156
            InteractionResult result = itemWrench.performPartAction(hit, this, partState, heldItem, player, hand, partPos);
×
157
            if (result.consumesAction()) {
×
158
                return result;
×
159
            }
160
        }
161

162
        if(getContainerProvider(partPos).isPresent()) {
×
163
            if (!world.isClientSide()) {
×
164
                return PartHelpers.openContainerPart((ServerPlayer) player, partPos, this);
×
165
            }
166
            return InteractionResult.SUCCESS;
×
167
        }
168
        return InteractionResult.PASS;
×
169
    }
170

171
    @Override
172
    public void addDrops(PartTarget target, S state, List<ItemStack> itemStacks, boolean dropMainElement, boolean saveState) {
173
        super.addDrops(target, state, itemStacks, dropMainElement, saveState);
7✔
174

175
        // Save enhancements
176
        if (!saveState && state.getMaxOffset() > 0) {
5✔
177
            // Drop Part Offset items each with as maximum the GeneralConfig.enchancementOffsetPartDropValue offset value.
178
            int remainingOffset = state.getMaxOffset();
3✔
179
            while (remainingOffset > 0) {
2✔
180
                int offset;
181
                if (remainingOffset < GeneralConfig.enchancementOffsetPartDropValue) {
3!
182
                    offset = remainingOffset;
×
183
                } else {
184
                    offset = GeneralConfig.enchancementOffsetPartDropValue;
2✔
185
                }
186
                remainingOffset -= offset;
4✔
187

188
                ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_ENHANCEMENT_OFFSET);
5✔
189
                RegistryEntries.ITEM_ENHANCEMENT_OFFSET.get().setEnhancementValue(itemStack, offset);
6✔
190
                itemStacks.add(itemStack);
4✔
191
            }
1✔
192
            state.setMaxOffset(0);
3✔
193
        }
194
    }
1✔
195

196
    @Override
197
    public BlockState getBlockState(IPartContainer partContainer, Direction side) {
198
        return getBlock().defaultBlockState()
×
199
                .setValue(IgnoredBlock.FACING, side);
×
200
    }
201

202
    @Override
203
    public BlockState getBaseBlockState() {
204
        return getBlock().defaultBlockState();
×
205
    }
206

207
    @Override
208
    public void loadTooltip(S state, List<Component> lines) {
209
        if(!state.isEnabled()) {
×
210
            lines.add(Component.translatable(L10NValues.PART_TOOLTIP_DISABLED));
×
211
        }
212
        lines.add(Component.translatable(L10NValues.GENERAL_ITEM_ID, state.getId()));
×
213

214
        if (state.getMaxOffset() > 0) {
×
215
            lines.add(Component.translatable(L10NValues.PART_TOOLTIP_MAXOFFSET, state.getMaxOffset()));
×
216
        }
217
    }
×
218

219
    @Override
220
    public void loadTooltip(ItemStack itemStack, List<Component> lines) {
221
        if(itemStack.has(RegistryEntries.DATACOMPONENT_PART_STATE)) {
×
222
            CompoundTag tag = itemStack.get(RegistryEntries.DATACOMPONENT_PART_STATE);
×
223
            if(tag.contains("id", Tag.TAG_INT)) {
×
224
                int id = tag.getInt("id");
×
225
                lines.add(Component.translatable(L10NValues.GENERAL_ITEM_ID, id));
×
226
            }
227
            if(tag.contains("maxOffset", Tag.TAG_INT)) {
×
228
                int maxOffset = tag.getInt("maxOffset");
×
229
                lines.add(Component.translatable(L10NValues.PART_TOOLTIP_MAXOFFSET, maxOffset));
×
230
            }
231
        }
232

233
        super.loadTooltip(itemStack, lines);
×
234
    }
×
235

236
    /**
237
     * Override this to register your network event actions.
238
     * @return The event actions.
239
     */
240
    protected Map<Class<? extends INetworkEvent>, IEventAction> constructNetworkEventActions() {
241
        return new IdentityHashMap<>();
4✔
242
    }
243

244
    @Override
245
    public final boolean hasEventSubscriptions() {
246
        return !networkEventActions.isEmpty();
8✔
247
    }
248

249
    @Override
250
    public final Set<Class<? extends INetworkEvent>> getSubscribedEvents() {
251
        return networkEventActions.keySet();
4✔
252
    }
253

254
    @SuppressWarnings("unchecked")
255
    @Override
256
    public final void onEvent(INetworkEvent event, IPartNetworkElement<P, S> networkElement) {
257
        if (networkElement.getTarget().getCenter().getPos().isLoaded()) {
6!
258
            networkEventActions.get(event.getClass()).onAction(event.getNetwork(), networkElement.getTarget(),
12✔
259
                    networkElement.getPartState(), event);
2✔
260
        }
261
    }
1✔
262

263
    @Override
264
    public boolean forceLightTransparency(S state) {
265
        return false;
2✔
266
    }
267

268
    @Override
269
    public void writeExtraGuiData(RegistryFriendlyByteBuf packetBuffer, PartPos pos, ServerPlayer player) {
270
        packetBuffer.writeUtf(this.getUniqueName().toString());
×
271
    }
×
272

273
    public interface IEventAction<P extends IPartType<P, S>, S extends IPartState<P>, E extends INetworkEvent> {
274

275
        public void onAction(INetwork network, PartTarget target, S state, E event);
276

277
    }
278

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