Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Will place the structure at the given location in multiple ticks.
- * The bigger the structure, the longer it will take to place.
- * TODO: structureRotation, mirror, palette, integrity and random are not used.
- *
- * @param location - The location to place the structure at.
- * @param includeEntities - If the entities present in the structure should be spawned.
- * @param structureRotation - The rotation of the structure.
- * @param mirror - The mirror settings of the structure.
- * @param palette - The palette index of the structure to use, starting at 0, or -1 to pick a random palette.
- * @param integrity - Determines how damaged the building should look by randomly skipping blocks to place. This value can range from 0 to 1. With 0 removing all blocks and 1 spawning the structure in pristine condition.
- * @param random - The randomizer used for setting the structure's LootTables and integrity.
- * @param maxPlacedPerPeriod - The maximum amount of blocks/entities placed per period.
- * @param period - The period between each placement in ticks.
- * @param placedBlockConsumer - The consumer that will be called when a block is placed.
- * @param placedEntityConsumer - The consumer that will be called when an entity is placed.
- * @return A CompletableFuture that completes when the structure is placed.
- */
- public CompletableFuture<Void> chainedPlace(Location location, boolean includeEntities,
- StructureRotation structureRotation, Mirror mirror,
- int palette, float integrity, Random random,
- int maxPlacedPerPeriod, long period,
- Consumer<BlockState> placedBlockConsumer,
- Consumer<Entity> placedEntityConsumer) {
- /*
- * The location of the returned block states and entities
- * are offsets relative to the structure's position that
- * is provided once the structure is placed into the world.
- */
- CompletableFuture<Void> chainedPlace = new CompletableFuture<>();
- List<Palette> palettes = structure.getPalettes();
- List<BlockState> blocks = palettes.stream().map(Palette::getBlocks)
- .flatMap(List::stream).toList();
- Iterator<BlockState> iterator = blocks.iterator();
- World world = location.getWorld();
- if (world == null)
- throw new IllegalArgumentException("Location must have a world.");
- var nmsWorld = ((CraftWorld) world).getHandle();
- try {
- // Will place blocks
- CompletableFuture<Void> paletteFuture = new CompletableFuture<>();
- BukkitRunnable placeTask = new BukkitRunnable() {
- @Override
- public void run() {
- Uber<Integer> maxPlaced = Uber.drive(0);
- while (iterator.hasNext() && maxPlaced.thanks() < maxPlacedPerPeriod) {
- BlockState blockState = iterator.next();
- Location blockLocation = location.clone().add(blockState.getX(), blockState.getY(), blockState.getZ());
- BlockState current = blockLocation.getBlock().getState();
- current.setType(blockState.getType());
- current.setBlockData(blockState.getBlockData());
- placedBlockConsumer.accept(current);
- maxPlaced.talk(maxPlaced.thanks() + 1);
- }
- if (!iterator.hasNext()) {
- paletteFuture.complete(null);
- this.cancel();
- }
- }
- };
- placeTask.runTaskTimer(plugin, 1L, period);
- //Once blocks are placed, will place entities
- paletteFuture.whenComplete((aVoid, throwable) -> {
- if (!includeEntities) {
- chainedPlace.complete(null);
- return;
- }
- Iterator<Entity> entityIterator = structure.getEntities().iterator();
- BukkitRunnable entityTask = new BukkitRunnable() {
- @Override
- public void run() {
- Uber<Integer> maxPlaced = Uber.drive(0);
- while (entityIterator.hasNext() && maxPlaced.thanks() < maxPlacedPerPeriod) {
- Entity entity = entityIterator.next();
- Location offset = entity.getLocation();
- Location entityLocation = location.clone().add(offset.getX(), offset.getY(), offset.getZ());
- entityLocation.setPitch(offset.getPitch());
- entityLocation.setYaw(offset.getYaw());
- placedEntityConsumer.accept(entity);
- /*
- * Intermediate level of API-NMS
- * Known to work in 1.20.1
- * Might break in future versions
- */
- var nmsEntity = ((CraftEntity) entity).getHandle();
- if (!nmsWorld.tryAddFreshEntityWithPassengers
- (nmsEntity, CreatureSpawnEvent.SpawnReason.CUSTOM))
- continue;
- entity = nmsEntity.getBukkitEntity();
- entity.teleport(entityLocation);
- maxPlaced.talk(maxPlaced.thanks() + 1);
- }
- if (!iterator.hasNext()) {
- chainedPlace.complete(null);
- this.cancel();
- }
- }
- };
- entityTask.runTaskTimer(plugin, 1L, period);
- });
- } catch (Exception e) {
- chainedPlace.completeExceptionally(e);
- }
- return chainedPlace;
- }
Advertisement
Add Comment
Please, Sign In to add comment