use of org.spongepowered.api.world.LocatableBlock 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(IMixinWorldServer world, WorldServer.ServerBlockEventList list, Object obj, BlockPos pos, Block blockIn, int eventId, int eventParam) {
boolean extending = (eventId == 0);
final IBlockState blockstate = ((net.minecraft.world.World) world).getBlockState(pos);
EnumFacing direction = blockstate.getValue(BlockDirectional.FACING);
final LocatableBlock locatable = LocatableBlock.builder().location(new Location<>((World) world, pos.getX(), pos.getY(), pos.getZ())).state((BlockState) blockstate).build();
// Sets toss out duplicate values (even though there shouldn't be any)
HashSet<Location<org.spongepowered.api.world.World>> locations = new HashSet<>();
locations.add(new Location<>((World) world, pos.getX(), pos.getY(), pos.getZ()));
BlockPistonStructureHelper movedBlocks = new BlockPistonStructureHelper((WorldServer) world, pos, direction, extending);
// calculates blocks to be moved
movedBlocks.canMove();
Stream.concat(movedBlocks.getBlocksToMove().stream(), movedBlocks.getBlocksToDestroy().stream()).map(block -> new Location<>((World) 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.getBlocksToDestroy().isEmpty()) {
final List<BlockPos> movedPositions = movedBlocks.getBlocksToMove();
BlockPos offsetPos;
// If there are no blocks to move, add the offset of piston
if (movedPositions.isEmpty()) {
offsetPos = pos.offset(direction);
} else {
// Add the offset of last block set to move
offsetPos = movedPositions.get(movedPositions.size() - 1).offset(direction);
}
locations.add(new Location<>((World) world, offsetPos.getX(), offsetPos.getY(), offsetPos.getZ()));
}
try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
if (extending) {
Sponge.getCauseStackManager().addContext(EventContextKeys.PISTON_EXTEND, world.asSpongeWorld());
} else {
Sponge.getCauseStackManager().addContext(EventContextKeys.PISTON_RETRACT, world.asSpongeWorld());
}
return SpongeCommonEventFactory.callChangeBlockEventPre(world, ImmutableList.copyOf(locations), locatable).isCancelled();
}
}
use of org.spongepowered.api.world.LocatableBlock in project SpongeCommon by SpongePowered.
the class BlockEventTickPhaseState method associateNeighborStateNotifier.
@Override
public void associateNeighborStateNotifier(BlockEventTickContext context, @Nullable BlockPos sourcePos, Block block, BlockPos notifyPos, WorldServer minecraftWorld, PlayerTracker.Type notifier) {
if (sourcePos == null) {
LocatableBlock locatableBlock = context.getSource(LocatableBlock.class).orElse(null);
if (locatableBlock == null) {
TileEntity tileEntity = context.getSource(TileEntity.class).orElseThrow(TrackingUtil.throwWithContext("Expected to be ticking over at a TileEntity!", context));
locatableBlock = tileEntity.getLocatableBlock();
}
sourcePos = ((IMixinLocation) (Object) locatableBlock.getLocation()).getBlockPos();
}
final User user = context.getNotifier().orElse(TrackingUtil.getNotifierOrOwnerFromBlock(minecraftWorld, sourcePos));
if (user != null) {
final IMixinChunk mixinChunk = (IMixinChunk) minecraftWorld.getChunkFromBlockCoords(notifyPos);
mixinChunk.addTrackedBlockPosition(block, notifyPos, user, PlayerTracker.Type.NOTIFIER);
}
}
use of org.spongepowered.api.world.LocatableBlock in project SpongeCommon by SpongePowered.
the class BlockTickPhaseState method unwind.
@Override
public void unwind(BlockTickContext context) {
final LocatableBlock locatableBlock = context.requireSource(LocatableBlock.class);
try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
Sponge.getCauseStackManager().pushCause(locatableBlock);
Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
final User entityCreator = context.getNotifier().orElseGet(() -> context.getOwner().orElse(null));
context.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(blockSnapshots -> TrackingUtil.processBlockCaptures(blockSnapshots, this, context));
context.getCapturedItemsSupplier().acceptAndClearIfNotEmpty(items -> {
final ArrayList<Entity> capturedEntities = new ArrayList<>();
for (EntityItem entity : items) {
capturedEntities.add(EntityUtil.fromNative(entity));
}
final SpawnEntityEvent spawnEntityEvent = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), capturedEntities);
SpongeImpl.postEvent(spawnEntityEvent);
for (Entity entity : spawnEntityEvent.getEntities()) {
if (entityCreator != null) {
EntityUtil.toMixin(entity).setCreator(entityCreator.getUniqueId());
}
EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
}
});
}
}
use of org.spongepowered.api.world.LocatableBlock in project SpongeCommon by SpongePowered.
the class BlockTickPhaseState method appendContextPreExplosion.
@Override
public void appendContextPreExplosion(ExplosionContext explosionContext, BlockTickContext context) {
context.getOwner().ifPresent(explosionContext::owner);
context.getNotifier().ifPresent(explosionContext::notifier);
final LocatableBlock locatableBlock = getLocatableBlockSourceFromContext(context);
explosionContext.source(locatableBlock);
}
use of org.spongepowered.api.world.LocatableBlock in project SpongeCommon by SpongePowered.
the class LocationBasedTickPhaseState method associateNeighborStateNotifier.
@Override
public void associateNeighborStateNotifier(T context, @Nullable BlockPos sourcePos, Block block, BlockPos notifyPos, WorldServer minecraftWorld, PlayerTracker.Type notifier) {
if (sourcePos == null) {
LocatableBlock locatableBlock = this.getLocatableBlockSourceFromContext(context);
sourcePos = ((IMixinLocation) (Object) locatableBlock.getLocation()).getBlockPos();
}
User user = context.getNotifier().orElse(TrackingUtil.getNotifierOrOwnerFromBlock(minecraftWorld, sourcePos));
if (user != null) {
final IMixinChunk mixinChunk = (IMixinChunk) minecraftWorld.getChunkFromBlockCoords(notifyPos);
mixinChunk.addTrackedBlockPosition(block, notifyPos, user, PlayerTracker.Type.NOTIFIER);
}
}
Aggregations