mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-14 22:44:07 +01:00
Merge branch 'mc1.18/dev' into mc1.19/dev
# Conflicts: # src/main/java/com/simibubi/create/infrastructure/gametest/tests/TestFluids.java
This commit is contained in:
commit
c77bcbfabf
20
.github/workflows/localization.yml
vendored
20
.github/workflows/localization.yml
vendored
@ -4,15 +4,17 @@
|
||||
name: Crowdin Action
|
||||
|
||||
# Controls when the action will run.
|
||||
on:
|
||||
on: workflow_dispatch
|
||||
# Only run when started manually
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
uploadTranslations:
|
||||
description: "Set to true to upload (changed) translations to Crowdin"
|
||||
type: boolean
|
||||
required: true
|
||||
default: false
|
||||
|
||||
#:
|
||||
# inputs:
|
||||
# uploadTranslations:
|
||||
# description: "Set to true to upload (changed) translations to Crowdin"
|
||||
# type: boolean
|
||||
# required: true
|
||||
# default: false
|
||||
|
||||
#schedule:
|
||||
#- cron: '0 */6 * * *' # Every 6 hours - https://crontab.guru/#0_*/6_*_*_*
|
||||
|
||||
@ -30,7 +32,7 @@ jobs:
|
||||
# Upload sources to Crowdin
|
||||
upload_sources: true
|
||||
# Upload translations to Crowdin, only use true at initial run
|
||||
upload_translations: ${{ github.event.inputs.uploadTranslations }}
|
||||
upload_translations: false
|
||||
# Make pull request of Crowdin translations
|
||||
download_translations: true
|
||||
# To download translations to the specified version branch
|
||||
|
@ -11,6 +11,7 @@
|
||||
"languages_mapping": {
|
||||
"locale_with_underscore": {
|
||||
"cs": "cs_cz",
|
||||
"cy": "cy_gb",
|
||||
"da": "da_dk",
|
||||
"de": "de_de",
|
||||
"eo": "eo_uy",
|
||||
|
@ -353,4 +353,7 @@ public class MechanicalBearingBlockEntity extends GeneratingKineticBlockEntity
|
||||
angle = forcedAngle;
|
||||
}
|
||||
|
||||
public ControlledContraptionEntity getMovedContraption() {
|
||||
return movedContraption;
|
||||
}
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ public class PulleyBlockEntity extends LinearActuatorBlockEntity implements Thre
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (mirrorParent != null)
|
||||
removeRopes();
|
||||
|
||||
@ -284,7 +284,7 @@ public class PulleyBlockEntity extends LinearActuatorBlockEntity implements Thre
|
||||
if (prevMirrorParent == null || !prevMirrorParent.equals(mirrorParent))
|
||||
sharedMirrorContraption = null;
|
||||
}
|
||||
|
||||
|
||||
if (compound.contains("MirrorChildren"))
|
||||
mirrorChildren = NBTHelper.readCompoundList(compound.getList("MirrorChildren", Tag.TAG_COMPOUND),
|
||||
NbtUtils::readBlockPos);
|
||||
@ -379,4 +379,8 @@ public class PulleyBlockEntity extends LinearActuatorBlockEntity implements Thre
|
||||
return 100;
|
||||
return 100 * getInterpolatedOffset(.5f) / distance;
|
||||
}
|
||||
|
||||
public BlockPos getMirrorParent() {
|
||||
return mirrorParent;
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,19 @@ package com.simibubi.create.infrastructure.gametest;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsMovement;
|
||||
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsMovingInteraction;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.content.kinetics.gauge.SpeedGaugeBlockEntity;
|
||||
|
||||
import com.simibubi.create.content.kinetics.gauge.StressGaugeBlockEntity;
|
||||
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ -27,6 +39,7 @@ import net.minecraft.core.Registry;
|
||||
import net.minecraft.gametest.framework.GameTestHelper;
|
||||
import net.minecraft.gametest.framework.GameTestInfo;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
@ -40,6 +53,7 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||
@ -80,7 +94,7 @@ public class CreateGameTestHelper extends GameTestHelper {
|
||||
public void flipBlock(BlockPos pos) {
|
||||
BlockState original = getBlockState(pos);
|
||||
if (!original.hasProperty(BlockStateProperties.FACING))
|
||||
fail("FACING property not in block: " + Registry.BLOCK.getId(original.getBlock()));
|
||||
fail("FACING property not in block: " + ForgeRegistries.BLOCKS.getKey(original.getBlock()));
|
||||
Direction facing = original.getValue(BlockStateProperties.FACING);
|
||||
BlockState reversed = original.setValue(BlockStateProperties.FACING, facing.getOpposite());
|
||||
setBlock(pos, reversed);
|
||||
@ -123,6 +137,34 @@ public class CreateGameTestHelper extends GameTestHelper {
|
||||
behavior.setValue(mode.ordinal());
|
||||
}
|
||||
|
||||
public void assertSpeedometerSpeed(BlockPos speedometer, float value) {
|
||||
SpeedGaugeBlockEntity be = getBlockEntity(AllBlockEntityTypes.SPEEDOMETER.get(), speedometer);
|
||||
assertInRange(be.getSpeed(), value - 0.01, value + 0.01);
|
||||
}
|
||||
|
||||
public void assertStressometerCapacity(BlockPos stressometer, float value) {
|
||||
StressGaugeBlockEntity be = getBlockEntity(AllBlockEntityTypes.STRESSOMETER.get(), stressometer);
|
||||
assertInRange(be.getNetworkCapacity(), value - 0.01, value + 0.01);
|
||||
}
|
||||
|
||||
public void toggleActorsOfType(Contraption contraption, ItemLike item) {
|
||||
AtomicBoolean toggled = new AtomicBoolean(false);
|
||||
contraption.getInteractors().forEach((localPos, behavior) -> {
|
||||
if (toggled.get() || !(behavior instanceof ContraptionControlsMovingInteraction controls))
|
||||
return;
|
||||
MutablePair<StructureBlockInfo, MovementContext> actor = contraption.getActorAt(localPos);
|
||||
if (actor == null)
|
||||
return;
|
||||
ItemStack filter = ContraptionControlsMovement.getFilter(actor.right);
|
||||
if (filter != null && filter.is(item.asItem())) {
|
||||
controls.handlePlayerInteraction(
|
||||
makeMockPlayer(), InteractionHand.MAIN_HAND, localPos, contraption.entity
|
||||
);
|
||||
toggled.set(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// block entities
|
||||
|
||||
/**
|
||||
|
@ -1,11 +1,20 @@
|
||||
package com.simibubi.create.infrastructure.gametest.tests;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.simibubi.create.AllBlockEntityTypes;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllEntityTypes;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.bearing.MechanicalBearingBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.elevator.ElevatorPulleyBlockEntity;
|
||||
import com.simibubi.create.content.kinetics.transmission.sequencer.SequencedGearshiftBlock;
|
||||
import com.simibubi.create.infrastructure.gametest.CreateGameTestHelper;
|
||||
import com.simibubi.create.infrastructure.gametest.GameTestGroup;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2LongMap;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.gametest.framework.GameTest;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
@ -13,6 +22,9 @@ import net.minecraft.world.entity.projectile.Arrow;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.CropBlock;
|
||||
import net.minecraft.world.level.block.LeverBlock;
|
||||
import net.minecraft.world.level.block.RedstoneLampBlock;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
@GameTestGroup(path = "contraptions")
|
||||
@ -89,6 +101,128 @@ public class TestContraptions {
|
||||
helper.succeedWhen(() -> helper.assertBlockPresent(Blocks.DIAMOND_BLOCK, end));
|
||||
}
|
||||
|
||||
@GameTest(template = "controls", timeoutTicks = CreateGameTestHelper.TEN_SECONDS)
|
||||
public static void controls(CreateGameTestHelper helper) {
|
||||
BlockPos button = new BlockPos(5, 5, 4);
|
||||
BlockPos gearshift = new BlockPos(4, 5, 4);
|
||||
BlockPos bearingPos = new BlockPos(4, 4, 4);
|
||||
AtomicInteger step = new AtomicInteger(1);
|
||||
|
||||
List<BlockPos> dirt = List.of(new BlockPos(4, 2, 6), new BlockPos(2, 2, 4), new BlockPos(4, 2, 2));
|
||||
List<BlockPos> wheat = List.of(new BlockPos(4, 3, 7), new BlockPos(1, 3, 4), new BlockPos(4, 3, 1));
|
||||
|
||||
helper.pressButton(button);
|
||||
helper.succeedWhen(() -> {
|
||||
// wait for gearshift to reset
|
||||
helper.assertBlockProperty(gearshift, SequencedGearshiftBlock.STATE, 0);
|
||||
if (step.get() == 4)
|
||||
return; // step 4: all done!
|
||||
MechanicalBearingBlockEntity bearing = helper.getBlockEntity(AllBlockEntityTypes.MECHANICAL_BEARING.get(), bearingPos);
|
||||
if (bearing.getMovedContraption() == null)
|
||||
helper.fail("Contraption not assembled");
|
||||
Contraption contraption = bearing.getMovedContraption().getContraption();
|
||||
switch (step.get()) {
|
||||
case 1 -> { // step 1: both should be active
|
||||
helper.assertBlockPresent(Blocks.FARMLAND, dirt.get(0));
|
||||
helper.assertBlockProperty(wheat.get(0), CropBlock.AGE, 0);
|
||||
// now disable harvester
|
||||
helper.toggleActorsOfType(contraption, AllBlocks.MECHANICAL_HARVESTER.get());
|
||||
helper.pressButton(button);
|
||||
step.incrementAndGet();
|
||||
helper.fail("Entering step 2");
|
||||
}
|
||||
case 2 -> { // step 2: harvester disabled
|
||||
helper.assertBlockPresent(Blocks.FARMLAND, dirt.get(1));
|
||||
helper.assertBlockProperty(wheat.get(1), CropBlock.AGE, 7);
|
||||
// now disable plough
|
||||
helper.toggleActorsOfType(contraption, AllBlocks.MECHANICAL_PLOUGH.get());
|
||||
helper.pressButton(button);
|
||||
step.incrementAndGet();
|
||||
helper.fail("Entering step 3");
|
||||
}
|
||||
case 3 -> { // step 3: both disabled
|
||||
helper.assertBlockPresent(Blocks.DIRT, dirt.get(2));
|
||||
helper.assertBlockProperty(wheat.get(2), CropBlock.AGE, 7);
|
||||
// successful!
|
||||
helper.pressButton(button);
|
||||
step.incrementAndGet();
|
||||
helper.fail("Entering step 4");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@GameTest(template = "elevator")
|
||||
public static void elevator(CreateGameTestHelper helper) {
|
||||
BlockPos pulley = new BlockPos(5, 12, 3);
|
||||
BlockPos secondaryPulley = new BlockPos(5, 12, 1);
|
||||
BlockPos bottomLamp = new BlockPos(2, 3, 2);
|
||||
BlockPos topLamp = new BlockPos(2, 12, 2);
|
||||
BlockPos lever = new BlockPos(1, 11, 2);
|
||||
BlockPos elevatorStart = new BlockPos(4, 2, 2);
|
||||
BlockPos cowSpawn = new BlockPos(4, 4, 2);
|
||||
BlockPos cowEnd = new BlockPos(4, 13, 2);
|
||||
|
||||
helper.runAtTickTime(1, () -> helper.spawn(EntityType.COW, cowSpawn));
|
||||
helper.runAtTickTime(
|
||||
15, () -> helper.getBlockEntity(AllBlockEntityTypes.ELEVATOR_PULLEY.get(), pulley).clicked()
|
||||
);
|
||||
helper.succeedWhen(() -> {
|
||||
helper.assertSecondsPassed(1);
|
||||
if (!helper.getBlockState(lever).getValue(LeverBlock.POWERED)) { // step 1: check entity, lamps, and secondary, then move up
|
||||
helper.getFirstEntity(AllEntityTypes.CONTROLLED_CONTRAPTION.get(), elevatorStart); // make sure entity exists
|
||||
|
||||
helper.assertBlockProperty(topLamp, RedstoneLampBlock.LIT, false);
|
||||
helper.assertBlockProperty(bottomLamp, RedstoneLampBlock.LIT, true);
|
||||
|
||||
ElevatorPulleyBlockEntity secondary = helper.getBlockEntity(AllBlockEntityTypes.ELEVATOR_PULLEY.get(), secondaryPulley);
|
||||
if (secondary.getMirrorParent() == null)
|
||||
helper.fail("Secondary pulley has no parent");
|
||||
|
||||
helper.pullLever(lever);
|
||||
helper.fail("Entering step 2");
|
||||
} else { // step 2: wait for top lamp and cow passenger
|
||||
helper.assertBlockProperty(topLamp, RedstoneLampBlock.LIT, true);
|
||||
helper.assertBlockProperty(bottomLamp, RedstoneLampBlock.LIT, false);
|
||||
helper.assertEntityPresent(EntityType.COW, cowEnd);
|
||||
// all done, disassemble
|
||||
helper.getBlockEntity(AllBlockEntityTypes.ELEVATOR_PULLEY.get(), pulley).clicked();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@GameTest(template = "roller_filling")
|
||||
public static void rollerFilling(CreateGameTestHelper helper) {
|
||||
BlockPos lever = new BlockPos(7, 6, 1);
|
||||
BlockPos barrelEnd = new BlockPos(2, 5, 2);
|
||||
List<BlockPos> existing = BlockPos.betweenClosedStream(new BlockPos(1, 3, 2), new BlockPos(4, 2, 2)).toList();
|
||||
List<BlockPos> filled = BlockPos.betweenClosedStream(new BlockPos(1, 2, 1), new BlockPos(4, 3, 3))
|
||||
.filter(pos -> !existing.contains(pos)).toList();
|
||||
List<BlockPos> tracks = BlockPos.betweenClosedStream(new BlockPos(1, 4, 2), new BlockPos(4, 4, 2)).toList();
|
||||
helper.pullLever(lever);
|
||||
helper.succeedWhen(() -> {
|
||||
helper.assertSecondsPassed(4);
|
||||
existing.forEach(pos -> helper.assertBlockPresent(AllBlocks.RAILWAY_CASING.get(), pos));
|
||||
filled.forEach(pos -> helper.assertBlockPresent(AllBlocks.ANDESITE_CASING.get(), pos));
|
||||
tracks.forEach(pos -> helper.assertBlockPresent(AllBlocks.TRACK.get(), pos));
|
||||
helper.assertContainerEmpty(barrelEnd);
|
||||
});
|
||||
}
|
||||
|
||||
@GameTest(template = "roller_paving_and_clearing", timeoutTicks = CreateGameTestHelper.TEN_SECONDS)
|
||||
public static void rollerPavingAndClearing(CreateGameTestHelper helper) {
|
||||
BlockPos lever = new BlockPos(8, 5, 1);
|
||||
List<BlockPos> paved = BlockPos.betweenClosedStream(new BlockPos(1, 2, 1), new BlockPos(4, 2, 1)).toList();
|
||||
// block above will be cleared too, but will later be replaced by the contraption's barrel
|
||||
BlockPos cleared = new BlockPos(2, 3, 1);
|
||||
helper.pullLever(lever);
|
||||
helper.succeedWhen(() -> {
|
||||
helper.assertSecondsPassed(9);
|
||||
paved.forEach(pos -> helper.assertBlockPresent(AllBlocks.ANDESITE_CASING.get(), pos));
|
||||
helper.assertBlockPresent(Blocks.AIR, cleared);
|
||||
});
|
||||
}
|
||||
|
||||
// FIXME: trains do not enjoy being loaded in structures
|
||||
// https://gist.github.com/TropheusJ/f2d0a7df48360d2e078d0987c115c6ef
|
||||
// @GameTest(template = "train_observer")
|
||||
|
@ -1,55 +1,62 @@
|
||||
package com.simibubi.create.infrastructure.gametest.tests;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.simibubi.create.AllBlockEntityTypes;
|
||||
import com.simibubi.create.content.fluids.hosePulley.HosePulleyFluidHandler;
|
||||
import com.simibubi.create.content.fluids.pipes.valve.FluidValveBlock;
|
||||
import com.simibubi.create.content.kinetics.gauge.SpeedGaugeBlockEntity;
|
||||
import com.simibubi.create.content.kinetics.gauge.StressGaugeBlockEntity;
|
||||
import com.simibubi.create.content.kinetics.waterwheel.WaterWheelBlockEntity;
|
||||
import com.simibubi.create.infrastructure.gametest.CreateGameTestHelper;
|
||||
import com.simibubi.create.infrastructure.gametest.GameTestGroup;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.gametest.framework.GameTest;
|
||||
import net.minecraft.gametest.framework.GameTestAssertException;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.RedStoneWireBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.RedstoneSide;
|
||||
import net.minecraft.world.level.block.LeverBlock;
|
||||
import net.minecraft.world.level.block.RedstoneLampBlock;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.FluidType;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
@GameTestGroup(path = "fluids")
|
||||
public class TestFluids {
|
||||
@GameTest(template = "hose_pulley_transfer", timeoutTicks = CreateGameTestHelper.TWENTY_SECONDS)
|
||||
public static void hosePulleyTransfer(CreateGameTestHelper helper) {
|
||||
// there was supposed to be redstone here built in, but it kept popping off, so put it there manually
|
||||
BlockPos brokenRedstone = new BlockPos(4, 8, 3);
|
||||
BlockState redstone = Blocks.REDSTONE_WIRE.defaultBlockState()
|
||||
.setValue(RedStoneWireBlock.NORTH, RedstoneSide.NONE)
|
||||
.setValue(RedStoneWireBlock.SOUTH, RedstoneSide.NONE)
|
||||
.setValue(RedStoneWireBlock.EAST, RedstoneSide.UP)
|
||||
.setValue(RedStoneWireBlock.WEST, RedstoneSide.SIDE)
|
||||
.setValue(RedStoneWireBlock.POWER, 14);
|
||||
helper.setBlock(brokenRedstone, redstone);
|
||||
// pump
|
||||
BlockPos lever = new BlockPos(6, 9, 3);
|
||||
BlockPos lever = new BlockPos(7, 7, 5);
|
||||
helper.pullLever(lever);
|
||||
helper.succeedWhen(() -> {
|
||||
helper.assertSecondsPassed(15);
|
||||
// check filled
|
||||
BlockPos filledLowerCorner = new BlockPos(8, 3, 2);
|
||||
BlockPos filledUpperCorner = new BlockPos(10, 5, 4);
|
||||
BlockPos filledLowerCorner = new BlockPos(2, 3, 2);
|
||||
BlockPos filledUpperCorner = new BlockPos(4, 5, 4);
|
||||
BlockPos.betweenClosed(filledLowerCorner, filledUpperCorner)
|
||||
.forEach(pos -> helper.assertBlockPresent(Blocks.WATER, pos));
|
||||
// check emptied
|
||||
BlockPos emptiedLowerCorner = new BlockPos(2, 3, 2);
|
||||
BlockPos emptiedUpperCorner = new BlockPos(4, 5, 4);
|
||||
BlockPos emptiedLowerCorner = new BlockPos(8, 3, 2);
|
||||
BlockPos emptiedUpperCorner = new BlockPos(10, 5, 4);
|
||||
BlockPos.betweenClosed(emptiedLowerCorner, emptiedUpperCorner)
|
||||
.forEach(pos -> helper.assertBlockPresent(Blocks.AIR, pos));
|
||||
// check nothing left in pulley
|
||||
BlockPos pulleyPos = new BlockPos(8, 7, 4);
|
||||
BlockPos pulleyPos = new BlockPos(4, 7, 3);
|
||||
IFluidHandler storage = helper.fluidStorageAt(pulleyPos);
|
||||
if (storage instanceof HosePulleyFluidHandler hose) {
|
||||
IFluidHandler internalTank = hose.getInternalTank();
|
||||
@ -62,27 +69,27 @@ public class TestFluids {
|
||||
}
|
||||
|
||||
@GameTest(template = "in_world_pumping_out")
|
||||
public static void inWorldPumpingOutput(CreateGameTestHelper helper) {
|
||||
BlockPos pumpPos = new BlockPos(3, 2, 2);
|
||||
BlockPos waterPos = pumpPos.west();
|
||||
BlockPos basinPos = pumpPos.east();
|
||||
helper.flipBlock(pumpPos);
|
||||
public static void inWorldPumpingOut(CreateGameTestHelper helper) {
|
||||
BlockPos lever = new BlockPos(4, 3, 3);
|
||||
BlockPos basin = new BlockPos(5, 2, 2);
|
||||
BlockPos output = new BlockPos(2, 2, 2);
|
||||
helper.pullLever(lever);
|
||||
helper.succeedWhen(() -> {
|
||||
helper.assertBlockPresent(Blocks.WATER, waterPos);
|
||||
helper.assertTankEmpty(basinPos);
|
||||
helper.assertBlockPresent(Blocks.WATER, output);
|
||||
helper.assertTankEmpty(basin);
|
||||
});
|
||||
}
|
||||
|
||||
@GameTest(template = "in_world_pumping_in")
|
||||
public static void inWorldPumpingPickup(CreateGameTestHelper helper) {
|
||||
BlockPos pumpPos = new BlockPos(3, 2, 2);
|
||||
BlockPos basinPos = pumpPos.east();
|
||||
BlockPos waterPos = pumpPos.west();
|
||||
public static void inWorldPumpingIn(CreateGameTestHelper helper) {
|
||||
BlockPos lever = new BlockPos(4, 3, 3);
|
||||
BlockPos basin = new BlockPos(5, 2, 2);
|
||||
BlockPos water = new BlockPos(2, 2, 2);
|
||||
FluidStack expectedResult = new FluidStack(Fluids.WATER, FluidType.BUCKET_VOLUME);
|
||||
helper.flipBlock(pumpPos);
|
||||
helper.pullLever(lever);
|
||||
helper.succeedWhen(() -> {
|
||||
helper.assertBlockPresent(Blocks.AIR, waterPos);
|
||||
helper.assertFluidPresent(expectedResult, basinPos);
|
||||
helper.assertBlockPresent(Blocks.AIR, water);
|
||||
helper.assertFluidPresent(expectedResult, basin);
|
||||
});
|
||||
}
|
||||
|
||||
@ -147,4 +154,151 @@ public class TestFluids {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@GameTest(template = "large_waterwheel", timeoutTicks = CreateGameTestHelper.TEN_SECONDS)
|
||||
public static void largeWaterwheel(CreateGameTestHelper helper) {
|
||||
BlockPos wheel = new BlockPos(4, 3, 2);
|
||||
BlockPos leftEnd = new BlockPos(6, 2, 2);
|
||||
BlockPos rightEnd = new BlockPos(2, 2, 2);
|
||||
List<BlockPos> edges = List.of(new BlockPos(4, 5, 1), new BlockPos(4, 5, 3));
|
||||
BlockPos openLever = new BlockPos(3, 8, 1);
|
||||
BlockPos leftLever = new BlockPos(5, 7, 1);
|
||||
waterwheel(helper, wheel, 4, 512, leftEnd, rightEnd, edges, openLever, leftLever);
|
||||
}
|
||||
|
||||
@GameTest(template = "small_waterwheel", timeoutTicks = CreateGameTestHelper.TEN_SECONDS)
|
||||
public static void smallWaterwheel(CreateGameTestHelper helper) {
|
||||
BlockPos wheel = new BlockPos(3, 2, 2);
|
||||
BlockPos leftEnd = new BlockPos(4, 2, 2);
|
||||
BlockPos rightEnd = new BlockPos(2, 2, 2);
|
||||
List<BlockPos> edges = List.of(new BlockPos(3, 3, 1), new BlockPos(3, 3, 3));
|
||||
BlockPos openLever = new BlockPos(2, 6, 1);
|
||||
BlockPos leftLever = new BlockPos(4, 5, 1);
|
||||
waterwheel(helper, wheel, 8, 128, leftEnd, rightEnd, edges, openLever, leftLever);
|
||||
}
|
||||
|
||||
private static void waterwheel(CreateGameTestHelper helper,
|
||||
BlockPos wheel, float expectedRpm, float expectedSU,
|
||||
BlockPos leftEnd, BlockPos rightEnd, List<BlockPos> edges,
|
||||
BlockPos openLever, BlockPos leftLever) {
|
||||
BlockPos speedometer = wheel.north();
|
||||
BlockPos stressometer = wheel.south();
|
||||
helper.pullLever(openLever);
|
||||
helper.succeedWhen(() -> {
|
||||
// must always be true
|
||||
edges.forEach(pos -> helper.assertBlockNotPresent(Blocks.WATER, pos));
|
||||
helper.assertBlockPresent(Blocks.WATER, rightEnd);
|
||||
// first step: expect water on left end while flow is allowed
|
||||
if (!helper.getBlockState(leftLever).getValue(LeverBlock.POWERED)) {
|
||||
helper.assertBlockPresent(Blocks.WATER, leftEnd);
|
||||
// water is present. both sides should cancel.
|
||||
helper.assertSpeedometerSpeed(speedometer, 0);
|
||||
helper.assertStressometerCapacity(stressometer, 0);
|
||||
// success, pull the lever, enter step 2
|
||||
helper.powerLever(leftLever);
|
||||
helper.fail("Entering step 2");
|
||||
} else {
|
||||
// lever is pulled, flow should stop
|
||||
helper.assertBlockNotPresent(Blocks.WATER, leftEnd);
|
||||
// 1-sided flow, should be spinning
|
||||
helper.assertSpeedometerSpeed(speedometer, expectedRpm);
|
||||
helper.assertStressometerCapacity(stressometer, expectedSU);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@GameTest(template = "waterwheel_materials", timeoutTicks = CreateGameTestHelper.FIFTEEN_SECONDS)
|
||||
public static void waterwheelMaterials(CreateGameTestHelper helper) {
|
||||
List<Item> planks = ForgeRegistries.BLOCKS.tags().getTag(BlockTags.PLANKS).stream()
|
||||
.map(ItemLike::asItem).collect(Collectors.toCollection(ArrayList::new));
|
||||
List<BlockPos> chests = List.of(new BlockPos(6, 4, 2), new BlockPos(6, 4, 3));
|
||||
List<BlockPos> deployers = chests.stream().map(pos -> pos.below(2)).toList();
|
||||
helper.runAfterDelay(3, () -> chests.forEach(chest ->
|
||||
planks.forEach(plank -> ItemHandlerHelper.insertItem(helper.itemStorageAt(chest), new ItemStack(plank), false))
|
||||
));
|
||||
|
||||
BlockPos smallWheel = new BlockPos(4, 2, 2);
|
||||
BlockPos largeWheel = new BlockPos(3, 3, 3);
|
||||
BlockPos lever = new BlockPos(5, 3, 1);
|
||||
helper.pullLever(lever);
|
||||
|
||||
helper.succeedWhen(() -> {
|
||||
Item plank = planks.get(0);
|
||||
if (!(plank instanceof BlockItem blockItem))
|
||||
throw new GameTestAssertException(ForgeRegistries.ITEMS.getKey(plank) + " is not a BlockItem");
|
||||
Block block = blockItem.getBlock();
|
||||
|
||||
WaterWheelBlockEntity smallWheelBe = helper.getBlockEntity(AllBlockEntityTypes.WATER_WHEEL.get(), smallWheel);
|
||||
if (!smallWheelBe.material.is(block))
|
||||
helper.fail("Small waterwheel has not consumed " + ForgeRegistries.ITEMS.getKey(plank));
|
||||
|
||||
WaterWheelBlockEntity largeWheelBe = helper.getBlockEntity(AllBlockEntityTypes.LARGE_WATER_WHEEL.get(), largeWheel);
|
||||
if (!largeWheelBe.material.is(block))
|
||||
helper.fail("Large waterwheel has not consumed " + ForgeRegistries.ITEMS.getKey(plank));
|
||||
|
||||
// next item
|
||||
planks.remove(0);
|
||||
deployers.forEach(pos -> {
|
||||
IItemHandler handler = helper.itemStorageAt(pos);
|
||||
for (int i = 0; i < handler.getSlots(); i++) {
|
||||
handler.extractItem(i, Integer.MAX_VALUE, false);
|
||||
}
|
||||
});
|
||||
if (!planks.isEmpty())
|
||||
helper.fail("Not all planks have been consumed");
|
||||
});
|
||||
}
|
||||
|
||||
@GameTest(template = "smart_observer_pipes")
|
||||
public static void smartObserverPipes(CreateGameTestHelper helper) {
|
||||
BlockPos lever = new BlockPos(3, 3, 1);
|
||||
BlockPos output = new BlockPos(3, 4, 4);
|
||||
BlockPos tankOutput = new BlockPos(1, 2, 4);
|
||||
FluidStack expected = new FluidStack(Fluids.WATER, 2 * FluidAttributes.BUCKET_VOLUME);
|
||||
helper.pullLever(lever);
|
||||
helper.succeedWhen(() -> {
|
||||
helper.assertFluidPresent(expected, tankOutput);
|
||||
helper.assertBlockPresent(Blocks.DIAMOND_BLOCK, output);
|
||||
});
|
||||
}
|
||||
|
||||
@GameTest(template = "threshold_switch", timeoutTicks = CreateGameTestHelper.TWENTY_SECONDS)
|
||||
public static void thresholdSwitch(CreateGameTestHelper helper) {
|
||||
BlockPos leftHandle = new BlockPos(4, 2, 4);
|
||||
BlockPos leftValve = new BlockPos(4, 2, 3);
|
||||
BlockPos leftTank = new BlockPos(5, 2, 3);
|
||||
|
||||
BlockPos rightHandle = new BlockPos(2, 2, 4);
|
||||
BlockPos rightValve = new BlockPos(2, 2, 3);
|
||||
BlockPos rightTank = new BlockPos(1, 2, 3);
|
||||
|
||||
BlockPos drainHandle = new BlockPos(3, 3, 2);
|
||||
BlockPos drainValve = new BlockPos(3, 3, 1);
|
||||
BlockPos lamp = new BlockPos(1, 3, 1);
|
||||
BlockPos tank = new BlockPos(2, 2, 1);
|
||||
helper.succeedWhen(() -> {
|
||||
if (!helper.getBlockState(leftValve).getValue(FluidValveBlock.ENABLED)) { // step 1
|
||||
helper.getBlockEntity(AllBlockEntityTypes.VALVE_HANDLE.get(), leftHandle)
|
||||
.activate(false); // open the valve, fill 4 buckets
|
||||
helper.fail("Entering step 2");
|
||||
} else if (!helper.getBlockState(rightValve).getValue(FluidValveBlock.ENABLED)) { // step 2
|
||||
helper.assertFluidPresent(FluidStack.EMPTY, leftTank); // wait for left tank to drain
|
||||
helper.assertBlockProperty(lamp, RedstoneLampBlock.LIT, false); // should not be on yet
|
||||
helper.getBlockEntity(AllBlockEntityTypes.VALVE_HANDLE.get(), rightHandle)
|
||||
.activate(false); // fill another 4 buckets
|
||||
helper.fail("Entering step 3");
|
||||
} else if (!helper.getBlockState(drainValve).getValue(FluidValveBlock.ENABLED)) { // step 3
|
||||
helper.assertFluidPresent(FluidStack.EMPTY, rightTank); // wait for right tank to drain
|
||||
// 16 buckets inserted. tank full, lamp on.
|
||||
helper.assertBlockProperty(lamp, RedstoneLampBlock.LIT, true);
|
||||
// drain what's filled so far
|
||||
helper.getBlockEntity(AllBlockEntityTypes.VALVE_HANDLE.get(), drainHandle)
|
||||
.activate(false); // drain all 8 buckets
|
||||
helper.fail("Entering step 4");
|
||||
} else {
|
||||
helper.assertTankEmpty(tank); // wait for it to empty
|
||||
helper.assertBlockProperty(lamp, RedstoneLampBlock.LIT, false); // should be off now
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.RedstoneLampBlock;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
@GameTestGroup(path = "items")
|
||||
public class TestItems {
|
||||
@ -229,8 +230,35 @@ public class TestItems {
|
||||
});
|
||||
}
|
||||
|
||||
@GameTest(template = "content_observer_counting")
|
||||
public static void contentObserverCounting(CreateGameTestHelper helper) {
|
||||
@GameTest(template = "smart_observer_belt_and_funnel", timeoutTicks = CreateGameTestHelper.TEN_SECONDS)
|
||||
public static void smartObserverBeltAndFunnel(CreateGameTestHelper helper) {
|
||||
BlockPos lever = new BlockPos(6, 3, 2);
|
||||
List<BlockPos> targets = List.of(
|
||||
new BlockPos(5, 2, 1), // belt
|
||||
new BlockPos(2, 4, 6) // funnel
|
||||
);
|
||||
List<BlockPos> overflows = List.of(
|
||||
new BlockPos(6, 2, 1), // belt
|
||||
new BlockPos(1, 3, 6) // funnel
|
||||
);
|
||||
helper.pullLever(lever);
|
||||
helper.succeedWhen(() -> {
|
||||
helper.assertSecondsPassed(9);
|
||||
targets.forEach(pos -> helper.assertBlockPresent(Blocks.DIAMOND_BLOCK, pos));
|
||||
overflows.forEach(pos -> helper.assertBlockPresent(Blocks.AIR, pos));
|
||||
});
|
||||
}
|
||||
|
||||
@GameTest(template = "smart_observer_chutes")
|
||||
public static void smartObserverChutes(CreateGameTestHelper helper) {
|
||||
BlockPos lever = new BlockPos(1, 5, 2);
|
||||
BlockPos output = new BlockPos(1, 5, 3);
|
||||
helper.pullLever(lever);
|
||||
helper.succeedWhen(() -> helper.assertBlockPresent(Blocks.DIAMOND_BLOCK, output));
|
||||
}
|
||||
|
||||
@GameTest(template = "smart_observer_counting")
|
||||
public static void smartObserverCounting(CreateGameTestHelper helper) {
|
||||
BlockPos chest = new BlockPos(3, 2, 1);
|
||||
long totalChestItems = helper.getTotalItems(chest);
|
||||
BlockPos chestNixiePos = new BlockPos(2, 3, 1);
|
||||
@ -253,6 +281,26 @@ public class TestItems {
|
||||
});
|
||||
}
|
||||
|
||||
@GameTest(template = "smart_observer_filtered_storage")
|
||||
public static void smartObserverFilteredStorage(CreateGameTestHelper helper) {
|
||||
BlockPos lever = new BlockPos(2, 3, 1);
|
||||
BlockPos leftLamp = new BlockPos(3, 2, 3);
|
||||
BlockPos rightLamp = new BlockPos(1, 2, 3);
|
||||
helper.pullLever(lever);
|
||||
helper.succeedWhen(() -> {
|
||||
helper.assertBlockProperty(leftLamp, RedstoneLampBlock.LIT, true);
|
||||
helper.assertBlockProperty(rightLamp, RedstoneLampBlock.LIT, false);
|
||||
});
|
||||
}
|
||||
|
||||
@GameTest(template = "smart_observer_storage")
|
||||
public static void smartObserverStorage(CreateGameTestHelper helper) {
|
||||
BlockPos lever = new BlockPos(1, 3, 2);
|
||||
BlockPos lamp = new BlockPos(1, 2, 3);
|
||||
helper.pullLever(lever);
|
||||
helper.succeedWhen(() -> helper.assertBlockProperty(lamp, RedstoneLampBlock.LIT, true));
|
||||
}
|
||||
|
||||
@GameTest(template = "depot_display", timeoutTicks = CreateGameTestHelper.TEN_SECONDS)
|
||||
public static void depotDisplay(CreateGameTestHelper helper) {
|
||||
BlockPos displayPos = new BlockPos(5, 3, 1);
|
||||
@ -275,7 +323,7 @@ public class TestItems {
|
||||
|
||||
DepotBlockEntity depot = depots.get(i);
|
||||
ItemStack item = depot.getHeldItem();
|
||||
String name = Registry.ITEM.getKey(item.getItem()).getPath();
|
||||
String name = ForgeRegistries.ITEMS.getKey(item.getItem()).getPath();
|
||||
|
||||
if (!name.equals(text))
|
||||
helper.fail("Text mismatch: wanted [" + name + "], got: " + text);
|
||||
@ -283,8 +331,8 @@ public class TestItems {
|
||||
});
|
||||
}
|
||||
|
||||
@GameTest(template = "stockpile_switch")
|
||||
public static void stockpileSwitch(CreateGameTestHelper helper) {
|
||||
@GameTest(template = "threshold_switch")
|
||||
public static void thresholdSwitch(CreateGameTestHelper helper) {
|
||||
BlockPos chest = new BlockPos(1, 2, 1);
|
||||
BlockPos lamp = new BlockPos(2, 3, 1);
|
||||
helper.assertBlockProperty(lamp, RedstoneLampBlock.LIT, false);
|
||||
|
@ -3,6 +3,7 @@ package com.simibubi.create.infrastructure.gametest.tests;
|
||||
import static com.simibubi.create.infrastructure.gametest.CreateGameTestHelper.FIFTEEN_SECONDS;
|
||||
|
||||
import com.simibubi.create.AllBlockEntityTypes;
|
||||
import com.simibubi.create.content.redstone.thresholdSwitch.ThresholdSwitchBlockEntity;
|
||||
import com.simibubi.create.content.schematics.SchematicExport;
|
||||
import com.simibubi.create.content.schematics.SchematicItem;
|
||||
import com.simibubi.create.content.schematics.cannon.SchematicannonBlockEntity;
|
||||
@ -16,10 +17,14 @@ import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.animal.Sheep;
|
||||
import net.minecraft.world.entity.decoration.ArmorStand;
|
||||
import net.minecraft.world.entity.monster.Zombie;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.RedstoneLampBlock;
|
||||
|
||||
@GameTestGroup(path = "misc")
|
||||
public class TestMisc {
|
||||
@ -63,4 +68,47 @@ public class TestMisc {
|
||||
helper.assertItemEntityPresent(Items.WHITE_WOOL, sheepPos, 2);
|
||||
});
|
||||
}
|
||||
|
||||
@GameTest(template = "smart_observer_blocks")
|
||||
public static void smartObserverBlocks(CreateGameTestHelper helper) {
|
||||
BlockPos lever = new BlockPos(2, 2, 1);
|
||||
BlockPos leftLamp = new BlockPos(3, 4, 3);
|
||||
BlockPos rightLamp = new BlockPos(1, 4, 3);
|
||||
helper.pullLever(lever);
|
||||
helper.succeedWhen(() -> {
|
||||
helper.assertBlockProperty(leftLamp, RedstoneLampBlock.LIT, true);
|
||||
helper.assertBlockProperty(rightLamp, RedstoneLampBlock.LIT, false);
|
||||
});
|
||||
}
|
||||
|
||||
@GameTest(template = "threshold_switch_pulley")
|
||||
public static void thresholdSwitchPulley(CreateGameTestHelper helper) {
|
||||
BlockPos lever = new BlockPos(3, 7, 1);
|
||||
BlockPos switchPos = new BlockPos(1, 6, 1);
|
||||
helper.pullLever(lever);
|
||||
helper.succeedWhen(() -> {
|
||||
ThresholdSwitchBlockEntity switchBe = helper.getBlockEntity(AllBlockEntityTypes.THRESHOLD_SWITCH.get(), switchPos);
|
||||
float level = switchBe.getStockLevel();
|
||||
if (level < 0 || level > 1)
|
||||
helper.fail("Invalid level: " + level);
|
||||
});
|
||||
}
|
||||
|
||||
@GameTest(template = "netherite_backtank", timeoutTicks = CreateGameTestHelper.TEN_SECONDS)
|
||||
public static void netheriteBacktank(CreateGameTestHelper helper) {
|
||||
BlockPos lava = new BlockPos(2, 2, 3);
|
||||
BlockPos zombieSpawn = lava.above(2);
|
||||
BlockPos armorStandPos = new BlockPos(2, 2, 1);
|
||||
helper.runAtTickTime(5, () -> {
|
||||
Zombie zombie = helper.spawn(EntityType.ZOMBIE, zombieSpawn);
|
||||
ArmorStand armorStand = helper.getFirstEntity(EntityType.ARMOR_STAND, armorStandPos);
|
||||
for (EquipmentSlot slot : EquipmentSlot.values()) {
|
||||
zombie.setItemSlot(slot, armorStand.getItemBySlot(slot).copy());
|
||||
}
|
||||
});
|
||||
helper.succeedWhen(() -> {
|
||||
helper.assertSecondsPassed(9);
|
||||
helper.assertEntityPresent(EntityType.ZOMBIE, lava);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user