Guest User

Untitled

a guest
Sep 13th, 2023
20
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.21 KB | None | 0 0
  1. /**
  2. * Will place the structure at the given location in multiple ticks.
  3. * The bigger the structure, the longer it will take to place.
  4. * TODO: structureRotation, mirror, palette, integrity and random are not used.
  5. *
  6. * @param location - The location to place the structure at.
  7. * @param includeEntities - If the entities present in the structure should be spawned.
  8. * @param structureRotation - The rotation of the structure.
  9. * @param mirror - The mirror settings of the structure.
  10. * @param palette - The palette index of the structure to use, starting at 0, or -1 to pick a random palette.
  11. * @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.
  12. * @param random - The randomizer used for setting the structure's LootTables and integrity.
  13. * @param maxPlacedPerPeriod - The maximum amount of blocks/entities placed per period.
  14. * @param period - The period between each placement in ticks.
  15. * @param placedBlockConsumer - The consumer that will be called when a block is placed.
  16. * @param placedEntityConsumer - The consumer that will be called when an entity is placed.
  17. * @return A CompletableFuture that completes when the structure is placed.
  18. */
  19. public CompletableFuture<Void> chainedPlace(Location location, boolean includeEntities,
  20. StructureRotation structureRotation, Mirror mirror,
  21. int palette, float integrity, Random random,
  22. int maxPlacedPerPeriod, long period,
  23. Consumer<BlockState> placedBlockConsumer,
  24. Consumer<Entity> placedEntityConsumer) {
  25. /*
  26. * The location of the returned block states and entities
  27. * are offsets relative to the structure's position that
  28. * is provided once the structure is placed into the world.
  29. */
  30. CompletableFuture<Void> chainedPlace = new CompletableFuture<>();
  31. List<Palette> palettes = structure.getPalettes();
  32. List<BlockState> blocks = palettes.stream().map(Palette::getBlocks)
  33. .flatMap(List::stream).toList();
  34. Iterator<BlockState> iterator = blocks.iterator();
  35. World world = location.getWorld();
  36. if (world == null)
  37. throw new IllegalArgumentException("Location must have a world.");
  38. var nmsWorld = ((CraftWorld) world).getHandle();
  39. try {
  40. // Will place blocks
  41. CompletableFuture<Void> paletteFuture = new CompletableFuture<>();
  42. BukkitRunnable placeTask = new BukkitRunnable() {
  43. @Override
  44. public void run() {
  45. Uber<Integer> maxPlaced = Uber.drive(0);
  46. while (iterator.hasNext() && maxPlaced.thanks() < maxPlacedPerPeriod) {
  47. BlockState blockState = iterator.next();
  48. Location blockLocation = location.clone().add(blockState.getX(), blockState.getY(), blockState.getZ());
  49. BlockState current = blockLocation.getBlock().getState();
  50. current.setType(blockState.getType());
  51. current.setBlockData(blockState.getBlockData());
  52. placedBlockConsumer.accept(current);
  53. maxPlaced.talk(maxPlaced.thanks() + 1);
  54. }
  55. if (!iterator.hasNext()) {
  56. paletteFuture.complete(null);
  57. this.cancel();
  58. }
  59. }
  60. };
  61. placeTask.runTaskTimer(plugin, 1L, period);
  62. //Once blocks are placed, will place entities
  63. paletteFuture.whenComplete((aVoid, throwable) -> {
  64. if (!includeEntities) {
  65. chainedPlace.complete(null);
  66. return;
  67. }
  68. Iterator<Entity> entityIterator = structure.getEntities().iterator();
  69. BukkitRunnable entityTask = new BukkitRunnable() {
  70. @Override
  71. public void run() {
  72. Uber<Integer> maxPlaced = Uber.drive(0);
  73. while (entityIterator.hasNext() && maxPlaced.thanks() < maxPlacedPerPeriod) {
  74. Entity entity = entityIterator.next();
  75. Location offset = entity.getLocation();
  76. Location entityLocation = location.clone().add(offset.getX(), offset.getY(), offset.getZ());
  77. entityLocation.setPitch(offset.getPitch());
  78. entityLocation.setYaw(offset.getYaw());
  79. placedEntityConsumer.accept(entity);
  80. /*
  81. * Intermediate level of API-NMS
  82. * Known to work in 1.20.1
  83. * Might break in future versions
  84. */
  85. var nmsEntity = ((CraftEntity) entity).getHandle();
  86. if (!nmsWorld.tryAddFreshEntityWithPassengers
  87. (nmsEntity, CreatureSpawnEvent.SpawnReason.CUSTOM))
  88. continue;
  89. entity = nmsEntity.getBukkitEntity();
  90. entity.teleport(entityLocation);
  91. maxPlaced.talk(maxPlaced.thanks() + 1);
  92. }
  93. if (!iterator.hasNext()) {
  94. chainedPlace.complete(null);
  95. this.cancel();
  96. }
  97. }
  98. };
  99. entityTask.runTaskTimer(plugin, 1L, period);
  100. });
  101. } catch (Exception e) {
  102. chainedPlace.completeExceptionally(e);
  103. }
  104. return chainedPlace;
  105. }
Advertisement
Add Comment
Please, Sign In to add comment