Search in sources :

Example 1 with PistonStructureResolver

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);
    }
}
Also used : TextComponent(net.minecraft.network.chat.TextComponent) Player(net.minecraft.world.entity.player.Player) BlockState(net.minecraft.world.level.block.state.BlockState) PistonStructureResolver(net.minecraft.world.level.block.piston.PistonStructureResolver) Level(net.minecraft.world.level.Level) BlockPos(net.minecraft.core.BlockPos) SubscribeEvent(net.minecraftforge.eventbus.api.SubscribeEvent)

Example 2 with PistonStructureResolver

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();
    }
}
Also used : ServerLevelBridge(org.spongepowered.common.bridge.server.level.ServerLevelBridge) ChangeBlockEvent(org.spongepowered.api.event.block.ChangeBlockEvent) SpongeAdventure(org.spongepowered.common.adventure.SpongeAdventure) CreatorTrackedBridge(org.spongepowered.common.bridge.CreatorTrackedBridge) Living(org.spongepowered.api.entity.living.Living) JukeboxBlockEntity(net.minecraft.world.level.block.entity.JukeboxBlockEntity) ServerboundPlayerActionPacket(net.minecraft.network.protocol.game.ServerboundPlayerActionPacket) Set(java.util.Set) MapIdTrackerBridge(org.spongepowered.common.bridge.map.MapIdTrackerBridge) BlockState(org.spongepowered.api.block.BlockState) Direction(org.spongepowered.api.util.Direction) ConstructEntityEvent(org.spongepowered.api.event.entity.ConstructEntityEvent) Stream(java.util.stream.Stream) World(org.spongepowered.api.world.World) ItemStack(net.minecraft.world.item.ItemStack) Player(org.spongepowered.api.entity.living.player.Player) MoveEntityEvent(org.spongepowered.api.event.entity.MoveEntityEvent) ServerLocation(org.spongepowered.api.world.server.ServerLocation) SpongeMapStorage(org.spongepowered.common.map.SpongeMapStorage) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge) EventContextKeys(org.spongepowered.api.event.EventContextKeys) ServerWorld(org.spongepowered.api.world.server.ServerWorld) DestructEntityEvent(org.spongepowered.api.event.entity.DestructEntityEvent) Agent(org.spongepowered.api.entity.living.Agent) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) EntityBridge(org.spongepowered.common.bridge.world.entity.EntityBridge) RotateEntityEvent(org.spongepowered.api.event.entity.RotateEntityEvent) PlaySoundEvent(org.spongepowered.api.event.sound.PlaySoundEvent) DetonateExplosiveEvent(org.spongepowered.api.event.entity.explosive.DetonateExplosiveEvent) InteractBlockEvent(org.spongepowered.api.event.block.InteractBlockEvent) CauseStackManager(org.spongepowered.api.event.CauseStackManager) GeneralPhase(org.spongepowered.common.event.tracking.phase.general.GeneralPhase) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) PlayerTracker(org.spongepowered.common.entity.PlayerTracker) UnknownProjectileSource(org.spongepowered.common.entity.projectile.UnknownProjectileSource) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) Entity(org.spongepowered.api.entity.Entity) Cause(org.spongepowered.api.event.Cause) Explosive(org.spongepowered.api.entity.explosive.Explosive) PistonStructureResolver(net.minecraft.world.level.block.piston.PistonStructureResolver) Audience(net.kyori.adventure.audience.Audience) VecHelper(org.spongepowered.common.util.VecHelper) InteractionHand(net.minecraft.world.InteractionHand) ServerPlayer(org.spongepowered.api.entity.living.player.server.ServerPlayer) LivingEntity(net.minecraft.world.entity.LivingEntity) MapItemSavedData(net.minecraft.world.level.saveddata.maps.MapItemSavedData) MusicDisc(org.spongepowered.api.effect.sound.music.MusicDisc) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) HandType(org.spongepowered.api.data.type.HandType) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) ExplosiveBridge(org.spongepowered.common.bridge.explosives.ExplosiveBridge) CollideBlockEvent(org.spongepowered.api.event.block.CollideBlockEvent) SetAITargetEvent(org.spongepowered.api.event.entity.ai.SetAITargetEvent) TrackedWorldBridge(org.spongepowered.common.bridge.world.TrackedWorldBridge) ActiveChunkReferantBridge(org.spongepowered.common.bridge.world.level.chunk.ActiveChunkReferantBridge) CollideEntityEvent(org.spongepowered.api.event.entity.CollideEntityEvent) NotePitch(org.spongepowered.api.data.type.NotePitch) InteractEntityEvent(org.spongepowered.api.event.entity.InteractEntityEvent) LocatableBlock(org.spongepowered.api.world.LocatableBlock) SoundType(org.spongepowered.api.effect.sound.SoundType) BlockHitResult(net.minecraft.world.phys.BlockHitResult) GameRules(net.minecraft.world.level.GameRules) Sponge(org.spongepowered.api.Sponge) InstrumentType(org.spongepowered.api.data.type.InstrumentType) UUID(java.util.UUID) ProjectileSource(org.spongepowered.api.projectile.source.ProjectileSource) Collectors(java.util.stream.Collectors) Tristate(org.spongepowered.api.util.Tristate) List(java.util.List) Sound(net.kyori.adventure.sound.Sound) MapInfo(org.spongepowered.api.map.MapInfo) BlockPos(net.minecraft.core.BlockPos) SoundEvent(net.minecraft.sounds.SoundEvent) Explosion(org.spongepowered.api.world.explosion.Explosion) PhaseContext(org.spongepowered.common.event.tracking.PhaseContext) Optional(java.util.Optional) InteractItemEvent(org.spongepowered.api.event.item.inventory.InteractItemEvent) Level(net.minecraft.world.level.Level) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) NonNull(org.checkerframework.checker.nullness.qual.NonNull) Constants(org.spongepowered.common.util.Constants) ServerLevel(net.minecraft.server.level.ServerLevel) Value(org.spongepowered.api.data.value.Value) EntityDamageSource(net.minecraft.world.damagesource.EntityDamageSource) HashSet(java.util.HashSet) ImmutableList(com.google.common.collect.ImmutableList) EntityTypes(org.spongepowered.api.entity.EntityTypes) ItemStackUtil(org.spongepowered.common.item.util.ItemStackUtil) Component(net.kyori.adventure.text.Component) DamageSource(net.minecraft.world.damagesource.DamageSource) SoundTypes(org.spongepowered.api.effect.sound.SoundTypes) PlatformEntityBridge(org.spongepowered.common.bridge.world.entity.PlatformEntityBridge) Nullable(org.checkerframework.checker.nullness.qual.Nullable) LevelBridge(org.spongepowered.common.bridge.world.level.LevelBridge) DirectionFacingProvider(org.spongepowered.common.registry.provider.DirectionFacingProvider) EntityHitResult(net.minecraft.world.phys.EntityHitResult) SpongeLocatableBlockBuilder(org.spongepowered.common.world.server.SpongeLocatableBlockBuilder) SpongeCommon(org.spongepowered.common.SpongeCommon) MapIndex(net.minecraft.world.level.saveddata.maps.MapIndex) HitResult(net.minecraft.world.phys.HitResult) MovementTypes(org.spongepowered.api.event.cause.entity.MovementTypes) Vector3d(org.spongepowered.math.vector.Vector3d) CreateMapEvent(org.spongepowered.api.event.action.CreateMapEvent) Block(net.minecraft.world.level.block.Block) SpawnTypes(org.spongepowered.api.event.cause.entity.SpawnTypes) Collections(java.util.Collections) DirectionalBlock(net.minecraft.world.level.block.DirectionalBlock) Jukebox(org.spongepowered.api.block.entity.Jukebox) SpongeLocatableBlockBuilder(org.spongepowered.common.world.server.SpongeLocatableBlockBuilder) ServerLocation(org.spongepowered.api.world.server.ServerLocation) ServerWorld(org.spongepowered.api.world.server.ServerWorld) CauseStackManager(org.spongepowered.api.event.CauseStackManager) PistonStructureResolver(net.minecraft.world.level.block.piston.PistonStructureResolver) LocatableBlock(org.spongepowered.api.world.LocatableBlock) BlockPos(net.minecraft.core.BlockPos) ServerLevelBridge(org.spongepowered.common.bridge.server.level.ServerLevelBridge) HashSet(java.util.HashSet)

Aggregations

BlockPos (net.minecraft.core.BlockPos)2 Level (net.minecraft.world.level.Level)2 PistonStructureResolver (net.minecraft.world.level.block.piston.PistonStructureResolver)2 ImmutableList (com.google.common.collect.ImmutableList)1 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Optional (java.util.Optional)1 Set (java.util.Set)1 UUID (java.util.UUID)1 Supplier (java.util.function.Supplier)1 Collectors (java.util.stream.Collectors)1 Stream (java.util.stream.Stream)1 Audience (net.kyori.adventure.audience.Audience)1 Sound (net.kyori.adventure.sound.Sound)1 Component (net.kyori.adventure.text.Component)1 TextComponent (net.minecraft.network.chat.TextComponent)1 ServerboundPlayerActionPacket (net.minecraft.network.protocol.game.ServerboundPlayerActionPacket)1 ServerLevel (net.minecraft.server.level.ServerLevel)1