diff --git a/src/generated/resources/assets/gtceu/lang/en_ud.json b/src/generated/resources/assets/gtceu/lang/en_ud.json index 5f7ddfe6700..17ad2092e0c 100644 --- a/src/generated/resources/assets/gtceu/lang/en_ud.json +++ b/src/generated/resources/assets/gtceu/lang/en_ud.json @@ -33,10 +33,11 @@ "behavior.portable_scanner.machine_progress": "%s / %s :pɐoꞀ/ssǝɹboɹԀ", "behavior.portable_scanner.machine_upwards_facing": "%s :buıɔɐℲ spɹɐʍd∩", "behavior.portable_scanner.mode.caption": "%s :ǝpoɯ ʎɐןdsıᗡ", - "behavior.portable_scanner.mode.show_all_info": "oɟuı ןןɐ ʍoɥS", + "behavior.portable_scanner.mode.show_all_info": ")oɟuı ןɐuɹǝʇuı buıpnןɔxǝ( oɟuı ןןɐ ʍoɥS", "behavior.portable_scanner.mode.show_block_info": "oɟuı ʞɔoןq ʍoɥS", "behavior.portable_scanner.mode.show_electrical_info": "oɟuı ןɐɔıɹʇɔǝןǝ ʍoɥS", "behavior.portable_scanner.mode.show_environmental_info": "oɟuı ןɐʇuǝɯuoɹıʌuǝ ʍoɥS", + "behavior.portable_scanner.mode.show_internal_info": "oɟuı buıbbnqǝp ןɐuɹǝʇuı ʍoɥS", "behavior.portable_scanner.mode.show_machine_info": "oɟuı ǝuıɥɔɐɯ ʍoɥS", "behavior.portable_scanner.mode.show_recipe_info": "oɟuı ǝdıɔǝɹ ʍoɥS", "behavior.portable_scanner.muffled": "˙pǝןɟɟnW", diff --git a/src/generated/resources/assets/gtceu/lang/en_us.json b/src/generated/resources/assets/gtceu/lang/en_us.json index 18b9a4c3d0e..51fdf10ca79 100644 --- a/src/generated/resources/assets/gtceu/lang/en_us.json +++ b/src/generated/resources/assets/gtceu/lang/en_us.json @@ -33,10 +33,11 @@ "behavior.portable_scanner.machine_progress": "Progress/Load: %s / %s", "behavior.portable_scanner.machine_upwards_facing": "Upwards Facing: %s", "behavior.portable_scanner.mode.caption": "Display mode: %s", - "behavior.portable_scanner.mode.show_all_info": "Show all info", + "behavior.portable_scanner.mode.show_all_info": "Show all info (excluding internal info)", "behavior.portable_scanner.mode.show_block_info": "Show block info", "behavior.portable_scanner.mode.show_electrical_info": "Show electrical info", "behavior.portable_scanner.mode.show_environmental_info": "Show environmental info", + "behavior.portable_scanner.mode.show_internal_info": "Show internal debugging info", "behavior.portable_scanner.mode.show_machine_info": "Show machine info", "behavior.portable_scanner.mode.show_recipe_info": "Show recipe info", "behavior.portable_scanner.muffled": "Muffled.", diff --git a/src/main/java/com/gregtechceu/gtceu/syncsystem/data_transformers/collections/ListTransformer.java b/src/main/java/com/gregtechceu/gtceu/syncsystem/data_transformers/collections/ListTransformer.java index eaf2d96ae53..1e34dfa20ba 100644 --- a/src/main/java/com/gregtechceu/gtceu/syncsystem/data_transformers/collections/ListTransformer.java +++ b/src/main/java/com/gregtechceu/gtceu/syncsystem/data_transformers/collections/ListTransformer.java @@ -7,6 +7,7 @@ import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; +import java.util.ArrayList; import java.util.List; public class ListTransformer implements IValueTransformer> { @@ -32,8 +33,10 @@ public List deserializeNBT(Tag tag, ISyncManaged holder, List current) { if (!(tag instanceof ListTag listTag) || elementTransformer == null) return List.of(); try { - current.clear(); - listTag.forEach(t -> current + if (current != null) current.clear(); + else current = new ArrayList<>(); + List finalCurrent = current; + listTag.forEach(t -> finalCurrent .add(elementTransformer.deserializeNBT(IValueTransformer.stripLdlibWrapper(t), null, null))); } catch (UnsupportedOperationException e) { GTCEu.LOGGER.error("Sync: Cannot sync an immutable list: {} {}", holder, e); diff --git a/src/main/java/com/gregtechceu/gtceu/syncsystem/data_transformers/collections/MapTransformer.java b/src/main/java/com/gregtechceu/gtceu/syncsystem/data_transformers/collections/MapTransformer.java index 48f07b6d8b6..1c82c008c7d 100644 --- a/src/main/java/com/gregtechceu/gtceu/syncsystem/data_transformers/collections/MapTransformer.java +++ b/src/main/java/com/gregtechceu/gtceu/syncsystem/data_transformers/collections/MapTransformer.java @@ -7,6 +7,7 @@ import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; +import java.util.HashMap; import java.util.Map; public class MapTransformer implements IValueTransformer> { @@ -39,7 +40,8 @@ public Tag serializeNBT(Map value, ISyncManaged holder) { @Override public Map deserializeNBT(Tag tag, ISyncManaged holder, Map current) { if (!(tag instanceof ListTag listTag)) return current; - current.clear(); + if (current != null) current.clear(); + else current = new HashMap<>(); for (Tag entryTag : listTag) { CompoundTag compound = (CompoundTag) entryTag; K key = keyTransformer.deserializeNBT(compound.get("k"), null, null); diff --git a/src/test/java/com/gregtechceu/gtceu/common/cover/AdvancedDetectorCoverTest.java b/src/test/java/com/gregtechceu/gtceu/common/cover/AdvancedDetectorCoverTest.java index 3c02085f142..7ba107e0120 100644 --- a/src/test/java/com/gregtechceu/gtceu/common/cover/AdvancedDetectorCoverTest.java +++ b/src/test/java/com/gregtechceu/gtceu/common/cover/AdvancedDetectorCoverTest.java @@ -1,6 +1,7 @@ package com.gregtechceu.gtceu.common.cover; import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.capability.IWorkable; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.common.cover.detector.AdvancedFluidDetectorCover; @@ -17,6 +18,8 @@ import net.minecraftforge.gametest.GameTestHolder; import net.minecraftforge.gametest.PrefixGameTestTemplate; +import org.apache.commons.lang3.mutable.MutableInt; + /** * The "electrolyzer" template contains a creative tank with water, * that is set to auto-output into an electrolyzer when supplied with a redstone signal @@ -27,25 +30,33 @@ @GameTestHolder(GTCEu.MOD_ID) public class AdvancedDetectorCoverTest { - @GameTest(template = "electrolyzer", batch = "coverTests", required = false) + @GameTest(template = "electrolyzer", batch = "coverTests") public static void testAdvancedActivityDetectorCoverWithActivity(GameTestHelper helper) { helper.pullLever(new BlockPos(2, 2, 2)); MetaMachine machine = ((IMachineBlockEntity) helper.getBlockEntity(new BlockPos(1, 2, 1))).getMetaMachine(); TestUtils.placeCover(helper, machine, GTItems.COVER_ACTIVITY_DETECTOR_ADVANCED.asStack(), Direction.WEST); - helper.runAtTickTime(30, () -> helper.assertRedstoneSignal( - new BlockPos(1, 2, 1), - Direction.WEST, - signal -> signal > 0, - () -> "expected redstone signal")); + MutableInt expected = new MutableInt(); + helper.runAtTickTime(40 - machine.getOffsetTimer() % 20, () -> { + IWorkable workable = (IWorkable) machine; + expected.setValue(Math.round(15f * workable.getProgress() / workable.getMaxProgress())); + }); + helper.runAtTickTime(41 - machine.getOffsetTimer() % 20, () -> { + // due to this cover updating only once every 20 ticks, we need to check multiple values + TestUtils.assertRedstoneEither(helper, new BlockPos(0, 2, 1), + (expected.intValue() + 13) % 15, + (expected.intValue() + 14) % 15, + expected.intValue()); + helper.succeed(); + }); } - @GameTest(template = "electrolyzer", batch = "coverTests", required = false) + @GameTest(template = "electrolyzer", batch = "coverTests") public static void testAdvancedActivityDetectorCoverWithoutActivity(GameTestHelper helper) { helper.pullLever(new BlockPos(2, 2, 2)); MetaMachine machine = ((IMachineBlockEntity) helper.getBlockEntity(new BlockPos(1, 2, 1))).getMetaMachine(); TestUtils.placeCover(helper, machine, GTItems.COVER_ACTIVITY_DETECTOR_ADVANCED.asStack(), Direction.WEST); - helper.runAtTickTime(35, () -> helper.pullLever(2, 2, 2)); - helper.runAtTickTime(40, () -> { + helper.runAtTickTime(20 - machine.getOffsetTimer() % 20, () -> helper.pullLever(2, 2, 2)); + helper.runAtTickTime(45 - machine.getOffsetTimer() % 20, () -> { TestUtils.assertLampOff(helper, new BlockPos(0, 2, 1)); helper.succeed(); }); @@ -60,8 +71,9 @@ public static void testAdvancedFluidDetectorCover(GameTestHelper helper) { cover.setMaxValue(100000); cover.setMinValue(1); cover.setLatched(false); - // At t=40, 36k will be inside, giving a redstone value of 5 - helper.runAtTickTime(40, () -> { + // At t=80, 21k will be inside, giving a redstone value of 2 or 3 + helper.runAtTickTime(81, () -> { + TestUtils.assertRedstone(helper, new BlockPos(0, 2, 1), 2, 3); TestUtils.assertLampOn(helper, new BlockPos(0, 2, 1)); helper.succeed(); }); diff --git a/src/test/java/com/gregtechceu/gtceu/common/cover/SolarPanelTest.java b/src/test/java/com/gregtechceu/gtceu/common/cover/SolarPanelTest.java index 0178c13356b..85296199fe1 100644 --- a/src/test/java/com/gregtechceu/gtceu/common/cover/SolarPanelTest.java +++ b/src/test/java/com/gregtechceu/gtceu/common/cover/SolarPanelTest.java @@ -1,16 +1,10 @@ package com.gregtechceu.gtceu.common.cover; import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; -import com.gregtechceu.gtceu.api.machine.MetaMachine; -import com.gregtechceu.gtceu.common.data.GTItems; -import com.gregtechceu.gtceu.common.data.GTMachines; import com.gregtechceu.gtceu.common.machine.electric.BatteryBufferMachine; -import com.gregtechceu.gtceu.gametest.util.TestUtils; import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; import net.minecraft.gametest.framework.GameTest; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.world.level.block.Blocks; @@ -21,23 +15,20 @@ @GameTestHolder(GTCEu.MOD_ID) public class SolarPanelTest { - private static BatteryBufferMachine makeBatteryBuffer(GameTestHelper helper, int tier) { - helper.setBlock(new BlockPos(0, 1, 0), GTMachines.BATTERY_BUFFER_4[tier].getBlock()); + private static BatteryBufferMachine getBatteryBuffer(GameTestHelper helper) { + // noinspection DataFlowIssue return (BatteryBufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) .getMetaMachine(); } - private static void placeSolar(GameTestHelper helper, MetaMachine machine) { - TestUtils.placeCover(helper, machine, GTItems.COVER_SOLAR_PANEL_HV.asStack(), Direction.UP); - } - - @GameTest(template = "empty_5x5", batch = "coverTests", required = false) // it doesn't fail only if running tests - // with the command for some reason - public static void only_works_in_game_generatesEnergyAtDayTest(GameTestHelper helper) { + @GameTest(template = "solar", batch = "coverTests") + public static void generatesEnergyAtDayTest(GameTestHelper helper) { helper.setDayTime(6000); - BatteryBufferMachine machine = makeBatteryBuffer(helper, GTValues.HV); - machine.getBatteryInventory().insertItem(0, GTItems.BATTERY_HV_LITHIUM.asStack(), false); - placeSolar(helper, machine); + BatteryBufferMachine machine = getBatteryBuffer(helper); + machine.onLoad(); + for (int y = helper.absolutePos(new BlockPos(0, 2, 0)).getY(); y < helper.getLevel().getMaxBuildHeight(); y++) { + helper.setBlock(0, helper.relativePos(new BlockPos(0, y, 0)).getY(), 0, Blocks.AIR); + } helper.runAtTickTime(80, () -> { helper.assertTrue(machine.energyContainer.getEnergyStored() > 0, "Solar panel cover didn't generate energy at day time"); @@ -45,15 +36,14 @@ public static void only_works_in_game_generatesEnergyAtDayTest(GameTestHelper he }); } - @GameTest(template = "empty_5x5", batch = "coverTests") + @GameTest(template = "solar", batch = "coverTests") public static void doesntGenerateEnergyAtDayWhenBlockedTest(GameTestHelper helper) { helper.setDayTime(6000); - BatteryBufferMachine machine = makeBatteryBuffer(helper, GTValues.HV); + BatteryBufferMachine machine = getBatteryBuffer(helper); + machine.onLoad(); helper.setBlock(new BlockPos(0, 3, 0), Blocks.DIAMOND_BLOCK); - machine.getBatteryInventory().insertItem(0, GTItems.BATTERY_HV_LITHIUM.asStack(), false); - placeSolar(helper, machine); helper.runAtTickTime(40, () -> { - helper.assertTrue(machine.energyContainer.getEnergyStored() == 0, + helper.assertTrue(machine.energyContainer.getEnergyStored() <= 1024, "Solar panel cover generated energy when blocked"); helper.succeed(); }); diff --git a/src/test/java/com/gregtechceu/gtceu/gametest/util/TestUtils.java b/src/test/java/com/gregtechceu/gtceu/gametest/util/TestUtils.java index 58273e6a5ff..8b51ec7161c 100644 --- a/src/test/java/com/gregtechceu/gtceu/gametest/util/TestUtils.java +++ b/src/test/java/com/gregtechceu/gtceu/gametest/util/TestUtils.java @@ -21,6 +21,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.GameTestAssertPosException; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.network.chat.MutableComponent; import net.minecraft.world.item.ItemStack; @@ -297,4 +298,31 @@ public static void succeedAfterTest(GameTestHelper helper, long timeout) { public static void assertEqual(GameTestHelper helper, @Nullable BlockPos pos1, @Nullable BlockPos pos2) { helper.assertTrue(pos1 != null && pos1.equals(pos2), "Expected %s to equal to %s".formatted(pos1, pos2)); } + + public static void assertRedstone(GameTestHelper helper, BlockPos pos, int min, int max) { + BlockPos absolutePos = helper.absolutePos(pos); + int strength = helper.getLevel().getBestNeighborSignal(absolutePos); + if (strength > max || strength < min) { + throw new GameTestAssertPosException( + "Expected redstone signal between %d and %d, got %d".formatted(min, max, strength), + absolutePos, pos, helper.getTick()); + } + } + + public static void assertRedstoneEither(GameTestHelper helper, BlockPos pos, int... values) { + BlockPos absolutePos = helper.absolutePos(pos); + int strength = helper.getLevel().getBestNeighborSignal(absolutePos); + boolean pass = false; + for (int i : values) { + if (i == strength) { + pass = true; + break; + } + } + if (!pass) { + throw new GameTestAssertPosException( + "Expected redstone signal to be one of %s, got %d".formatted(values, strength), + absolutePos, pos, helper.getTick()); + } + } } diff --git a/src/test/resources/data/gtceu/structures/solar.nbt b/src/test/resources/data/gtceu/structures/solar.nbt new file mode 100644 index 00000000000..fd291c6b007 Binary files /dev/null and b/src/test/resources/data/gtceu/structures/solar.nbt differ