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

CyclopsMC / IntegratedDynamics / 15234420851

25 May 2025 05:01AM UTC coverage: 45.303% (+0.03%) from 45.27%
15234420851

push

github

rubensworks
Bump mod version

2567 of 8413 branches covered (30.51%)

Branch coverage included in aggregate %.

11736 of 23159 relevant lines covered (50.68%)

2.4 hits per line

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

54.61
/src/main/java/org/cyclops/integrateddynamics/core/part/write/PartTypeWriteBase.java
1
package org.cyclops.integrateddynamics.core.part.write;
2

3
import net.minecraft.ChatFormatting;
4
import net.minecraft.core.Direction;
5
import net.minecraft.core.Vec3i;
6
import net.minecraft.network.RegistryFriendlyByteBuf;
7
import net.minecraft.network.chat.Component;
8
import net.minecraft.network.chat.MutableComponent;
9
import net.minecraft.server.level.ServerPlayer;
10
import net.minecraft.world.MenuProvider;
11
import net.minecraft.world.entity.player.Inventory;
12
import net.minecraft.world.entity.player.Player;
13
import net.minecraft.world.inventory.AbstractContainerMenu;
14
import net.minecraft.world.item.ItemStack;
15
import net.minecraft.world.level.block.Block;
16
import net.minecraft.world.level.block.state.BlockState;
17
import net.neoforged.neoforge.common.NeoForge;
18
import org.apache.commons.lang3.tuple.Triple;
19
import org.cyclops.cyclopscore.config.extendedconfig.BlockConfig;
20
import org.cyclops.cyclopscore.network.PacketCodec;
21
import org.cyclops.integrateddynamics.api.evaluate.variable.IValue;
22
import org.cyclops.integrateddynamics.api.evaluate.variable.IVariable;
23
import org.cyclops.integrateddynamics.api.evaluate.variable.ValueDeseralizationContext;
24
import org.cyclops.integrateddynamics.api.network.INetwork;
25
import org.cyclops.integrateddynamics.api.network.IPartNetwork;
26
import org.cyclops.integrateddynamics.api.network.event.INetworkEvent;
27
import org.cyclops.integrateddynamics.api.part.IPartContainer;
28
import org.cyclops.integrateddynamics.api.part.PartPos;
29
import org.cyclops.integrateddynamics.api.part.PartRenderPosition;
30
import org.cyclops.integrateddynamics.api.part.PartTarget;
31
import org.cyclops.integrateddynamics.api.part.aspect.IAspect;
32
import org.cyclops.integrateddynamics.api.part.aspect.IAspectWrite;
33
import org.cyclops.integrateddynamics.api.part.write.IPartStateWriter;
34
import org.cyclops.integrateddynamics.api.part.write.IPartTypeWriter;
35
import org.cyclops.integrateddynamics.core.block.IgnoredBlock;
36
import org.cyclops.integrateddynamics.core.block.IgnoredBlockStatus;
37
import org.cyclops.integrateddynamics.core.helper.L10NValues;
38
import org.cyclops.integrateddynamics.core.helper.NetworkHelpers;
39
import org.cyclops.integrateddynamics.core.helper.PartHelpers;
40
import org.cyclops.integrateddynamics.core.network.event.VariableContentsUpdatedEvent;
41
import org.cyclops.integrateddynamics.core.part.PartTypeAspects;
42
import org.cyclops.integrateddynamics.core.part.PartTypeBase;
43
import org.cyclops.integrateddynamics.core.part.event.PartWriterAspectEvent;
44
import org.cyclops.integrateddynamics.inventory.container.ContainerPartWriter;
45
import org.cyclops.integrateddynamics.part.aspect.Aspects;
46

47
import javax.annotation.Nullable;
48
import java.util.List;
49
import java.util.Map;
50
import java.util.Optional;
51

52
/**
53
 * An abstract {@link IPartTypeWriter}.
54
 * @author rubensworks
55
 */
56
public abstract class PartTypeWriteBase<P extends IPartTypeWriter<P, S>, S extends IPartStateWriter<P>>
57
        extends PartTypeAspects<P, S> implements IPartTypeWriter<P, S> {
58

59
    private List<IAspectWrite> aspectsWrite = null;
3✔
60

61
    public PartTypeWriteBase(String name) {
62
        this(name, new PartRenderPosition(0.3125F, 0.3125F, 0.625F, 0.625F, 0.25F, 0.25F));
12✔
63
    }
1✔
64

65
    public PartTypeWriteBase(String name, PartRenderPosition partRenderPosition) {
66
        super(name, partRenderPosition);
4✔
67
    }
1✔
68

69
    @Override
70
    protected Map<Class<? extends INetworkEvent>, IEventAction> constructNetworkEventActions() {
71
        Map<Class<? extends INetworkEvent>, IEventAction> actions = super.constructNetworkEventActions();
3✔
72
        IEventAction<P, S, INetworkEvent> updateEventListener = (network, target, state, event) -> NetworkHelpers
5✔
73
                .getPartNetwork(network).ifPresent(partNetwork -> onVariableContentsUpdated(partNetwork, target, state));
12✔
74
        actions.put(VariableContentsUpdatedEvent.class, updateEventListener);
5✔
75
        return actions;
2✔
76
    }
77

78
    @Override
79
    protected Block createBlock(BlockConfig blockConfig) {
80
        return new IgnoredBlockStatus();
4✔
81
    }
82

83
    @Override
84
    public void update(INetwork network, IPartNetwork partNetwork, PartTarget target, S state) {
85
        super.update(network, partNetwork, target, state);
6✔
86
        IAspect aspect = getActiveAspect(target, state);
5✔
87
        if (aspect != null) {
2✔
88
            aspect.update(network, partNetwork, this, target, state);
7✔
89
        }
90
    }
1✔
91

92
    @Override
93
    public boolean setTargetOffset(S state, PartPos center, Vec3i offset) {
94
        IAspectWrite activeAspect = state.getActiveAspect();
3✔
95
        if(activeAspect != null) {
2!
96
            activeAspect.onDeactivate(this, getTarget(center, state), state);
×
97
        }
98
        boolean ret = super.setTargetOffset(state, center, offset);
6✔
99
        if(activeAspect != null) {
2!
100
            activeAspect.onActivate(this, getTarget(center, state), state);
×
101
        }
102
        return ret;
2✔
103
    }
104

105
    @Override
106
    public void addDrops(PartTarget target, S state, List<ItemStack> itemStacks, boolean dropMainElement, boolean saveState) {
107
        for(int i = 0; i < state.getInventory().getContainerSize(); i++) {
×
108
            ItemStack itemStack = state.getInventory().getItem(i);
×
109
            if(!itemStack.isEmpty()) {
×
110
                itemStacks.add(itemStack);
×
111
            }
112
        }
113
        state.getInventory().clearContent();
×
114
        state.triggerAspectInfoUpdate((P) this, target, null, false);
×
115
        super.addDrops(target, state, itemStacks, dropMainElement, saveState);
×
116
    }
×
117

118
    @Override
119
    public void beforeNetworkKill(INetwork network, IPartNetwork partNetwork, PartTarget target, S state) {
120
        super.beforeNetworkKill(network, partNetwork, target, state);
6✔
121
        state.triggerAspectInfoUpdate((P) this, target, null, true);
6✔
122
    }
1✔
123

124
    @Override
125
    public void afterNetworkAlive(INetwork network, IPartNetwork partNetwork, PartTarget target, S state) {
126
        super.afterNetworkAlive(network, partNetwork, target, state);
6✔
127
        updateActivation(target, state, null);
5✔
128
    }
1✔
129

130
    @Override
131
    public List<IAspectWrite> getWriteAspects() {
132
        if (aspectsWrite == null) {
3✔
133
            aspectsWrite = Aspects.REGISTRY.getWriteAspects(this);
5✔
134
        }
135
        return aspectsWrite;
3✔
136
    }
137

138
    @Override
139
    public boolean hasActiveVariable(IPartNetwork network, PartTarget target, S partState) {
140
        return partState.hasVariable();
×
141
    }
142

143
    @Override
144
    public <V extends IValue> IVariable<V> getActiveVariable(INetwork network, IPartNetwork partNetwork, PartTarget target, S partState) {
145
        return partState.getVariable(network, partNetwork, ValueDeseralizationContext.of(target.getCenter().getPos().getLevel(true)));
11✔
146
    }
147

148
    @Override
149
    public IAspectWrite getActiveAspect(PartTarget target, S partState) {
150
        return partState.getActiveAspect();
3✔
151
    }
152

153
    @Override
154
    public void updateActivation(PartTarget target, S partState, @Nullable Player player) {
155
        boolean isNetworkInitializing = player == null; // TODO: in next major, also add isNetworkInitializing param to updateActivation so we don't need this hack!
5!
156

157
        // Check inside the inventory for a variable item and determine everything with that.
158
        int activeIndex = -1;
2✔
159
        for(int i = 0 ; i < partState.getInventory().getContainerSize(); i++) {
9!
160
            if(!partState.getInventory().getItem(i).isEmpty()) {
6✔
161
                activeIndex = i;
2✔
162
                break;
1✔
163
            }
164
        }
165
        IAspectWrite aspect = activeIndex == -1 ? null : getWriteAspects().get(activeIndex);
9!
166
        partState.triggerAspectInfoUpdate((P) this, target, aspect, isNetworkInitializing);
6✔
167

168
        INetwork network = NetworkHelpers.getNetwork(target.getCenter()).orElse(null);
7✔
169
        if (network != null && aspect != null) {
4!
170
            IPartNetwork partNetwork = NetworkHelpers.getPartNetwork(network).orElse(null);
6✔
171
            if (partNetwork != null) {
2!
172
                NeoForge.EVENT_BUS.post(new PartWriterAspectEvent<>(network, partNetwork, target, (P) this,
13✔
173
                        partState, player, aspect, partState.getInventory().getItem(activeIndex)));
4✔
174
            }
175
        }
176
        if (network != null && !isNetworkInitializing) {
4!
177
            network.getEventBus().post(new VariableContentsUpdatedEvent(network));
×
178
        }
179
    }
1✔
180

181
    protected void onVariableContentsUpdated(IPartNetwork network, PartTarget target, S state) {
182
        state.onVariableContentsUpdated((P) this, target);
4✔
183
    }
1✔
184

185
    protected IgnoredBlockStatus.Status getStatus(IPartStateWriter state) {
186
        IgnoredBlockStatus.Status status = IgnoredBlockStatus.Status.INACTIVE;
2✔
187
        if (state != null && !state.getInventory().isEmpty()) {
6!
188
            if (state.hasVariable() && state.isEnabled()) {
6!
189
                status = IgnoredBlockStatus.Status.ACTIVE;
3✔
190
            } else {
191
                status = IgnoredBlockStatus.Status.ERROR;
2✔
192
            }
193
        }
194
        return status;
2✔
195
    }
196

197
    @Override
198
    public BlockState getBlockState(IPartContainer partContainer,
199
                                    Direction side) {
200
        IgnoredBlockStatus.Status status = getStatus(partContainer != null
5!
201
                ? (IPartStateWriter) partContainer.getPartState(side) : null);
5✔
202
        return getBlock().defaultBlockState().setValue(IgnoredBlock.FACING, side)
10✔
203
                .setValue(IgnoredBlockStatus.STATUS, status);
2✔
204
    }
205

206
    @Override
207
    public void loadTooltip(S state, List<Component> lines) {
208
        super.loadTooltip(state, lines);
×
209
        IAspectWrite aspectWrite = state.getActiveAspect();
×
210
        if (aspectWrite != null) {
×
211
            if (state.hasVariable() && state.isEnabled()) {
×
212
                lines.add(Component.translatable(
×
213
                        L10NValues.PART_TOOLTIP_WRITER_ACTIVEASPECT,
214
                        Component.translatable(aspectWrite.getTranslationKey()),
×
215
                        Component.translatable(aspectWrite.getValueType().getTranslationKey())
×
216
                                .withStyle(aspectWrite.getValueType().getDisplayColorFormat())));
×
217
            } else {
218
                lines.add(Component.translatable(L10NValues.PART_TOOLTIP_ERRORS)
×
219
                        .withStyle(ChatFormatting.RED));
×
220
                for (MutableComponent error : state.getErrors(aspectWrite)) {
×
221
                    lines.add(error.withStyle(ChatFormatting.RED));
×
222
                }
×
223
            }
224
        } else {
225
            lines.add(Component.translatable(L10NValues.PART_TOOLTIP_INACTIVE));
×
226
        }
227
    }
×
228

229
    @Override
230
    public Optional<MenuProvider> getContainerProvider(PartPos pos) {
231
        return Optional.of(new MenuProvider() {
×
232
            @Override
233
            public Component getDisplayName() {
234
                return Component.translatable(getTranslationKey());
×
235
            }
236

237
            @Nullable
238
            @Override
239
            public AbstractContainerMenu createMenu(int id, Inventory playerInventory, Player playerEntity) {
240
                Triple<IPartContainer, PartTypeBase, PartTarget> data = PartHelpers.getContainerPartConstructionData(pos);
×
241
                S partState = (S) data.getLeft().getPartState(data.getRight().getCenter().getSide());
×
242
                return new ContainerPartWriter<>(id, playerInventory, partState.getInventory(),
×
243
                        data.getRight(), Optional.of(data.getLeft()), (PartTypeWriteBase) data.getMiddle());
×
244
            }
245

246
            @Override
247
            public boolean shouldTriggerClientSideContainerClosingOnOpen() {
248
                return false;
×
249
            }
250
        });
251
    }
252

253
    @Override
254
    public void writeExtraGuiData(RegistryFriendlyByteBuf packetBuffer, PartPos pos, ServerPlayer player) {
255
        // Write inventory size
256
        packetBuffer.writeInt(getWriteAspects().size());
×
257
        // Write part position
258
        PacketCodec.write(packetBuffer, pos);
×
259

260
        super.writeExtraGuiData(packetBuffer, pos, player);
×
261
    }
×
262

263
    @Override
264
    public boolean shouldTriggerBlockRenderUpdate(@Nullable S oldPartState, @Nullable S newPartState) {
265
        return super.shouldTriggerBlockRenderUpdate(oldPartState, newPartState)
×
266
                || getStatus(oldPartState) != getStatus(newPartState);
×
267
    }
268

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