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();
}
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);
}
}
}
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;
}
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;
}
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;
}
}
Aggregations