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

CyclopsMC / IntegratedDynamics / 13601866717

01 Mar 2025 06:09AM UTC coverage: 38.607% (+0.05%) from 38.557%
13601866717

push

github

rubensworks
Bump mod version

1955 of 8371 branches covered (23.35%)

Branch coverage included in aggregate %.

10119 of 22903 relevant lines covered (44.18%)

2.07 hits per line

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

50.85
/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.Collection;
41
import java.util.Collections;
42
import java.util.IdentityHashMap;
43
import java.util.List;
44
import java.util.Map;
45
import java.util.Set;
46

47
/**
48
 * An abstract {@link IPartType} with a default implementation for creating
49
 * network elements.
50
 * @author rubensworks
51
 */
52
public abstract class PartTypeBase<P extends IPartType<P, S>, S extends IPartState<P>>
53
        extends PartTypeAdapter<P, S> {
54

55
    @Getter
3✔
56
    private Item item;
57
    @Getter
3✔
58
    private Block block;
59
    private final String name;
60
    @Getter
3✔
61
    private final PartRenderPosition partRenderPosition;
62
    private final Map<Class<? extends INetworkEvent>, IEventAction> networkEventActions;
63

64
    public PartTypeBase(String name, PartRenderPosition partRenderPosition) {
2✔
65
        this.name = name;
3✔
66
        this.partRenderPosition = partRenderPosition;
3✔
67

68
        networkEventActions = constructNetworkEventActions();
4✔
69

70
        registerBlock();
2✔
71
    }
1✔
72

73
    @Override
74
    public ResourceLocation getUniqueName() {
75
        return ResourceLocation.fromNamespaceAndPath(getMod().getModId(), this.name);
7✔
76
    }
77

78
    protected ModBase getMod() {
79
        return IntegratedDynamics._instance;
2✔
80
    }
81

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

278
    }
279

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