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

CyclopsMC / IntegratedCrafting / #479011801

07 Sep 2025 01:21PM UTC coverage: 24.859% (-0.02%) from 24.876%
#479011801

push

github

rubensworks
Fix repeating block updates for attuned ifaces without target

0 of 2 new or added lines in 1 file covered. (0.0%)

1 existing line in 1 file now uncovered.

750 of 3017 relevant lines covered (24.86%)

0.25 hits per line

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

0.0
/src/main/java/org/cyclops/integratedcrafting/part/PartTypeInterfaceCraftingAttuned.java
1
package org.cyclops.integratedcrafting.part;
2

3
import net.minecraft.ChatFormatting;
4
import net.minecraft.core.BlockPos;
5
import net.minecraft.core.Direction;
6
import net.minecraft.nbt.CompoundTag;
7
import net.minecraft.network.FriendlyByteBuf;
8
import net.minecraft.network.chat.Component;
9
import net.minecraft.network.chat.MutableComponent;
10
import net.minecraft.server.level.ServerPlayer;
11
import net.minecraft.world.MenuProvider;
12
import net.minecraft.world.SimpleContainer;
13
import net.minecraft.world.entity.player.Inventory;
14
import net.minecraft.world.entity.player.Player;
15
import net.minecraft.world.inventory.AbstractContainerMenu;
16
import net.minecraft.world.level.BlockGetter;
17
import net.minecraft.world.level.block.Block;
18
import net.minecraft.world.level.block.state.BlockState;
19
import net.minecraftforge.common.util.LazyOptional;
20
import org.apache.commons.lang3.tuple.Triple;
21
import org.cyclops.commoncapabilities.api.capability.recipehandler.IRecipeDefinition;
22
import org.cyclops.commoncapabilities.api.capability.recipehandler.IRecipeHandler;
23
import org.cyclops.cyclopscore.config.extendedconfig.BlockConfig;
24
import org.cyclops.cyclopscore.helper.BlockHelpers;
25
import org.cyclops.cyclopscore.modcompat.commoncapabilities.BlockCapabilitiesHelpers;
26
import org.cyclops.integratedcrafting.GeneralConfig;
27
import org.cyclops.integratedcrafting.api.network.ICraftingNetwork;
28
import org.cyclops.integratedcrafting.core.part.PartTypeInterfaceCraftingBase;
29
import org.cyclops.integratedcrafting.inventory.container.ContainerPartInterfaceCraftingSettings;
30
import org.cyclops.integrateddynamics.Capabilities;
31
import org.cyclops.integrateddynamics.api.evaluate.variable.ValueDeseralizationContext;
32
import org.cyclops.integrateddynamics.api.network.INetwork;
33
import org.cyclops.integrateddynamics.api.network.IPartNetwork;
34
import org.cyclops.integrateddynamics.api.part.IPartContainer;
35
import org.cyclops.integrateddynamics.api.part.PartPos;
36
import org.cyclops.integrateddynamics.api.part.PartTarget;
37
import org.cyclops.integrateddynamics.core.block.IgnoredBlockStatus;
38
import org.cyclops.integrateddynamics.core.helper.PartHelpers;
39
import org.cyclops.integrateddynamics.core.part.PartTypeBase;
40

41
import javax.annotation.Nullable;
42
import java.util.Collection;
43
import java.util.Collections;
44
import java.util.List;
45
import java.util.Optional;
46

47
/**
48
 * Interface for auto crafting that reads out all available target machine recipes.
49
 * @author rubensworks
50
 */
51
public class PartTypeInterfaceCraftingAttuned extends PartTypeInterfaceCraftingBase<PartTypeInterfaceCraftingAttuned, PartTypeInterfaceCraftingAttuned.State> {
52

53
    public PartTypeInterfaceCraftingAttuned(String name) {
54
        super(name);
×
55
    }
×
56

57
    @Override
58
    public int getConsumptionRate(PartTypeInterfaceCraftingAttuned.State state) {
59
        return state.getCraftingJobHandler().getProcessingCraftingJobs().size() * GeneralConfig.interfaceCraftingAttunedBaseConsumption;
×
60
    }
61

62
    @Override
63
    public Optional<MenuProvider> getContainerProvider(PartPos pos) {
64
        return Optional.of(new MenuProvider() {
×
65

66
            @Override
67
            public MutableComponent getDisplayName() {
68
                return Component.translatable(getTranslationKey());
×
69
            }
70

71
            @Override
72
            public AbstractContainerMenu createMenu(int id, Inventory playerInventory, Player playerEntity) {
73
                Triple<IPartContainer, PartTypeBase, PartTarget> data = PartHelpers.getContainerPartConstructionData(pos);
×
74
                return new ContainerPartInterfaceCraftingSettings(id, playerInventory, new SimpleContainer(0),
×
75
                        data.getRight(), Optional.of(data.getLeft()), data.getMiddle());
×
76
            }
77
        });
78
    }
79

80
    @Override
81
    public void writeExtraGuiData(FriendlyByteBuf packetBuffer, PartPos pos, ServerPlayer player) {
82
        super.writeExtraGuiDataSettings(packetBuffer, pos, player); // We show the settings directly.
×
83
    }
×
84

85
    @Override
86
    public Optional<MenuProvider> getContainerProviderSettings(PartPos pos) {
87
        return Optional.empty();
×
88
    }
89

90
    @Override
91
    protected PartTypeInterfaceCraftingAttuned.State constructDefaultState() {
92
        return new PartTypeInterfaceCraftingAttuned.State();
×
93
    }
94

95
    @Override
96
    protected Block createBlock(BlockConfig blockConfig) {
97
        return new IgnoredBlockStatus();
×
98
    }
99

100
    protected IgnoredBlockStatus.Status getStatus(State state) {
101
        IgnoredBlockStatus.Status status = IgnoredBlockStatus.Status.INACTIVE;
×
102
        if (state != null) {
×
103
            if (state.hasValidTarget()) {
×
104
                status = IgnoredBlockStatus.Status.ACTIVE;
×
105
            } else {
106
                status = IgnoredBlockStatus.Status.ERROR;
×
107
            }
108
        }
109

110
        return status;
×
111
    }
112

113
    @Override
114
    public BlockState getBlockState(IPartContainer partContainer, Direction side) {
115
        IgnoredBlockStatus.Status status = this.getStatus(partContainer != null ? (State)partContainer.getPartState(side) : null);
×
116
        return super.getBlockState(partContainer, side)
×
117
                .setValue(IgnoredBlockStatus.STATUS, status);
×
118
    }
119

120
    @Override
121
    public void loadTooltip(State state, List<Component> lines) {
122
        super.loadTooltip(state, lines);
×
123

124
        if (!state.hasValidTarget()) {
×
125
            lines.add(Component.translatable("parttype.integratedcrafting.interface_crafting_attuned.unsupported").withStyle(ChatFormatting.RED));
×
126
        }
127
    }
×
128

129
    @Override
130
    public boolean shouldTriggerBlockRenderUpdate(@Nullable State oldPartState, @Nullable State newPartState) {
131
        return super.shouldTriggerBlockRenderUpdate(oldPartState, newPartState) || this.getStatus(oldPartState) != this.getStatus(newPartState);
×
132
    }
133

134
    @Override
135
    public void onBlockNeighborChange(INetwork network, IPartNetwork partNetwork, PartTarget target, State state, BlockGetter world, Block neighbourBlock, BlockPos neighbourBlockPos) {
136
        boolean hadValidTarget = state.hasValidTarget();
×
137
        removeTargetFromNetwork(network, target.getTarget(), state);
×
138

139
        super.onBlockNeighborChange(network, partNetwork, target, state, world, neighbourBlock, neighbourBlockPos);
×
140

141
        addTargetToNetwork(network, target, state, false);
×
142

143
        // Only trigger block update if really necessary.
NEW
144
        state.isDirtyAndReset();
×
145
        if (hadValidTarget != state.hasValidTarget()) {
×
NEW
146
            state.markDirty();
×
UNCOV
147
            BlockHelpers.markForUpdate(target.getCenter().getPos().getLevel(true), target.getCenter().getPos().getBlockPos());
×
148
        }
149
    }
×
150

151
    public static class State extends PartTypeInterfaceCraftingBase.State<PartTypeInterfaceCraftingAttuned, PartTypeInterfaceCraftingAttuned.State> {
×
152

153
        protected boolean hasValidTarget = false;
×
154
        private Collection<IRecipeDefinition> recipes;
155

156
        protected LazyOptional<IRecipeHandler> getTargetRecipeHandler() {
157
            PartPos target = getTarget().getTarget();
×
158
            return BlockCapabilitiesHelpers.getTileOrBlockCapability(target.getPos(), target.getSide(), Capabilities.RECIPE_HANDLER);
×
159
        }
160

161
        @Override
162
        public void setNetworks(@org.jetbrains.annotations.Nullable INetwork network, @org.jetbrains.annotations.Nullable ICraftingNetwork craftingNetwork, @org.jetbrains.annotations.Nullable IPartNetwork partNetwork, int channel, @org.jetbrains.annotations.Nullable ValueDeseralizationContext valueDeseralizationContext, boolean initialize) {
163
            super.setNetworks(network, craftingNetwork, partNetwork, channel, valueDeseralizationContext, initialize);
×
164

165
            this.hasValidTarget = getTargetRecipeHandler().isPresent();
×
166
            this.recipes = getTargetRecipeHandler()
×
167
                    .map(IRecipeHandler::getRecipes)
×
168
                    .orElse(Collections.emptyList());
×
169
            markDirty();
×
170
        }
×
171

172
        public boolean hasValidTarget() {
173
            return this.hasValidTarget;
×
174
        }
175

176
        @Override
177
        public void writeToNBT(CompoundTag tag) {
178
            super.writeToNBT(tag);
×
179
            tag.putBoolean("hasValidTarget", hasValidTarget);
×
180
        }
×
181

182
        @Override
183
        public void readFromNBT(ValueDeseralizationContext valueDeseralizationContext, CompoundTag tag) {
184
            super.readFromNBT(valueDeseralizationContext, tag);
×
185
            this.hasValidTarget = tag.getBoolean("hasValidTarget");
×
186
        }
×
187

188
        @Override
189
        public Collection<IRecipeDefinition> getRecipes() {
190
            return this.recipes;
×
191
        }
192
    }
193

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

© 2025 Coveralls, Inc