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

CyclopsMC / IntegratedDynamics / 13739195914

08 Mar 2025 03:58PM UTC coverage: 39.059% (+0.06%) from 39.002%
13739195914

push

github

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

1966 of 8373 branches covered (23.48%)

Branch coverage included in aggregate %.

10307 of 23049 relevant lines covered (44.72%)

2.1 hits per line

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

49.01
/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.BlockBehaviour;
17
import net.minecraft.world.level.block.state.BlockState;
18
import net.neoforged.neoforge.common.NeoForge;
19
import org.apache.commons.lang3.tuple.Triple;
20
import org.cyclops.cyclopscore.config.extendedconfig.BlockConfigCommon;
21
import org.cyclops.cyclopscore.network.PacketCodecs;
22
import org.cyclops.integrateddynamics.api.evaluate.variable.IValue;
23
import org.cyclops.integrateddynamics.api.evaluate.variable.IVariable;
24
import org.cyclops.integrateddynamics.api.evaluate.variable.ValueDeseralizationContext;
25
import org.cyclops.integrateddynamics.api.network.INetwork;
26
import org.cyclops.integrateddynamics.api.network.IPartNetwork;
27
import org.cyclops.integrateddynamics.api.network.event.INetworkEvent;
28
import org.cyclops.integrateddynamics.api.part.IPartContainer;
29
import org.cyclops.integrateddynamics.api.part.PartPos;
30
import org.cyclops.integrateddynamics.api.part.PartRenderPosition;
31
import org.cyclops.integrateddynamics.api.part.PartTarget;
32
import org.cyclops.integrateddynamics.api.part.aspect.IAspect;
33
import org.cyclops.integrateddynamics.api.part.aspect.IAspectWrite;
34
import org.cyclops.integrateddynamics.api.part.write.IPartStateWriter;
35
import org.cyclops.integrateddynamics.api.part.write.IPartTypeWriter;
36
import org.cyclops.integrateddynamics.core.block.IgnoredBlock;
37
import org.cyclops.integrateddynamics.core.block.IgnoredBlockStatus;
38
import org.cyclops.integrateddynamics.core.helper.L10NValues;
39
import org.cyclops.integrateddynamics.core.helper.NetworkHelpers;
40
import org.cyclops.integrateddynamics.core.helper.PartHelpers;
41
import org.cyclops.integrateddynamics.core.network.event.VariableContentsUpdatedEvent;
42
import org.cyclops.integrateddynamics.core.part.PartTypeAspects;
43
import org.cyclops.integrateddynamics.core.part.PartTypeBase;
44
import org.cyclops.integrateddynamics.core.part.event.PartWriterAspectEvent;
45
import org.cyclops.integrateddynamics.inventory.container.ContainerPartWriter;
46
import org.cyclops.integrateddynamics.part.aspect.Aspects;
47

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

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

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

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

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

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

79
    @Override
80
    protected Block createBlock(BlockConfigCommon<?> blockConfig, BlockBehaviour.Properties properties) {
81
        return new IgnoredBlockStatus(properties);
5✔
82
    }
83

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

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

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

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

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

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

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

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

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

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

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

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

182
    protected void onVariableContentsUpdated(IPartNetwork network, PartTarget target, S state) {
183
        state.onVariableContentsUpdated((P) this, target);
×
184
    }
×
185

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

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

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

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

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

249
    @Override
250
    public void writeExtraGuiData(RegistryFriendlyByteBuf packetBuffer, PartPos pos, ServerPlayer player) {
251
        // Write inventory size
252
        packetBuffer.writeInt(getWriteAspects().size());
×
253
        // Write part position
254
        PacketCodecs.write(packetBuffer, pos);
×
255

256
        super.writeExtraGuiData(packetBuffer, pos, player);
×
257
    }
×
258

259
    @Override
260
    public boolean shouldTriggerBlockRenderUpdate(@Nullable S oldPartState, @Nullable S newPartState) {
261
        return super.shouldTriggerBlockRenderUpdate(oldPartState, newPartState)
×
262
                || getStatus(oldPartState) != getStatus(newPartState);
×
263
    }
264

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