use of org.spongepowered.api.block.BlockState 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();
}
}
use of org.spongepowered.api.block.BlockState in project SpongeCommon by SpongePowered.
the class PlaceBlockPacketState method appendNotifierToBlockEvent.
@Override
public void appendNotifierToBlockEvent(final BasicPacketContext context, final TrackedWorldBridge mixinWorldServer, final BlockPos pos, final TrackableBlockEventDataBridge blockEvent) {
final Player player = PhaseTracker.getCauseStackManager().currentCause().first(Player.class).get();
final BlockState state = ((ServerWorld) mixinWorldServer).block(pos.getX(), pos.getY(), pos.getZ());
final LocatableBlock locatable = new SpongeLocatableBlockBuilder().world((ServerWorld) mixinWorldServer).position(pos.getX(), pos.getY(), pos.getZ()).state(state).build();
blockEvent.bridge$setTickingLocatable(locatable);
blockEvent.bridge$setSourceUserUUID(player.uniqueId());
}
use of org.spongepowered.api.block.BlockState in project SpongeCommon by SpongePowered.
the class DefaultTeleportHelperFilter method isSafeBodyMaterial.
@Override
public boolean isSafeBodyMaterial(BlockState blockState) {
net.minecraft.world.level.block.state.BlockState state = (net.minecraft.world.level.block.state.BlockState) blockState;
Material material = state.getMaterial();
// Deny blocks that suffocate
if (state.isSuffocating(EmptyBlockGetter.INSTANCE, BlockPos.ZERO)) {
return false;
}
// Deny dangerous lava
if (material == Material.LAVA) {
return false;
}
// Deny non-passable non "full" blocks
return !(state.getBlock() instanceof SlabBlock || state.getBlock() instanceof CauldronBlock || state.getBlock() instanceof AnvilBlock || state.getBlock() instanceof FenceBlock || state.getBlock() instanceof ChorusPlantBlock || state.getBlock() instanceof SnowLayerBlock || material == Material.GLASS || material == Material.LEAVES);
}
use of org.spongepowered.api.block.BlockState in project SpongeCommon by SpongePowered.
the class SchematicTranslator method deserializeBlockContainer.
private static void deserializeBlockContainer(final DataView view, final SpongeArchetypeVolume archetypeVolume, final int width, final int length, final Vector3i offset, final boolean needsFixers) {
final MutableBimapPalette<BlockState, BlockType> palette;
final DataView paletteMap = view.getView(Constants.Sponge.Schematic.BLOCK_PALETTE).orElseThrow(() -> new InvalidDataException("Missing BlockPalette as required by Schematic Specification"));
final Set<DataQuery> paletteKeys = paletteMap.keys(false);
// If we had a default palette_max we don't want to allocate all
// that space for nothing so we use a sensible default instead
palette = new MutableBimapPalette<>(PaletteTypes.BLOCK_STATE_PALETTE.get(), Sponge.game().registry(RegistryTypes.BLOCK_TYPE), RegistryTypes.BLOCK_TYPE, paletteKeys.size());
for (final DataQuery key : paletteKeys) {
final BlockState state = BlockStateSerializerDeserializer.deserialize(key.parts().get(0)).orElseGet(() -> BlockTypes.BEDROCK.get().defaultState());
palette.assign(state, paletteMap.getInt(key).orElseThrow(() -> new IllegalStateException("Somehow got a missing biome in the palette map for schematic")));
}
final byte[] blockData = (byte[]) view.get(Constants.Sponge.Schematic.BLOCK_DATA).orElseThrow(() -> new InvalidDataException("Missing BlockData for Schematic"));
SchematicTranslator.readByteArrayData(width, (width * length), offset, palette, blockData, archetypeVolume, BlockVolume.Modifiable::setBlock);
view.getViewList(Constants.Sponge.Schematic.BLOCKENTITY_CONTAINER).ifPresent(tileData -> tileData.forEach(SchematicTranslator.deserializeBlockEntities(offset, archetypeVolume, needsFixers)));
}
use of org.spongepowered.api.block.BlockState in project SpongeCommon by SpongePowered.
the class VolumeTransformationTest method fillVolume.
private static SpongeArchetypeVolume fillVolume(final Vector3i min, final Vector3i max, final Vector3i origin) {
final Vector3i rawMin = min.min(max);
final Vector3i rawMax = max.max(min);
final Vector3i size = rawMax.sub(rawMin).add(Vector3i.ONE);
final Vector3i relativeMin = rawMin.sub(origin);
final RegistryHolder holder = Sponge.game();
final SpongeArchetypeVolume volume = new SpongeArchetypeVolume(relativeMin, size, holder);
final StubbedRegistry<BlockType> blockRegistry = (StubbedRegistry<BlockType>) RegistryTypes.BLOCK_TYPE.get();
final Vector3i volMax = volume.max().add(Vector3i.ONE);
IntStream.range(relativeMin.x(), volMax.x()).forEach(x -> IntStream.range(relativeMin.z(), volMax.z()).forEach(z -> IntStream.range(relativeMin.y(), volMax.y()).forEach(y -> {
final BlockType block = blockRegistry.createEntry("minecraft", String.format("volumetest{%d, %d, %d}", x, y, z));
final BlockState blockState = block.defaultState();
volume.setBlock(x, y, z, blockState);
})));
return volume;
}
Aggregations