diff --git a/.github/workflows/verify-pull-request.yaml b/.github/workflows/verify-pull-request.yaml index f8db9be48..c039245d7 100644 --- a/.github/workflows/verify-pull-request.yaml +++ b/.github/workflows/verify-pull-request.yaml @@ -106,3 +106,35 @@ jobs: with: name: project-red-${{ steps.versioning.outputs.version }} path: '*/build/libs/ProjectRed-*.jar' + + integration_tests: + name: Integration Test - ${{ matrix.module }} + runs-on: ubuntu-latest + needs: build_test + strategy: + matrix: + module: [transmission] + steps: + - name: Checkout git repo + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set up JDK 21 + uses: actions/setup-java@v3 + with: + distribution: 'adopt' + java-version: '21' + + - name: Restore Gradle cache + uses: actions/cache@v3 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle2-${{ hashFiles('**/build.gradle', '**/build.properties', '**/gradle.properties', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle2- + + - name: Run game tests + run: ./gradlew :${{ matrix.module }}:runGameTestServer diff --git a/core/build.gradle b/core/build.gradle index 2d8d6fa6d..98ead9f95 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -31,7 +31,8 @@ dependencies { accessTransformers "io.codechicken:CBMultipart:${mc_version}-${cbm_version}" // ProjectRed API - jarJar(api project(":api")) // Use JarJar to bake within Core jar + compileOnly project(":api") // Not on runtime bc already included via JarJar + jarJar(project(":api")) // Use JarJar to bake within Core jar // JEI compileOnly("mezz.jei:jei-${mc_version}-common-api:${jei_version}") diff --git a/expansion/build.gradle b/expansion/build.gradle index 9cb64487f..9d6967fe4 100644 --- a/expansion/build.gradle +++ b/expansion/build.gradle @@ -24,5 +24,6 @@ dependencies { accessTransformers "io.codechicken:CodeChickenLib:${mc_version}-${ccl_version}" accessTransformers "io.codechicken:CBMultipart:${mc_version}-${cbm_version}" + compileOnly project(":api") implementation project(":core") } diff --git a/exploration/build.gradle b/exploration/build.gradle index 8575f37b0..43e6e727d 100644 --- a/exploration/build.gradle +++ b/exploration/build.gradle @@ -24,5 +24,6 @@ dependencies { accessTransformers "io.codechicken:CodeChickenLib:${mc_version}-${ccl_version}" accessTransformers "io.codechicken:CBMultipart:${mc_version}-${cbm_version}" + compileOnly project(":api") implementation project(":core") } diff --git a/fabrication/build.gradle b/fabrication/build.gradle index 83420b415..efe54bd75 100644 --- a/fabrication/build.gradle +++ b/fabrication/build.gradle @@ -24,6 +24,7 @@ dependencies { accessTransformers "io.codechicken:CodeChickenLib:${mc_version}-${ccl_version}" accessTransformers "io.codechicken:CBMultipart:${mc_version}-${cbm_version}" + compileOnly project(":api") implementation project(":core") implementation project(":integration") implementation project(":transmission") diff --git a/illumination/build.gradle b/illumination/build.gradle index ac3affe13..46ffcac35 100644 --- a/illumination/build.gradle +++ b/illumination/build.gradle @@ -24,5 +24,6 @@ dependencies { accessTransformers "io.codechicken:CodeChickenLib:${mc_version}-${ccl_version}" accessTransformers "io.codechicken:CBMultipart:${mc_version}-${cbm_version}" + compileOnly project(":api") implementation project(":core") } diff --git a/integration/build.gradle b/integration/build.gradle index 7a18b79ce..cfa350726 100644 --- a/integration/build.gradle +++ b/integration/build.gradle @@ -24,5 +24,6 @@ dependencies { accessTransformers "io.codechicken:CodeChickenLib:${mc_version}-${ccl_version}" accessTransformers "io.codechicken:CBMultipart:${mc_version}-${cbm_version}" + compileOnly project(":api") implementation project(":core") } diff --git a/integration/src/main/java/mrtjp/projectred/integration/part/ArrayGatePart.java b/integration/src/main/java/mrtjp/projectred/integration/part/ArrayGatePart.java index 2b938aae0..8c422a845 100644 --- a/integration/src/main/java/mrtjp/projectred/integration/part/ArrayGatePart.java +++ b/integration/src/main/java/mrtjp/projectred/integration/part/ArrayGatePart.java @@ -124,8 +124,8 @@ public int calculateSignal() { if ((propagationMask & 1 << r) == 0) { continue; } int s; - if (maskConnectsCorner(r)) { - FaceLookup lookup = FaceLookup.lookupCorner(level(), pos(), getSide(), r); + if (maskConnectsInside(r)) { + FaceLookup lookup = FaceLookup.lookupInsideFace(level(), pos(), getSide(), r); s = RedstoneFaceLookup.resolveSignal(lookup, true); } else if (maskConnectsStraight(r)) { @@ -135,8 +135,8 @@ public int calculateSignal() { s = RedstoneFaceLookup.resolveVanillaSignal(lookup, this, true, true); } - } else if (maskConnectsInside(r)) { - FaceLookup lookup = FaceLookup.lookupInsideFace(level(), pos(), getSide(), r); + } else if (maskConnectsCorner(r)) { + FaceLookup lookup = FaceLookup.lookupCorner(level(), pos(), getSide(), r); s = RedstoneFaceLookup.resolveSignal(lookup, true); } else { // For non-connected sides, just do a vanilla signal lookup diff --git a/runtime/build.gradle b/runtime/build.gradle index cf6ad6efc..0d98000c0 100644 --- a/runtime/build.gradle +++ b/runtime/build.gradle @@ -11,13 +11,16 @@ neoForge { accessTransformers.from "../core/src/main/resources/META-INF/accesstransformer.cfg" runs { - configureEach { - } - client { + client() } server { + server() + } + + configureEach { + logLevel = org.slf4j.event.Level.DEBUG } } } @@ -31,4 +34,3 @@ dependencies { runtimeOnly project(":integration") runtimeOnly project(":transmission") } - diff --git a/transmission/build.gradle b/transmission/build.gradle index 7a31536cb..938fb6d5d 100644 --- a/transmission/build.gradle +++ b/transmission/build.gradle @@ -14,6 +14,23 @@ neoForge { data() programArguments.addAll '--mod', mod_id, '--all', '--output', file("src/main/generated").absolutePath, '--existing', file("src/main/resources").absolutePath } + + gameTestServer { + type = "gameTestServer" + gameDirectory = project.file('runs/gameTestServer') + systemProperty 'neoforge.enableGameTest', 'true' + systemProperty 'neoforge.enabledGameTestNamespaces', mod_id + } + + configureEach { + logLevel = org.slf4j.event.Level.DEBUG + } + } + + mods { + "${mod_id}" { + sourceSet(sourceSets.main) + } } } @@ -24,5 +41,6 @@ dependencies { accessTransformers "io.codechicken:CodeChickenLib:${mc_version}-${ccl_version}" accessTransformers "io.codechicken:CBMultipart:${mc_version}-${cbm_version}" + compileOnly project(":api") implementation project(":core") } diff --git a/transmission/src/main/java/mrtjp/projectred/transmission/gametests/RedwirePropagationTests.java b/transmission/src/main/java/mrtjp/projectred/transmission/gametests/RedwirePropagationTests.java new file mode 100644 index 000000000..ad99fbb63 --- /dev/null +++ b/transmission/src/main/java/mrtjp/projectred/transmission/gametests/RedwirePropagationTests.java @@ -0,0 +1,68 @@ +package mrtjp.projectred.transmission.gametests; + +import mrtjp.projectred.transmission.ProjectRedTransmission; +import net.minecraft.core.BlockPos; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.world.level.block.LeverBlock; +import net.minecraft.world.level.block.RedstoneLampBlock; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +@GameTestHolder(ProjectRedTransmission.MOD_ID) +@PrefixGameTestTemplate(false) +public class RedwirePropagationTests { + + @GameTest(template = "alloy_rw_wraparound_rs_block") + public static void redAlloyPropagatesAroundRSBlock(GameTestHelper helper) { + // Red alloy wires should propagate signal around a redsone block, + // and also power the lamp underneath + + // Positions + var lever = new BlockPos(0, 2, 1); + var lampA = new BlockPos(3, 2, 1); + var lampB = new BlockPos(6, 2, 1); + + // Assert start condition + helper.assertBlockState(lever, state -> !state.getValue(LeverBlock.POWERED), () -> "Lever should be off!"); + helper.assertBlockState(lampA, state -> !state.getValue(RedstoneLampBlock.LIT), () -> "Lamp should be off!"); + helper.assertBlockState(lampB, state -> !state.getValue(RedstoneLampBlock.LIT), () -> "Lamp should be off!"); + + // Pull lever, wait 2 ticks, then check lamp states + helper.startSequence() + .thenExecute(() -> helper.setBlock(lever, helper.getBlockState(lever).setValue(LeverBlock.POWERED, true))) + .thenIdle(2) + .thenExecute(() -> { + helper.assertBlockState(lever, state -> state.getValue(LeverBlock.POWERED), () -> "Lever should be on!"); + helper.assertBlockState(lampA, state -> state.getValue(RedstoneLampBlock.LIT), () -> "Lamp A should be on!"); + helper.assertBlockState(lampB, state -> state.getValue(RedstoneLampBlock.LIT), () -> "Lamp B should be on!"); + }).thenSucceed(); + } + + @GameTest(template = "insulated_rw_wraparound_rs_block") + public static void insulatedWirePropagatesAroundRSBlock(GameTestHelper helper) { + // Insulated wires should propagate signal around a redsone block, + // but NOT power the lamp underneath + + // Positions + var lever = new BlockPos(0, 2, 1); + var lampA = new BlockPos(3, 2, 1); + var lampB = new BlockPos(6, 2, 1); + + // Assert start condition + helper.assertBlockState(lever, state -> !state.getValue(LeverBlock.POWERED), () -> "Lever should be off!"); + helper.assertBlockState(lampA, state -> !state.getValue(RedstoneLampBlock.LIT), () -> "Lamp should be off!"); + helper.assertBlockState(lampB, state -> !state.getValue(RedstoneLampBlock.LIT), () -> "Lamp should be off!"); + + // Pull lever, wait 2 ticks, then check lamp states + helper.startSequence() + .thenExecute(() -> helper.setBlock(lever, helper.getBlockState(lever).setValue(LeverBlock.POWERED, true))) + .thenIdle(2) + .thenExecute(() -> { + helper.assertBlockState(lever, state -> state.getValue(LeverBlock.POWERED), () -> "Lever should be on!"); + helper.assertBlockState(lampA, state -> !state.getValue(RedstoneLampBlock.LIT), () -> "Lamp A should be off!"); + helper.assertBlockState(lampB, state -> state.getValue(RedstoneLampBlock.LIT), () -> "Lamp B should be on!"); + }).thenSucceed(); + } + +} diff --git a/transmission/src/main/java/mrtjp/projectred/transmission/part/RedwirePart.java b/transmission/src/main/java/mrtjp/projectred/transmission/part/RedwirePart.java index 157b83004..c5a50b500 100644 --- a/transmission/src/main/java/mrtjp/projectred/transmission/part/RedwirePart.java +++ b/transmission/src/main/java/mrtjp/projectred/transmission/part/RedwirePart.java @@ -170,8 +170,8 @@ public int calculateSignal() { for (int r = 0; r < 4; r++) { int s = 0; - if (maskConnectsCorner(r)) { - FaceLookup lookup = FaceLookup.lookupCorner(level(), pos(), getSide(), r); + if (maskConnectsInside(r)) { + FaceLookup lookup = FaceLookup.lookupInsideFace(level(), pos(), getSide(), r); s = resolveSignal(lookup); } else if (maskConnectsStraight(r)) { @@ -181,8 +181,8 @@ public int calculateSignal() { s = RedstoneFaceLookup.resolveVanillaSignal(lookup, this, true, true); } - } else if (maskConnectsInside(r)) { - FaceLookup lookup = FaceLookup.lookupInsideFace(level(), pos(), getSide(), r); + } else if (maskConnectsCorner(r)) { + FaceLookup lookup = FaceLookup.lookupCorner(level(), pos(), getSide(), r); s = resolveSignal(lookup); } diff --git a/transmission/src/main/resources/data/projectred_transmission/structure/alloy_rw_wraparound_rs_block.nbt b/transmission/src/main/resources/data/projectred_transmission/structure/alloy_rw_wraparound_rs_block.nbt new file mode 100644 index 000000000..53659b5f2 Binary files /dev/null and b/transmission/src/main/resources/data/projectred_transmission/structure/alloy_rw_wraparound_rs_block.nbt differ diff --git a/transmission/src/main/resources/data/projectred_transmission/structure/insulated_rw_wraparound_rs_block.nbt b/transmission/src/main/resources/data/projectred_transmission/structure/insulated_rw_wraparound_rs_block.nbt new file mode 100644 index 000000000..e93b9dd7b Binary files /dev/null and b/transmission/src/main/resources/data/projectred_transmission/structure/insulated_rw_wraparound_rs_block.nbt differ