Skip to content

Commit 5a1770b

Browse files
committed
Move default side config setup to being applied as a default item component instead of in the BE
1 parent 01f8259 commit 5a1770b

30 files changed

+894
-461
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
2+
package mekanism.common.tests.component;
3+
4+
import com.google.common.collect.Sets;
5+
import java.util.Collection;
6+
import java.util.EnumSet;
7+
import java.util.Map.Entry;
8+
import java.util.Set;
9+
import java.util.stream.Collectors;
10+
import mekanism.api.RelativeSide;
11+
import mekanism.common.attachments.component.AttachedSideConfig;
12+
import mekanism.common.attachments.component.AttachedSideConfig.LightConfigInfo;
13+
import mekanism.common.block.interfaces.IHasTileEntity;
14+
import mekanism.common.lib.transmitter.TransmissionType;
15+
import mekanism.common.registries.MekanismBlocks;
16+
import mekanism.common.registries.MekanismDataComponents;
17+
import mekanism.common.tests.helpers.MekGameTestHelper;
18+
import mekanism.common.tile.component.TileComponentConfig;
19+
import mekanism.common.tile.component.config.ConfigInfo;
20+
import mekanism.common.tile.prefab.TileEntityConfigurableMachine;
21+
import mekanism.generators.common.registries.GeneratorsBlocks;
22+
import net.minecraft.core.BlockPos;
23+
import net.minecraft.gametest.framework.GameTest;
24+
import net.minecraft.world.item.ItemStack;
25+
import net.minecraft.world.level.block.Block;
26+
import net.neoforged.neoforge.registries.DeferredHolder;
27+
import net.neoforged.testframework.annotation.ForEachTest;
28+
import net.neoforged.testframework.annotation.TestHolder;
29+
import net.neoforged.testframework.gametest.EmptyTemplate;
30+
31+
@ForEachTest(groups = "component.item")
32+
public class ItemPropertiesTest {
33+
34+
@GameTest
35+
@EmptyTemplate
36+
@TestHolder(description = "Validate we don't have any transmission types missing from side configs, and that we don't define a side for ones we are disabled on.")
37+
public static void validateSideConfigs(final MekGameTestHelper helper) {
38+
helper.succeedIf(() -> {
39+
validateSideConfigs(helper, MekanismBlocks.BLOCKS.getPrimaryEntries());
40+
validateSideConfigs(helper, GeneratorsBlocks.BLOCKS.getPrimaryEntries());
41+
});
42+
}
43+
44+
private static void validateSideConfigs(MekGameTestHelper helper, Collection<DeferredHolder<Block, ? extends Block>> blocks) {
45+
BlockPos center = helper.absolutePos(new BlockPos(0, 2, 0));
46+
for (DeferredHolder<Block, ? extends Block> holder : blocks) {
47+
Block block = holder.get();
48+
ItemStack stack = new ItemStack(block);
49+
if (!stack.isEmpty() && block instanceof IHasTileEntity<?> hasTileEntity &&
50+
//TODO: Would we rather actually place the block?
51+
hasTileEntity.newBlockEntity(center, block.defaultBlockState()) instanceof TileEntityConfigurableMachine configurable) {
52+
if (stack.get(MekanismDataComponents.EJECTOR) == null) {
53+
helper.fail("Block " + holder.getId() + " is missing a default ejector data component");
54+
}
55+
AttachedSideConfig defaultConfig = stack.get(MekanismDataComponents.SIDE_CONFIG);
56+
if (defaultConfig == null) {
57+
helper.fail("Block " + holder.getId() + " is missing a default side config data component");
58+
} else {
59+
TileComponentConfig config = configurable.getConfig();
60+
Set<TransmissionType> keys = defaultConfig.configInfo().keySet();
61+
Set<TransmissionType> transmissionTypes = EnumSet.copyOf(config.getTransmissions());
62+
if (!keys.containsAll(transmissionTypes)) {
63+
helper.fail("Block " + holder.getId() + " is missing side configs for the following transmission types: " +
64+
Sets.difference(transmissionTypes, keys).stream().map(TransmissionType::getTransmission).collect(Collectors.joining(", ")));
65+
} else if (keys.size() != transmissionTypes.size()) {
66+
helper.fail("Block " + holder.getId() + " has side configs for the following transmission types, but the BE doesn't: " +
67+
Sets.difference(keys, transmissionTypes).stream().map(TransmissionType::getTransmission).collect(Collectors.joining(", ")));
68+
} else {
69+
for (Entry<TransmissionType, LightConfigInfo> entry : defaultConfig.configInfo().entrySet()) {
70+
TransmissionType type = entry.getKey();
71+
ConfigInfo info = config.getConfig(type);
72+
helper.assertTrue(info != null, "Config " + type.getTransmission() + " cannot be null");
73+
for (RelativeSide side : entry.getValue().sideConfig().keySet()) {
74+
if (!info.isSideEnabled(side)) {
75+
helper.fail("Block " + holder.getId() + " has side config for type: " + type.getTransmission() + " on side: " +
76+
side.name() + ", but the BE has side configs disabled on that side.");
77+
}
78+
}
79+
}
80+
}
81+
}
82+
} else if (!stack.isEmpty()) {
83+
if (stack.get(MekanismDataComponents.EJECTOR) != null) {
84+
helper.fail("Block " + holder.getId() + " is has a default ejector data component, but the tile doesn't");
85+
}
86+
if (stack.get(MekanismDataComponents.SIDE_CONFIG) != null) {
87+
helper.fail("Block " + holder.getId() + " is has a default side config data component, but the tile doesn't");
88+
}
89+
}
90+
}
91+
}
92+
}

src/main/java/mekanism/client/render/RenderPropertiesProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,10 @@ public static IClientItemExtensions mekaSuit() {
8686

8787
private static final ISpecialGear MEKA_SUIT = type -> switch (type) {
8888
case HELMET -> MekaSuitArmor.HELMET;
89-
//TODO - 1.20.5: Do we want a separate part for body?
90-
case CHESTPLATE, BODY -> MekaSuitArmor.BODYARMOR;
89+
case CHESTPLATE -> MekaSuitArmor.BODYARMOR;
9190
case LEGGINGS -> MekaSuitArmor.PANTS;
9291
case BOOTS -> MekaSuitArmor.BOOTS;
92+
default -> throw new IllegalStateException("No model present for registered meka suit piece of type " + type);
9393
};
9494

9595
public static IClientBlockExtensions particles() {

src/main/java/mekanism/client/render/item/block/RenderEnergyCubeItem.java

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.mojang.blaze3d.vertex.PoseStack;
44
import com.mojang.math.Axis;
5-
import java.util.Arrays;
65
import mekanism.api.RelativeSide;
76
import mekanism.client.model.ModelEnergyCore;
87
import mekanism.client.render.MekanismRenderer;
@@ -42,22 +41,15 @@ public void renderByItem(@NotNull ItemStack stack, @NotNull ItemDisplayContext d
4241
int light, int overlayLight) {
4342
EnergyCubeTier tier = ((ItemBlockEnergyCube) stack.getItem()).getTier();
4443
CubeSideState[] sideStates = new CubeSideState[EnumUtils.SIDES.length];
45-
IPersistentConfigInfo sideConfig = AttachedSideConfig.getStoredConfigInfo(stack, TransmissionType.ENERGY);
46-
if (sideConfig != null) {
47-
for (RelativeSide side : EnumUtils.SIDES) {
48-
DataType dataType = sideConfig.getDataType(side);
49-
CubeSideState state = CubeSideState.INACTIVE;
50-
if (dataType != DataType.NONE) {
51-
state = dataType.canOutput() ? CubeSideState.ACTIVE_LIT : CubeSideState.ACTIVE_UNLIT;
52-
}
53-
sideStates[side.ordinal()] = state;
54-
}
55-
} else if (tier == EnergyCubeTier.CREATIVE) {
56-
Arrays.fill(sideStates, CubeSideState.ACTIVE_LIT);
57-
} else {
58-
for (RelativeSide side : EnumUtils.SIDES) {
59-
sideStates[side.ordinal()] = side == RelativeSide.FRONT ? CubeSideState.ACTIVE_LIT : CubeSideState.ACTIVE_UNLIT;
44+
AttachedSideConfig fallback = tier == EnergyCubeTier.CREATIVE ? ItemBlockEnergyCube.ALL_OUTPUT : ItemBlockEnergyCube.SIDE_CONFIG;
45+
IPersistentConfigInfo sideConfig = AttachedSideConfig.getStoredConfigInfo(stack, fallback, TransmissionType.ENERGY);
46+
for (RelativeSide side : EnumUtils.SIDES) {
47+
DataType dataType = sideConfig.getDataType(side);
48+
CubeSideState state = CubeSideState.INACTIVE;
49+
if (dataType != DataType.NONE) {
50+
state = dataType.canOutput() ? CubeSideState.ACTIVE_LIT : CubeSideState.ACTIVE_UNLIT;
6051
}
52+
sideStates[side.ordinal()] = state;
6153
}
6254
ModelData modelData = ModelData.builder().with(TileEntityEnergyCube.SIDE_STATE_PROPERTY, sideStates).build();
6355
renderBlockItem(stack, displayContext, matrix, renderer, light, overlayLight, modelData);

src/main/java/mekanism/common/attachments/FrequencyAware.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ public static <FREQ extends Frequency> FrequencyAware<FREQ> none() {
3939

4040
public static <FREQ extends Frequency> Codec<FrequencyAware<FREQ>> codec(FrequencyType<FREQ> frequencyType) {
4141
return RecordCodecBuilder.create(instance -> instance.group(
42-
//TODO - 1.20.5: Validate this is equivalent to Frequency#serializeIdentityWithOwner??
4342
frequencyType.getIdentitySerializer().codec().optionalFieldOf(SerializationConstants.IDENTITY).forGetter(FrequencyAware::identity)
4443
).apply(instance, identity -> {
4544
FREQ frequency = null;

src/main/java/mekanism/common/attachments/component/AttachedEjector.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.mojang.serialization.codecs.RecordCodecBuilder;
55
import io.netty.buffer.ByteBuf;
66
import java.util.ArrayList;
7+
import java.util.Arrays;
78
import java.util.Collections;
89
import java.util.List;
910
import java.util.Optional;
@@ -16,10 +17,13 @@
1617
import net.minecraft.util.ExtraCodecs;
1718
import org.jetbrains.annotations.Nullable;
1819

19-
//TODO - 1.20.5: Try to make the version be what is attached to things that support ejectors so that if nothing is set it doesn't end up in the component patch
2020
@NothingNullByDefault
2121
public record AttachedEjector(List<Optional<EnumColor>> inputColors, boolean strictInput, Optional<EnumColor> outputColor) {
2222

23+
//TODO - 1.20.5: Re-evaluate this, and maybe rework it so that we can actually just use Collections.emptyList
24+
// without our constructor check failing, and without the codec running into issues because of the min size
25+
public static final AttachedEjector DEFAULT = new AttachedEjector(Arrays.stream(EnumUtils.SIDES).map(side -> Optional.<EnumColor>empty()).toList(), false, Optional.empty());
26+
2327
public static final Codec<AttachedEjector> CODEC = RecordCodecBuilder.create(instance -> instance.group(
2428
ExtraCodecs.optionalEmptyMap(EnumColor.CODEC).listOf(EnumUtils.SIDES.length, EnumUtils.SIDES.length).fieldOf(SerializationConstants.INPUT_COLOR).forGetter(AttachedEjector::inputColors),
2529
Codec.BOOL.fieldOf(SerializationConstants.STRICT_INPUT).forGetter(AttachedEjector::strictInput),
@@ -33,9 +37,16 @@ public record AttachedEjector(List<Optional<EnumColor>> inputColors, boolean str
3337
);
3438

3539
public static AttachedEjector create(EnumColor[] inputColors, boolean strictInput, @Nullable EnumColor outputColor) {
40+
boolean isDefault = strictInput == DEFAULT.strictInput() && outputColor == DEFAULT.outputColor().orElse(null);
3641
List<Optional<EnumColor>> inputs = new ArrayList<>(inputColors.length);
3742
for (EnumColor inputColor : inputColors) {
3843
inputs.add(Optional.ofNullable(inputColor));
44+
if (inputColor != null) {
45+
isDefault = false;
46+
}
47+
}
48+
if (isDefault) {
49+
return DEFAULT;
3950
}
4051
return new AttachedEjector(inputs, strictInput, Optional.ofNullable(outputColor));
4152
}

0 commit comments

Comments
 (0)