use of net.minecraft.world.level.block.piston.PistonStructureResolver in project MinecraftForge by MinecraftForge.
the class PistonEventTest method pistonPre.
@SubscribeEvent
public static void pistonPre(PistonEvent.Pre event) {
if (event.getPistonMoveType() == PistonMoveType.EXTEND) {
Level world = (Level) event.getWorld();
PistonStructureResolver pistonHelper = event.getStructureHelper();
Player player = DistExecutor.safeCallWhenOn(Dist.CLIENT, () -> () -> Minecraft.getInstance().player);
if (world.isClientSide && player != null) {
if (pistonHelper.resolve()) {
player.sendMessage(new TextComponent(String.format(Locale.ENGLISH, "Piston will extend moving %d blocks and destroy %d blocks", pistonHelper.getToPush().size(), pistonHelper.getToDestroy().size())), player.getUUID());
} else {
player.sendMessage(new TextComponent("Piston won't extend"), player.getUUID());
}
}
if (pistonHelper.resolve()) {
List<BlockPos> posList = pistonHelper.getToPush();
for (BlockPos newPos : posList) {
BlockState state = event.getWorld().getBlockState(newPos);
if (state.getBlock() == Blocks.BLACK_WOOL) {
Block.dropResources(state, world, newPos);
world.setBlockAndUpdate(newPos, Blocks.AIR.defaultBlockState());
}
}
}
// Make the block move up and out of the way so long as it won't replace the piston
BlockPos pushedBlockPos = event.getFaceOffsetPos();
if (world.getBlockState(pushedBlockPos).getBlock() == shiftOnMove.get() && event.getDirection() != Direction.DOWN) {
world.setBlockAndUpdate(pushedBlockPos, Blocks.AIR.defaultBlockState());
world.setBlockAndUpdate(pushedBlockPos.above(), shiftOnMove.get().defaultBlockState());
}
// Block pushing cobblestone (directly, indirectly works)
event.setCanceled(event.getWorld().getBlockState(event.getFaceOffsetPos()).getBlock() == Blocks.COBBLESTONE);
} else {
boolean isSticky = event.getWorld().getBlockState(event.getPos()).getBlock() == Blocks.STICKY_PISTON;
Player player = DistExecutor.safeCallWhenOn(Dist.CLIENT, () -> () -> Minecraft.getInstance().player);
if (event.getWorld().isClientSide() && player != null) {
if (isSticky) {
BlockPos targetPos = event.getFaceOffsetPos().relative(event.getDirection());
boolean canPush = PistonBaseBlock.isPushable(event.getWorld().getBlockState(targetPos), (Level) event.getWorld(), event.getFaceOffsetPos(), event.getDirection().getOpposite(), false, event.getDirection());
boolean isAir = event.getWorld().isEmptyBlock(targetPos);
player.sendMessage(new TextComponent(String.format(Locale.ENGLISH, "Piston will retract moving %d blocks", !isAir && canPush ? 1 : 0)), player.getUUID());
} else {
player.sendMessage(new TextComponent("Piston will retract"), player.getUUID());
}
}
// Offset twice to see if retraction will pull cobblestone
event.setCanceled(event.getWorld().getBlockState(event.getFaceOffsetPos().relative(event.getDirection())).getBlock() == Blocks.COBBLESTONE && isSticky);
}
}
use of net.minecraft.world.level.block.piston.PistonStructureResolver in project SpongeCommon by SpongePowered.
the class SpongeCommonEventFactory method handlePistonEvent.
/**
* This simulates the blocks a piston moves and calls the event for saner
* debugging.
*
* @return if the event was cancelled
*/
public static boolean handlePistonEvent(final TrackedWorldBridge world, final BlockPos pos, final net.minecraft.world.level.block.state.BlockState blockstate, final int eventId) {
final boolean extending = (eventId == 0);
final net.minecraft.core.Direction direction = blockstate.getValue(DirectionalBlock.FACING);
final LocatableBlock locatable = new SpongeLocatableBlockBuilder().world((ServerWorld) world).state((BlockState) blockstate).position(pos.getX(), pos.getY(), pos.getZ()).build();
// Sets toss out duplicate values (even though there shouldn't be any)
final HashSet<ServerLocation> locations = new HashSet<>();
locations.add(ServerLocation.of((ServerWorld) world, pos.getX(), pos.getY(), pos.getZ()));
final PistonStructureResolver movedBlocks = new PistonStructureResolver((ServerLevel) world, pos, direction, extending);
// calculates blocks to be moved
movedBlocks.resolve();
Stream.concat(movedBlocks.getToPush().stream(), movedBlocks.getToDestroy().stream()).map(block -> ServerLocation.of((ServerWorld) world, block.getX(), block.getY(), block.getZ())).collect(// SUPER
Collectors.toCollection(() -> locations));
// If the piston is extending and there are no blocks to destroy, add the offset location for protection purposes
if (extending && movedBlocks.getToDestroy().isEmpty()) {
final List<BlockPos> movedPositions = movedBlocks.getToPush();
final BlockPos offsetPos;
// If there are no blocks to move, add the offset of piston
if (movedPositions.isEmpty()) {
offsetPos = pos.relative(direction);
} else {
// Add the offset of last block set to move
offsetPos = movedPositions.get(movedPositions.size() - 1).relative(direction);
}
locations.add(ServerLocation.of((ServerWorld) world, offsetPos.getX(), offsetPos.getY(), offsetPos.getZ()));
}
try (final CauseStackManager.StackFrame frame = PhaseTracker.getInstance().pushCauseFrame()) {
if (extending) {
frame.addContext(EventContextKeys.PISTON_EXTEND, (ServerWorld) world);
} else {
frame.addContext(EventContextKeys.PISTON_RETRACT, (ServerWorld) world);
}
return SpongeCommonEventFactory.callChangeBlockEventPre((ServerLevelBridge) world, ImmutableList.copyOf(locations), locatable).isCancelled();
}
}
Aggregations