Search in sources :

Example 1 with NotifyNeighborBlockEvent

use of org.spongepowered.api.event.block.NotifyNeighborBlockEvent in project SpongeCommon by SpongePowered.

the class MixinTileEntityPiston method fireEvent.

private void fireEvent(CallbackInfo ci) {
    if (this.world.isRemote) {
        this.world.neighborChanged(this.pos, this.pistonState.getBlock(), this.pos);
        ci.cancel();
        return;
    }
    NotifyNeighborBlockEvent event = SpongeCommonEventFactory.callNotifyNeighborEvent((World) this.world, this.pos, java.util.EnumSet.of(this.pistonFacing.getOpposite()));
    if (event == null || !event.isCancelled() && !event.getNeighbors().isEmpty()) {
        this.world.neighborChanged(this.pos, this.pistonState.getBlock(), this.pos);
    }
    // We cancel here to avoid Forge event call in SF
    ci.cancel();
}
Also used : NotifyNeighborBlockEvent(org.spongepowered.api.event.block.NotifyNeighborBlockEvent)

Example 2 with NotifyNeighborBlockEvent

use of org.spongepowered.api.event.block.NotifyNeighborBlockEvent in project SpongeCommon by SpongePowered.

the class MixinWorldServer method notifyNeighborsOfStateExcept.

/**
 * @author gabizou - March 12th, 2016
 *
 * Technically an overwrite to properly track on *server* worlds.
 */
@Override
public void notifyNeighborsOfStateExcept(BlockPos pos, Block blockType, EnumFacing skipSide) {
    if (!isValid(pos)) {
        return;
    }
    final Chunk chunk = ((IMixinChunkProviderServer) this.getChunkProvider()).getLoadedChunkWithoutMarkingActive(pos.getX() >> 4, pos.getZ() >> 4);
    // Don't let neighbor updates trigger a chunk load ever
    if (chunk == null) {
        return;
    }
    EnumSet<EnumFacing> directions = EnumSet.copyOf(NOTIFY_DIRECTIONS);
    directions.remove(skipSide);
    final NotifyNeighborBlockEvent event = SpongeCommonEventFactory.callNotifyNeighborEvent(this, pos, directions);
    if (event == null || !event.isCancelled()) {
        final PhaseTracker phaseTracker = PhaseTracker.getInstance();
        for (EnumFacing facing : EnumFacing.values()) {
            if (event != null) {
                final Direction direction = DirectionFacingProvider.getInstance().getKey(facing).get();
                if (!event.getNeighbors().keySet().contains(direction)) {
                    continue;
                }
            }
            phaseTracker.notifyBlockOfStateChange(this, pos.offset(facing), blockType, pos);
        }
    }
}
Also used : NotifyNeighborBlockEvent(org.spongepowered.api.event.block.NotifyNeighborBlockEvent) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) EnumFacing(net.minecraft.util.EnumFacing) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) Chunk(net.minecraft.world.chunk.Chunk) IMixinChunkProviderServer(org.spongepowered.common.interfaces.world.gen.IMixinChunkProviderServer) Direction(org.spongepowered.api.util.Direction)

Example 3 with NotifyNeighborBlockEvent

use of org.spongepowered.api.event.block.NotifyNeighborBlockEvent in project SpongeForge by SpongePowered.

the class SpongeForgeEventFactory method callNeighborNotifyEvent.

public static NotifyNeighborBlockEvent callNeighborNotifyEvent(Event event) {
    NotifyNeighborBlockEvent spongeEvent = (NotifyNeighborBlockEvent) event;
    LocatableBlock locatableBlock = spongeEvent.getCause().first(LocatableBlock.class).orElse(null);
    TileEntity tileEntitySource = spongeEvent.getCause().first(TileEntity.class).orElse(null);
    Location<World> sourceLocation = null;
    IBlockState state = null;
    if (locatableBlock != null) {
        Location<World> location = locatableBlock.getLocation();
        sourceLocation = location;
        state = (IBlockState) locatableBlock.getBlockState();
    } else if (tileEntitySource != null) {
        sourceLocation = tileEntitySource.getLocation();
        state = (IBlockState) sourceLocation.getBlock();
    } else {
        // should never happen but just in case it does
        return spongeEvent;
    }
    EnumSet<EnumFacing> facings = EnumSet.noneOf(EnumFacing.class);
    for (Map.Entry<Direction, BlockState> mapEntry : spongeEvent.getNeighbors().entrySet()) {
        if (mapEntry.getKey() != Direction.NONE) {
            facings.add(DirectionFacingProvider.getInstance().get(mapEntry.getKey()).get());
        }
    }
    if (facings.isEmpty()) {
        return spongeEvent;
    }
    BlockPos pos = ((IMixinLocation) (Object) sourceLocation).getBlockPos();
    net.minecraft.world.World world = (net.minecraft.world.World) sourceLocation.getExtent();
    // TODO - the boolean forced redstone bit needs to be set properly
    final NeighborNotifyEvent forgeEvent = new NeighborNotifyEvent(world, pos, state, facings, false);
    ((IMixinEventBus) MinecraftForge.EVENT_BUS).post(forgeEvent, true);
    if (forgeEvent.isCanceled()) {
        spongeEvent.setCancelled(true);
    }
    return spongeEvent;
}
Also used : IBlockState(net.minecraft.block.state.IBlockState) IMixinLocation(org.spongepowered.common.interfaces.world.IMixinLocation) EnumFacing(net.minecraft.util.EnumFacing) World(org.spongepowered.api.world.World) IMixinWorld(org.spongepowered.common.interfaces.world.IMixinWorld) Direction(org.spongepowered.api.util.Direction) TileEntity(org.spongepowered.api.block.tileentity.TileEntity) IMixinEventBus(org.spongepowered.mod.interfaces.IMixinEventBus) NotifyNeighborBlockEvent(org.spongepowered.api.event.block.NotifyNeighborBlockEvent) BlockState(org.spongepowered.api.block.BlockState) IBlockState(net.minecraft.block.state.IBlockState) NeighborNotifyEvent(net.minecraftforge.event.world.BlockEvent.NeighborNotifyEvent) LocatableBlock(org.spongepowered.api.world.LocatableBlock) BlockPos(net.minecraft.util.math.BlockPos) Map(java.util.Map)

Example 4 with NotifyNeighborBlockEvent

use of org.spongepowered.api.event.block.NotifyNeighborBlockEvent in project SpongeCommon by SpongePowered.

the class NeighborNotification method markCancelledTransactions.

@Override
public boolean markCancelledTransactions(final NotifyNeighborBlockEvent event, final ImmutableList<? extends GameTransaction<NotifyNeighborBlockEvent>> blockTransactions) {
    boolean cancelledAny = false;
    for (final NotificationTicket transaction : event.tickets()) {
        if (!transaction.valid()) {
            cancelledAny = true;
            for (final GameTransaction<NotifyNeighborBlockEvent> gameTransaction : blockTransactions) {
                final NeighborNotification blockTransaction = (NeighborNotification) gameTransaction;
                final Vector3i position = transaction.targetPosition();
                final BlockPos affectedPosition = blockTransaction.affectedPosition;
                if (position.x() == affectedPosition.getX() && position.y() == affectedPosition.getY() && position.z() == affectedPosition.getZ()) {
                    gameTransaction.markCancelled();
                }
            }
        }
    }
    return cancelledAny;
}
Also used : NotifyNeighborBlockEvent(org.spongepowered.api.event.block.NotifyNeighborBlockEvent) Vector3i(org.spongepowered.math.vector.Vector3i) SpongeNotificationTicket(org.spongepowered.common.block.SpongeNotificationTicket) NotificationTicket(org.spongepowered.api.block.transaction.NotificationTicket) BlockPos(net.minecraft.core.BlockPos)

Example 5 with NotifyNeighborBlockEvent

use of org.spongepowered.api.event.block.NotifyNeighborBlockEvent in project SpongeCommon by SpongePowered.

the class SpongeCommonEventFactory method callNotifyNeighborEvent.

@SuppressWarnings("rawtypes")
public static NotifyNeighborBlockEvent callNotifyNeighborEvent(World world, BlockPos sourcePos, EnumSet notifiedSides) {
    final PhaseTracker phaseTracker = PhaseTracker.getInstance();
    final PhaseData peek = phaseTracker.getCurrentPhaseData();
    final PhaseContext<?> context = peek.context;
    // Don't fire notify events during world gen or while restoring
    if (peek.state.isWorldGeneration() || peek.state == State.RESTORING_BLOCKS) {
        return null;
    }
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        final BlockState blockstate = (BlockState) ((net.minecraft.world.World) world).getBlockState(sourcePos);
        final LocatableBlock locatable = LocatableBlock.builder().location(new Location<World>(world, sourcePos.getX(), sourcePos.getY(), sourcePos.getZ())).state(blockstate).build();
        if (context.getNotifier().isPresent()) {
            context.addNotifierAndOwnerToCauseStack();
        } else {
            final IMixinChunk mixinChunk = (IMixinChunk) ((WorldServer) world).getChunkFromBlockCoords(sourcePos);
            mixinChunk.getBlockNotifier(sourcePos).ifPresent(user -> Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, user));
            mixinChunk.getBlockOwner(sourcePos).ifPresent(owner -> Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, owner));
        }
        Sponge.getCauseStackManager().pushCause(locatable);
        final Map<Direction, BlockState> neighbors = new HashMap<>();
        for (Object obj : notifiedSides) {
            EnumFacing notifiedSide = (EnumFacing) obj;
            BlockPos offset = sourcePos.offset(notifiedSide);
            Direction direction = DirectionFacingProvider.getInstance().getKey(notifiedSide).get();
            Location<World> location = new Location<>(world, VecHelper.toVector3i(offset));
            if (location.getBlockY() >= 0 && location.getBlockY() <= 255) {
                neighbors.put(direction, location.getBlock());
            }
        }
        // ImmutableMap<Direction, BlockState> originalNeighbors =
        // ImmutableMap.copyOf(neighbors);
        NotifyNeighborBlockEvent event = SpongeEventFactory.createNotifyNeighborBlockEvent(Sponge.getCauseStackManager().getCurrentCause(), neighbors, neighbors);
        SpongeImpl.postEvent(event);
        return event;
    }
}
Also used : PhaseData(org.spongepowered.common.event.tracking.PhaseData) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) HashMap(java.util.HashMap) EnumFacing(net.minecraft.util.EnumFacing) World(org.spongepowered.api.world.World) Direction(org.spongepowered.api.util.Direction) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) BlockState(org.spongepowered.api.block.BlockState) IBlockState(net.minecraft.block.state.IBlockState) NotifyNeighborBlockEvent(org.spongepowered.api.event.block.NotifyNeighborBlockEvent) CauseStackManager(org.spongepowered.api.event.CauseStackManager) LocatableBlock(org.spongepowered.api.world.LocatableBlock) IInteractionObject(net.minecraft.world.IInteractionObject) BlockPos(net.minecraft.util.math.BlockPos) Location(org.spongepowered.api.world.Location)

Aggregations

NotifyNeighborBlockEvent (org.spongepowered.api.event.block.NotifyNeighborBlockEvent)7 EnumFacing (net.minecraft.util.EnumFacing)5 Direction (org.spongepowered.api.util.Direction)4 BlockPos (net.minecraft.util.math.BlockPos)3 PhaseTracker (org.spongepowered.common.event.tracking.PhaseTracker)3 IMixinChunk (org.spongepowered.common.interfaces.IMixinChunk)3 IBlockState (net.minecraft.block.state.IBlockState)2 Chunk (net.minecraft.world.chunk.Chunk)2 BlockState (org.spongepowered.api.block.BlockState)2 LocatableBlock (org.spongepowered.api.world.LocatableBlock)2 World (org.spongepowered.api.world.World)2 IMixinChunkProviderServer (org.spongepowered.common.interfaces.world.gen.IMixinChunkProviderServer)2 HashMap (java.util.HashMap)1 Map (java.util.Map)1 BlockPos (net.minecraft.core.BlockPos)1 IInteractionObject (net.minecraft.world.IInteractionObject)1 NeighborNotifyEvent (net.minecraftforge.event.world.BlockEvent.NeighborNotifyEvent)1 TileEntity (org.spongepowered.api.block.tileentity.TileEntity)1 NotificationTicket (org.spongepowered.api.block.transaction.NotificationTicket)1 CauseStackManager (org.spongepowered.api.event.CauseStackManager)1