Skip to content

Commit

Permalink
Fix Warp+Force lens behavior when hitting force relays
Browse files Browse the repository at this point in the history
(fixes #4046)
  • Loading branch information
TheRealWormbo committed Apr 2, 2024
1 parent c4d5b26 commit 1a19a43
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 1 deletion.
3 changes: 2 additions & 1 deletion Fabric/src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@
"vazkii.botania.test.item.SpectatorScanTest",
"vazkii.botania.test.item.lens.BoreLensTest",
"vazkii.botania.test.item.lens.EntropicWarpLensTest",
"vazkii.botania.test.item.lens.PaintslingerLensTest"
"vazkii.botania.test.item.lens.PaintslingerLensTest",
"vazkii.botania.test.item.lens.WarpForceTest"
],
"fabric-datagen": [
"vazkii.botania.fabric.data.FabricDatagenInitializer"
Expand Down
11 changes: 11 additions & 0 deletions Xplat/src/main/java/vazkii/botania/common/item/lens/ForceLens.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;

import vazkii.botania.api.internal.ManaBurst;
import vazkii.botania.common.block.BotaniaBlocks;
import vazkii.botania.common.helper.ForcePushHelper;
import vazkii.botania.common.item.BotaniaItems;
import vazkii.botania.mixin.PistonBaseBlockAccessor;

public class ForceLens extends Lens {
Expand All @@ -30,6 +33,14 @@ public boolean collideBurst(ManaBurst burst, HitResult pos, boolean isManaBlock,
&& !burst.isFake()
&& !isManaBlock) {
BlockHitResult rtr = (BlockHitResult) pos;
BlockState state = entity.level().getBlockState(rtr.getBlockPos());
ItemStack sourceLens = burst.getSourceLens();
boolean isWarp = sourceLens.is(BotaniaItems.lensWarp);
if (isWarp && state.is(BotaniaBlocks.pistonRelay)) {
// warp+force should not move the force relay
return false;
}

// mana burst could have been warped here, so don't assume that any block is unmovable
moveBlocks(entity.level(), rtr.getBlockPos().relative(rtr.getDirection()), rtr.getDirection().getOpposite(), ManaBurst.NO_SOURCE);
}
Expand Down
12 changes: 12 additions & 0 deletions Xplat/src/main/java/vazkii/botania/test/TestingUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import org.jetbrains.annotations.Nullable;

import vazkii.botania.common.block.ForceRelayBlock;
import vazkii.botania.common.item.BotaniaItems;

import java.util.Objects;
Expand Down Expand Up @@ -118,4 +119,15 @@ public static void bindWithWandOfTheForest(GameTestHelper helper, BlockPos first
player.setPos(Vec3.atCenterOf(second));
useItemOn(helper, player, InteractionHand.MAIN_HAND, second);
}

public static void bindForceRelayTarget(GameTestHelper helper, BlockPos relayPos, BlockPos targetPos) {
var data = ForceRelayBlock.WorldData.get(helper.getLevel());
data.mapping.put(helper.absolutePos(relayPos), helper.absolutePos(targetPos));
}

@Nullable
public static BlockPos getBoundForceRelayTarget(GameTestHelper helper, BlockPos relayPos) {
var data = ForceRelayBlock.WorldData.get(helper.getLevel());
return data.mapping.get(helper.absolutePos(relayPos));
}
}
106 changes: 106 additions & 0 deletions Xplat/src/main/java/vazkii/botania/test/item/lens/WarpForceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package vazkii.botania.test.item.lens;

import net.minecraft.core.BlockPos;
import net.minecraft.gametest.framework.GameTest;
import net.minecraft.gametest.framework.GameTestHelper;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.ButtonBlock;
import net.minecraft.world.level.block.state.BlockState;

import vazkii.botania.common.block.BotaniaBlocks;
import vazkii.botania.common.block.block_entity.BotaniaBlockEntities;
import vazkii.botania.common.item.BotaniaItems;
import vazkii.botania.common.item.lens.LensItem;
import vazkii.botania.test.TestingUtil;

public class WarpForceTest {
private static final String TEMPLATE = "botania:item/lens/force_warp_relay_interaction";

private static final BlockPos SPREADER_POS = new BlockPos(1, 2, 1);
private static final BlockPos SPREADER_TARGET_POS = new BlockPos(6, 2, 1);
private static final BlockPos BUTTON_POS = new BlockPos(1, 2, 3);
private static final BlockPos RELAY_POS = new BlockPos(3, 2, 1);
private static final BlockPos BOUND_POS = new BlockPos(3, 2, 3);

@GameTest(template = TEMPLATE, timeoutTicks = 50)
public void testWarpForceLens(GameTestHelper helper) {
setUpLensesAndBindings(helper, BotaniaItems.lensWarp, BotaniaItems.lensPiston);

helper.startSequence()
.thenExecute(() -> helper.pressButton(BUTTON_POS))
.thenWaitUntil(() -> helper.assertBlockProperty(BUTTON_POS, ButtonBlock.POWERED, false))
.thenExecute(() -> {
helper.assertBlock(RELAY_POS, BotaniaBlocks.pistonRelay::equals, () -> "Force relay moved");
helper.assertBlockState(BOUND_POS, BlockState::isAir, () -> "Bound block did not move");
helper.assertBlock(BOUND_POS.east(), Blocks.POLISHED_ANDESITE::equals,
() -> "Bound block did not move to expected position");
TestingUtil.assertEquals(TestingUtil.getBoundForceRelayTarget(helper, RELAY_POS), helper.absolutePos(BOUND_POS),
() -> "Relay binding has changed");
})
// second shot to confirm binding still works
.thenExecute(() -> helper.setBlock(BOUND_POS, Blocks.POLISHED_DIORITE))
.thenExecute(() -> helper.pressButton(BUTTON_POS))
.thenWaitUntil(() -> helper.assertBlockProperty(BUTTON_POS, ButtonBlock.POWERED, false))
.thenExecute(() -> {
helper.assertBlockState(RELAY_POS, blockState -> blockState.is(BotaniaBlocks.pistonRelay),
() -> "Force relay moved after second burst");
helper.assertBlockState(BOUND_POS, BlockState::isAir, () -> "Bound block did not move");
helper.assertBlock(BOUND_POS.east(), Blocks.POLISHED_DIORITE::equals,
() -> "New block did not move to expected position after second burst");
helper.assertBlock(BOUND_POS.east(2), Blocks.POLISHED_ANDESITE::equals,
() -> "Original block did not move to expected position after second burst");
TestingUtil.assertEquals(TestingUtil.getBoundForceRelayTarget(helper, RELAY_POS), helper.absolutePos(BOUND_POS),
() -> "Relay binding has changed after second burst");
})
.thenSucceed();
}

// TODO: Regression test for https://github.com/VazkiiMods/Botania/issues/4593
@GameTest(template = TEMPLATE, timeoutTicks = 50, required = false)
public void testForceWarpLens(GameTestHelper helper) {
setUpLensesAndBindings(helper, BotaniaItems.lensPiston, BotaniaItems.lensWarp);

helper.startSequence()
.thenExecute(() -> helper.pressButton(BUTTON_POS))
.thenWaitUntil(() -> helper.assertBlockProperty(BUTTON_POS, ButtonBlock.POWERED, false))
.thenExecute(() -> {
helper.assertBlockState(RELAY_POS, BlockState::isAir, () -> "Force relay did not move");
helper.assertBlock(RELAY_POS.east(), BotaniaBlocks.pistonRelay::equals,
() -> "Force relay did not move to expected position");
helper.assertBlockState(BOUND_POS, BlockState::isAir, () -> "Bound block did not move");
helper.assertBlock(BOUND_POS.east(), Blocks.POLISHED_ANDESITE::equals,
() -> "Bound block did not move to expected position");
TestingUtil.assertEquals(TestingUtil.getBoundForceRelayTarget(helper, RELAY_POS.east()), BOUND_POS.east(),
() -> "Relay binding was not updated");
})
// second shot to confirm binding still works
.thenExecute(() -> helper.setBlock(BOUND_POS, Blocks.POLISHED_DIORITE))
.thenExecute(() -> helper.pressButton(BUTTON_POS))
.thenWaitUntil(() -> helper.assertBlockProperty(BUTTON_POS, ButtonBlock.POWERED, false))
.thenExecute(() -> {
helper.assertBlock(BOUND_POS, Blocks.POLISHED_DIORITE::equals, () -> "New block at original bound position moved");
helper.assertBlockState(RELAY_POS.east(), BlockState::isAir, () -> "Force relay did not move after second burst");
helper.assertBlock(RELAY_POS.east(2), BotaniaBlocks.pistonRelay::equals,
() -> "Force relay did not move to expected position after second burst");
helper.assertBlockState(BOUND_POS.east(), BlockState::isAir, () -> "Bound block did not move a second time");
helper.assertBlock(BOUND_POS.east(2), Blocks.POLISHED_ANDESITE::equals,
() -> "Bound block did not move to expected position after second burst");
TestingUtil.assertEquals(TestingUtil.getBoundForceRelayTarget(helper, RELAY_POS.east(2)), BOUND_POS.east(2),
() -> "Relay binding was not updated after second burst");
})
.thenSucceed();
}

private static void setUpLensesAndBindings(GameTestHelper helper, Item firstLensType, Item secondLensType) {
final var warpLensStack = new ItemStack(firstLensType);
final var forceLensStack = new ItemStack(secondLensType);
final var compositeLens = ((LensItem) warpLensStack.getItem()).setCompositeLens(warpLensStack, forceLensStack);
final var spreaderEntity = TestingUtil.assertBlockEntity(helper, SPREADER_POS, BotaniaBlockEntities.SPREADER);
spreaderEntity.getItemHandler().setItem(0, compositeLens);

TestingUtil.bindWithWandOfTheForest(helper, SPREADER_POS, SPREADER_TARGET_POS);
TestingUtil.bindForceRelayTarget(helper, RELAY_POS, BOUND_POS);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
DataVersion: 3465,
size: [7, 3, 5],
data: [
{pos: [1, 1, 1], state: "botania:redstone_spreader{has_scaffolding:false,waterlogged:false}"},
{pos: [1, 1, 2], state: "minecraft:polished_andesite"},
{pos: [1, 1, 3], state: "minecraft:polished_blackstone_button{face:wall,facing:south,powered:false}"},
{pos: [3, 1, 1], state: "botania:piston_relay"},
{pos: [3, 1, 3], state: "minecraft:polished_andesite"},
{pos: [6, 1, 1], state: "minecraft:obsidian"},
{pos: [6, 1, 3], state: "minecraft:obsidian"},
{pos: [1, 2, 1], state: "botania:creative_pool{color:none,waterlogged:false}"}
],
entities: [],
palette: [
"minecraft:polished_andesite",
"botania:piston_relay",
"minecraft:obsidian",
"minecraft:polished_blackstone_button{face:wall,facing:south,powered:false}",
"botania:redstone_spreader{has_scaffolding:false,waterlogged:false}",
"botania:creative_pool{color:none,waterlogged:false}"
]
}

0 comments on commit 1a19a43

Please sign in to comment.