001/* 002 * PlotSquared, a land and world management plugin for Minecraft. 003 * Copyright (C) IntellectualSites <https://intellectualsites.com> 004 * Copyright (C) IntellectualSites team and contributors 005 * 006 * This program is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with this program. If not, see <https://www.gnu.org/licenses/>. 018 */ 019package com.plotsquared.core.generator; 020 021import com.google.inject.Inject; 022import com.plotsquared.core.PlotSquared; 023import com.plotsquared.core.configuration.Settings; 024import com.plotsquared.core.inject.factory.ProgressSubscriberFactory; 025import com.plotsquared.core.location.Direction; 026import com.plotsquared.core.location.Location; 027import com.plotsquared.core.player.PlotPlayer; 028import com.plotsquared.core.plot.BlockBucket; 029import com.plotsquared.core.plot.Plot; 030import com.plotsquared.core.plot.PlotAreaTerrainType; 031import com.plotsquared.core.plot.PlotId; 032import com.plotsquared.core.queue.QueueCoordinator; 033import com.plotsquared.core.util.MathMan; 034import com.plotsquared.core.util.RegionManager; 035import com.plotsquared.core.util.task.TaskManager; 036import com.sk89q.worldedit.function.pattern.Pattern; 037import com.sk89q.worldedit.regions.CuboidRegion; 038import com.sk89q.worldedit.world.block.BlockTypes; 039import org.checkerframework.checker.nullness.qual.NonNull; 040import org.checkerframework.checker.nullness.qual.Nullable; 041 042import java.util.List; 043import java.util.Optional; 044 045/** 046 * A plot manager with square plots which tessellate on a square grid with the following sections: ROAD, WALL, BORDER (wall), PLOT, FLOOR (plot). 047 */ 048public class ClassicPlotManager extends SquarePlotManager { 049 050 private final ClassicPlotWorld classicPlotWorld; 051 private final RegionManager regionManager; 052 private final ProgressSubscriberFactory subscriberFactory; 053 054 @Inject 055 public ClassicPlotManager(final @NonNull ClassicPlotWorld classicPlotWorld, final @NonNull RegionManager regionManager) { 056 super(classicPlotWorld, regionManager); 057 this.classicPlotWorld = classicPlotWorld; 058 this.regionManager = regionManager; 059 this.subscriberFactory = PlotSquared.platform().injector().getInstance(ProgressSubscriberFactory.class); 060 } 061 062 @Override 063 public boolean setComponent( 064 @NonNull PlotId plotId, 065 @NonNull String component, 066 @NonNull Pattern blocks, 067 @Nullable PlotPlayer<?> actor, 068 @Nullable QueueCoordinator queue 069 ) { 070 final Optional<ClassicPlotManagerComponent> componentOptional = ClassicPlotManagerComponent.fromString(component); 071 return componentOptional.map(classicPlotManagerComponent -> switch (classicPlotManagerComponent) { 072 case FLOOR -> setFloor(plotId, blocks, actor, queue); 073 case WALL -> setWallFilling(plotId, blocks, actor, queue); 074 case AIR -> setAir(plotId, blocks, actor, queue); 075 case MAIN -> setMain(plotId, blocks, actor, queue); 076 case MIDDLE -> setMiddle(plotId, blocks, queue); 077 case OUTLINE -> setOutline(plotId, blocks, actor, queue); 078 case BORDER -> setWall(plotId, blocks, actor, queue); 079 case ALL -> setAll(plotId, blocks, actor, queue); 080 }).orElse(false); 081 } 082 083 @Override 084 public boolean unClaimPlot(@NonNull Plot plot, @Nullable Runnable whenDone, @Nullable QueueCoordinator queue) { 085 setWallFilling(plot.getId(), classicPlotWorld.WALL_FILLING.toPattern(), null, queue); 086 if (classicPlotWorld.PLACE_TOP_BLOCK && (!classicPlotWorld.WALL_BLOCK.isAir() || !classicPlotWorld.WALL_BLOCK 087 .equals(classicPlotWorld.CLAIMED_WALL_BLOCK))) { 088 setWall(plot.getId(), classicPlotWorld.WALL_BLOCK.toPattern(), null, queue); 089 } 090 TaskManager.runTask(whenDone); 091 return true; 092 } 093 094 /** 095 * Set the plot floor 096 * 097 * @param plotId id of plot to set floor of 098 * @param blocks pattern to set 099 * @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues, 100 * otherwise writes to the queue but does not enqueue. 101 * @return success or not 102 */ 103 public boolean setFloor( 104 @NonNull PlotId plotId, 105 @NonNull Pattern blocks, 106 @Nullable PlotPlayer<?> actor, 107 @Nullable QueueCoordinator queue 108 ) { 109 Plot plot = classicPlotWorld.getPlotAbs(plotId); 110 if (plot != null && plot.isBasePlot()) { 111 return this.regionManager 112 .setCuboids( 113 classicPlotWorld, 114 plot.getRegions(), 115 blocks, 116 classicPlotWorld.PLOT_HEIGHT, 117 classicPlotWorld.PLOT_HEIGHT, 118 actor, 119 queue 120 ); 121 } 122 return false; 123 } 124 125 /** 126 * Sets the plot main, floor and air areas. 127 * 128 * @param plotId id of plot to set all of 129 * @param blocks pattern to set 130 * @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues, 131 * otherwise writes to the queue but does not enqueue. 132 * @return success or not 133 */ 134 public boolean setAll( 135 @NonNull PlotId plotId, 136 @NonNull Pattern blocks, 137 @Nullable PlotPlayer<?> actor, 138 @Nullable QueueCoordinator queue 139 ) { 140 Plot plot = classicPlotWorld.getPlotAbs(plotId); 141 if (plot != null && plot.isBasePlot()) { 142 return this.regionManager.setCuboids( 143 classicPlotWorld, 144 plot.getRegions(), 145 blocks, 146 classicPlotWorld.getMinBuildHeight(), 147 classicPlotWorld.getMaxBuildHeight() - 1, 148 actor, 149 queue 150 ); 151 } 152 return false; 153 } 154 155 /** 156 * Sets the plot air region. 157 * 158 * @param plotId id of plot to set air of 159 * @param blocks pattern to set 160 * @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues, 161 * otherwise writes to the queue but does not enqueue. 162 * @return success or not 163 */ 164 public boolean setAir( 165 @NonNull PlotId plotId, 166 @NonNull Pattern blocks, 167 @Nullable PlotPlayer<?> actor, 168 @Nullable QueueCoordinator queue 169 ) { 170 Plot plot = classicPlotWorld.getPlotAbs(plotId); 171 if (plot != null && plot.isBasePlot()) { 172 return this.regionManager 173 .setCuboids( 174 classicPlotWorld, 175 plot.getRegions(), 176 blocks, 177 classicPlotWorld.PLOT_HEIGHT + 1, 178 classicPlotWorld.getMaxBuildHeight() - 1, 179 actor, 180 queue 181 ); 182 } 183 return false; 184 } 185 186 /** 187 * Sets the plot main blocks. 188 * 189 * @param plotId id of plot to set main of 190 * @param blocks pattern to set 191 * @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues, 192 * otherwise writes to the queue but does not enqueue. 193 * @return success or not 194 */ 195 public boolean setMain( 196 @NonNull PlotId plotId, 197 @NonNull Pattern blocks, 198 @Nullable PlotPlayer<?> actor, 199 @Nullable QueueCoordinator queue 200 ) { 201 Plot plot = classicPlotWorld.getPlotAbs(plotId); 202 if (plot == null || plot.isBasePlot()) { 203 return this.regionManager.setCuboids( 204 classicPlotWorld, 205 plot.getRegions(), 206 blocks, 207 classicPlotWorld.getMinBuildHeight(), 208 classicPlotWorld.PLOT_HEIGHT - 1, 209 actor, 210 queue 211 ); 212 } 213 return false; 214 } 215 216 /** 217 * Set the middle plot block to a Pattern 218 * 219 * @param plotId id of plot to set middle block of 220 * @param blocks pattern to set 221 * @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues, 222 * otherwise writes to the queue but does not enqueue. 223 * @return success or not 224 */ 225 public boolean setMiddle(@NonNull PlotId plotId, @NonNull Pattern blocks, @Nullable QueueCoordinator queue) { 226 Plot plot = classicPlotWorld.getPlotAbs(plotId); 227 if (plot == null || !plot.isBasePlot()) { 228 return false; 229 } 230 Location[] corners = plot.getCorners(); 231 232 boolean enqueue = false; 233 if (queue == null) { 234 queue = classicPlotWorld.getQueue(); 235 enqueue = true; 236 } 237 238 int x = MathMan.average(corners[0].getX(), corners[1].getX()); 239 int z = MathMan.average(corners[0].getZ(), corners[1].getZ()); 240 queue.setBlock(x, classicPlotWorld.PLOT_HEIGHT, z, blocks); 241 return !enqueue || queue.enqueue(); 242 } 243 244 /** 245 * Set a plot's outline 246 * 247 * @param plotId id of plot to set outline of 248 * @param blocks pattern to set 249 * @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues, 250 * otherwise writes to the queue but does not enqueue. 251 * @return success or not 252 */ 253 public boolean setOutline( 254 @NonNull PlotId plotId, 255 @NonNull Pattern blocks, 256 @Nullable PlotPlayer<?> actor, 257 @Nullable QueueCoordinator queue 258 ) { 259 if (classicPlotWorld.ROAD_WIDTH == 0) { 260 return false; 261 } 262 // When using full vanilla generation, don't generate the walls 263 if (classicPlotWorld.getTerrain() == PlotAreaTerrainType.ALL) { 264 // Return true because the method actually did what it's intended to in this case, 265 // which is absolutely nothing 266 return true; 267 } 268 Plot plot = classicPlotWorld.getPlotAbs(plotId); 269 if (plot == null) { 270 return false; 271 } 272 Location bottom = plot.getBottomAbs(); 273 Location top = plot.getExtendedTopAbs(); 274 275 boolean enqueue = false; 276 if (queue == null) { 277 queue = classicPlotWorld.getQueue(); 278 enqueue = true; 279 if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) { 280 queue.addProgressSubscriber(subscriberFactory.createWithActor(actor)); 281 } 282 } 283 284 int maxY = classicPlotWorld.getMaxBuildHeight() - 1; 285 if (!plot.isMerged(Direction.NORTH)) { 286 int z = bottom.getZ(); 287 for (int x = bottom.getX(); x <= top.getX(); x++) { 288 for (int y = classicPlotWorld.PLOT_HEIGHT; y <= maxY; y++) { 289 queue.setBlock(x, y, z, blocks); 290 } 291 } 292 } 293 if (!plot.isMerged(Direction.WEST)) { 294 int x = bottom.getX(); 295 for (int z = bottom.getZ(); z <= top.getZ(); z++) { 296 for (int y = classicPlotWorld.PLOT_HEIGHT; y <= maxY; y++) { 297 queue.setBlock(x, y, z, blocks); 298 } 299 } 300 } 301 302 if (!plot.isMerged(Direction.SOUTH)) { 303 int z = top.getZ(); 304 for (int x = bottom.getX(); x <= top.getX(); x++) { 305 for (int y = classicPlotWorld.PLOT_HEIGHT; y <= maxY; y++) { 306 queue.setBlock(x, y, z, blocks); 307 } 308 } 309 } 310 if (!plot.isMerged(Direction.EAST)) { 311 int x = top.getX(); 312 for (int z = bottom.getZ(); z <= top.getZ(); z++) { 313 for (int y = classicPlotWorld.PLOT_HEIGHT; y <= maxY; y++) { 314 queue.setBlock(x, y, z, blocks); 315 } 316 } 317 } 318 if (plot.isBasePlot()) { 319 for (CuboidRegion region : plot.getRegions()) { 320 Location pos1 = Location.at( 321 classicPlotWorld.getWorldName(), 322 region.getMinimumPoint().getX(), 323 maxY, 324 region.getMinimumPoint().getZ() 325 ); 326 Location pos2 = Location.at( 327 classicPlotWorld.getWorldName(), 328 region.getMaximumPoint().getX(), 329 maxY, 330 region.getMaximumPoint().getZ() 331 ); 332 queue.setCuboid(pos1, pos2, blocks); 333 } 334 } 335 return !enqueue || queue.enqueue(); 336 } 337 338 /** 339 * Set the wall filling for a plot 340 * 341 * @param plotId id of plot to set wall filling of 342 * @param blocks pattern to set 343 * @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues, 344 * otherwise writes to the queue but does not enqueue. 345 * @return success or not 346 */ 347 public boolean setWallFilling( 348 @NonNull PlotId plotId, 349 @NonNull Pattern blocks, 350 @Nullable PlotPlayer<?> actor, 351 @Nullable QueueCoordinator queue 352 ) { 353 if (classicPlotWorld.ROAD_WIDTH == 0) { 354 return false; 355 } 356 // When using full vanilla generation, don't generate the walls 357 if (classicPlotWorld.getTerrain() == PlotAreaTerrainType.ALL) { 358 // Return true because the method actually did what it's intended to in this case, 359 // which is absolutely nothing 360 return true; 361 } 362 Plot plot = classicPlotWorld.getPlotAbs(plotId); 363 if (plot == null) { 364 return false; 365 } 366 Location bot = plot.getExtendedBottomAbs().subtract( 367 plot.isMerged(Direction.WEST) ? 0 : 1, 368 0, 369 plot.isMerged(Direction.NORTH) ? 0 : 1 370 ); 371 Location top = plot.getExtendedTopAbs().add(1, 0, 1); 372 373 boolean enqueue = false; 374 if (queue == null) { 375 queue = classicPlotWorld.getQueue(); 376 enqueue = true; 377 if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) { 378 queue.addProgressSubscriber(subscriberFactory.createWithActor(actor)); 379 } 380 } 381 382 if (!plot.isMerged(Direction.NORTH)) { 383 int z = bot.getZ(); 384 for (int x = bot.getX(); x < top.getX(); x++) { 385 for (int y = classicPlotWorld.getMinBuildHeight(); y <= classicPlotWorld.WALL_HEIGHT; y++) { 386 queue.setBlock(x, y, z, blocks); 387 } 388 } 389 } 390 if (!plot.isMerged(Direction.WEST)) { 391 int x = bot.getX(); 392 for (int z = bot.getZ(); z < top.getZ(); z++) { 393 for (int y = classicPlotWorld.getMinBuildHeight(); y <= classicPlotWorld.WALL_HEIGHT; y++) { 394 queue.setBlock(x, y, z, blocks); 395 } 396 } 397 } 398 if (!plot.isMerged(Direction.SOUTH)) { 399 int z = top.getZ(); 400 for (int x = bot.getX(); x < top.getX() + (plot.isMerged(Direction.EAST) ? 0 : 1); x++) { 401 for (int y = classicPlotWorld.getMinBuildHeight(); y <= classicPlotWorld.WALL_HEIGHT; y++) { 402 queue.setBlock(x, y, z, blocks); 403 } 404 } 405 } 406 if (!plot.isMerged(Direction.EAST)) { 407 int x = top.getX(); 408 for (int z = bot.getZ(); z < top.getZ() + (plot.isMerged(Direction.SOUTH) ? 0 : 1); z++) { 409 for (int y = classicPlotWorld.getMinBuildHeight(); y <= classicPlotWorld.WALL_HEIGHT; y++) { 410 queue.setBlock(x, y, z, blocks); 411 } 412 } 413 } 414 return !enqueue || queue.enqueue(); 415 } 416 417 /** 418 * Set a plot's wall top block only 419 * 420 * @param plotId id of plot to set wall top block of 421 * @param blocks pattern to set 422 * @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues, 423 * otherwise writes to the queue but does not enqueue. 424 * @return success or not 425 */ 426 public boolean setWall( 427 @NonNull PlotId plotId, 428 @NonNull Pattern blocks, 429 @Nullable PlotPlayer<?> actor, 430 @Nullable QueueCoordinator queue 431 ) { 432 if (classicPlotWorld.ROAD_WIDTH == 0) { 433 return false; 434 } 435 // When using full vanilla generation, don't generate the walls 436 if (classicPlotWorld.getTerrain() == PlotAreaTerrainType.ALL) { 437 // Return true because the method actually did what it's intended to in this case, 438 // which is absolutely nothing 439 return true; 440 } 441 Plot plot = classicPlotWorld.getPlotAbs(plotId); 442 if (plot == null) { 443 return false; 444 } 445 Location bot = plot.getExtendedBottomAbs().subtract( 446 plot.isMerged(Direction.WEST) ? 0 : 1, 447 0, 448 plot.isMerged(Direction.NORTH) ? 0 : 1 449 ); 450 Location top = plot.getExtendedTopAbs().add(1, 0, 1); 451 452 boolean enqueue = false; 453 if (queue == null) { 454 enqueue = true; 455 queue = classicPlotWorld.getQueue(); 456 if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) { 457 queue.addProgressSubscriber(subscriberFactory.createWithActor(actor)); 458 } 459 } 460 461 int y = classicPlotWorld.WALL_HEIGHT + 1; 462 if (!plot.isMerged(Direction.NORTH)) { 463 int z = bot.getZ(); 464 for (int x = bot.getX(); x < top.getX(); x++) { 465 queue.setBlock(x, y, z, blocks); 466 } 467 } 468 if (!plot.isMerged(Direction.WEST)) { 469 int x = bot.getX(); 470 for (int z = bot.getZ(); z < top.getZ(); z++) { 471 queue.setBlock(x, y, z, blocks); 472 } 473 } 474 if (!plot.isMerged(Direction.SOUTH)) { 475 int z = top.getZ(); 476 for (int x = bot.getX(); x < top.getX() + (plot.isMerged(Direction.EAST) ? 0 : 1); x++) { 477 queue.setBlock(x, y, z, blocks); 478 } 479 } 480 if (!plot.isMerged(Direction.EAST)) { 481 int x = top.getX(); 482 for (int z = bot.getZ(); z < top.getZ() + (plot.isMerged(Direction.SOUTH) ? 0 : 1); z++) { 483 queue.setBlock(x, y, z, blocks); 484 } 485 } 486 return !enqueue || queue.enqueue(); 487 } 488 489 @Override 490 public boolean createRoadEast(@NonNull Plot plot, @Nullable QueueCoordinator queue) { 491 Location pos1 = getPlotBottomLocAbs(plot.getId()); 492 Location pos2 = getPlotTopLocAbs(plot.getId()); 493 int sx = pos2.getX() + 1; 494 int ex = sx + classicPlotWorld.ROAD_WIDTH - 1; 495 int sz = pos1.getZ() - 2; 496 int ez = pos2.getZ() + 2; 497 498 boolean enqueue = false; 499 if (queue == null) { 500 queue = classicPlotWorld.getQueue(); 501 enqueue = true; 502 } 503 504 int maxY = classicPlotWorld.getMaxGenHeight(); 505 queue.setCuboid( 506 Location.at( 507 classicPlotWorld.getWorldName(), 508 sx, 509 classicPlotWorld.schematicStartHeight() + 1, 510 sz + 1 511 ), 512 Location.at(classicPlotWorld.getWorldName(), ex, maxY, ez - 1), BlockTypes.AIR.getDefaultState() 513 ); 514 if (classicPlotWorld.PLOT_BEDROCK) { 515 queue.setCuboid( 516 Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.getMinGenHeight(), sz + 1), 517 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.getMinGenHeight(), ez - 1), 518 BlockTypes.BEDROCK.getDefaultState() 519 ); 520 } 521 int startYOffset = classicPlotWorld.PLOT_BEDROCK ? 1 : 0; 522 queue.setCuboid( 523 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.getMinGenHeight() + startYOffset, sz + 1), 524 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.WALL_HEIGHT, ez - 1), 525 classicPlotWorld.WALL_FILLING.toPattern() 526 ); 527 queue.setCuboid( 528 Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.getMinGenHeight() + startYOffset, sz + 1), 529 Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.WALL_HEIGHT, ez - 1), 530 classicPlotWorld.WALL_FILLING.toPattern() 531 ); 532 queue.setCuboid( 533 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.getMinGenHeight() + startYOffset, sz + 1), 534 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.ROAD_HEIGHT, ez - 1), 535 classicPlotWorld.ROAD_BLOCK.toPattern() 536 ); 537 538 if (classicPlotWorld.PLACE_TOP_BLOCK) { 539 queue.setCuboid( 540 Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.WALL_HEIGHT + 1, sz + 1), 541 Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.WALL_HEIGHT + 1, ez - 1), 542 classicPlotWorld.WALL_BLOCK.toPattern() 543 ); 544 queue.setCuboid( 545 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.WALL_HEIGHT + 1, sz + 1), 546 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.WALL_HEIGHT + 1, ez - 1), 547 classicPlotWorld.WALL_BLOCK.toPattern() 548 ); 549 } 550 return !enqueue || queue.enqueue(); 551 } 552 553 @Override 554 public boolean createRoadSouth(@NonNull Plot plot, @Nullable QueueCoordinator queue) { 555 Location pos1 = getPlotBottomLocAbs(plot.getId()); 556 Location pos2 = getPlotTopLocAbs(plot.getId()); 557 int sz = pos2.getZ() + 1; 558 int ez = sz + classicPlotWorld.ROAD_WIDTH - 1; 559 int sx = pos1.getX() - 2; 560 int ex = pos2.getX() + 2; 561 562 boolean enqueue = false; 563 if (queue == null) { 564 queue = classicPlotWorld.getQueue(); 565 enqueue = true; 566 } 567 568 queue.setCuboid( 569 Location.at( 570 classicPlotWorld.getWorldName(), 571 sx + 1, 572 classicPlotWorld.schematicStartHeight() + 1, 573 sz 574 ), 575 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.getMaxGenHeight(), ez), 576 BlockTypes.AIR.getDefaultState() 577 ); 578 if (classicPlotWorld.PLOT_BEDROCK) { 579 queue.setCuboid( 580 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.getMinGenHeight(), sz), 581 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.getMinGenHeight(), ez), 582 BlockTypes.BEDROCK.getDefaultState() 583 ); 584 } 585 int startYOffset = classicPlotWorld.PLOT_BEDROCK ? 1 : 0; 586 queue.setCuboid( 587 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.getMinGenHeight() + startYOffset, sz), 588 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT, sz), 589 classicPlotWorld.WALL_FILLING.toPattern() 590 ); 591 queue.setCuboid( 592 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.getMinGenHeight() + startYOffset, ez), 593 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT, ez), 594 classicPlotWorld.WALL_FILLING.toPattern() 595 ); 596 queue.setCuboid( 597 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.getMinGenHeight() + startYOffset, sz + 1), 598 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.ROAD_HEIGHT, ez - 1), 599 classicPlotWorld.ROAD_BLOCK.toPattern() 600 ); 601 602 if (classicPlotWorld.PLACE_TOP_BLOCK) { 603 queue.setCuboid( 604 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.WALL_HEIGHT + 1, sz), 605 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT + 1, sz), 606 classicPlotWorld.WALL_BLOCK.toPattern() 607 ); 608 queue.setCuboid( 609 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.WALL_HEIGHT + 1, ez), 610 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT + 1, ez), 611 classicPlotWorld.WALL_BLOCK.toPattern() 612 ); 613 } 614 return !enqueue || queue.enqueue(); 615 } 616 617 618 @Override 619 public boolean createRoadSouthEast(@NonNull Plot plot, @Nullable QueueCoordinator queue) { 620 Location pos2 = getPlotTopLocAbs(plot.getId()); 621 int sx = pos2.getX() + 1; 622 int ex = sx + classicPlotWorld.ROAD_WIDTH - 1; 623 int sz = pos2.getZ() + 1; 624 int ez = sz + classicPlotWorld.ROAD_WIDTH - 1; 625 626 boolean enqueue = false; 627 if (queue == null) { 628 queue = classicPlotWorld.getQueue(); 629 enqueue = true; 630 } 631 632 queue.setCuboid( 633 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.ROAD_HEIGHT + 1, sz + 1), 634 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.getMaxGenHeight(), ez - 1), 635 BlockTypes.AIR.getDefaultState() 636 ); 637 if (classicPlotWorld.PLOT_BEDROCK) { 638 queue.setCuboid( 639 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.getMinGenHeight(), sz + 1), 640 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.getMinGenHeight(), ez - 1), 641 BlockTypes.BEDROCK.getDefaultState() 642 ); 643 } 644 int startYOffset = classicPlotWorld.PLOT_BEDROCK ? 1 : 0; 645 queue.setCuboid( 646 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.getMinGenHeight() + startYOffset, sz + 1), 647 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.ROAD_HEIGHT, ez - 1), 648 classicPlotWorld.ROAD_BLOCK.toPattern() 649 ); 650 return !enqueue || queue.enqueue(); 651 } 652 653 @Override 654 public boolean removeRoadEast(@NonNull Plot plot, @Nullable QueueCoordinator queue) { 655 Location pos1 = getPlotBottomLocAbs(plot.getId()); 656 Location pos2 = getPlotTopLocAbs(plot.getId()); 657 int sx = pos2.getX() + 1; 658 int ex = sx + classicPlotWorld.ROAD_WIDTH - 1; 659 int sz = pos1.getZ() - 1; 660 int ez = pos2.getZ() + 1; 661 662 boolean enqueue = false; 663 if (queue == null) { 664 queue = classicPlotWorld.getQueue(); 665 enqueue = true; 666 } 667 668 queue 669 .setCuboid( 670 Location.at( 671 classicPlotWorld.getWorldName(), 672 sx, 673 classicPlotWorld.schematicStartHeight() + 1, 674 sz 675 ), 676 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.getMaxGenHeight(), ez), 677 BlockTypes.AIR.getDefaultState() 678 ); 679 int startYOffset = classicPlotWorld.PLOT_BEDROCK ? 1 : 0; 680 queue.setCuboid( 681 Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.getMinGenHeight() + startYOffset, sz + 1), 682 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.PLOT_HEIGHT - 1, ez - 1), 683 classicPlotWorld.MAIN_BLOCK.toPattern() 684 ); 685 queue.setCuboid( 686 Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.PLOT_HEIGHT, sz + 1), 687 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.PLOT_HEIGHT, ez - 1), 688 classicPlotWorld.TOP_BLOCK.toPattern() 689 ); 690 691 return !enqueue || queue.enqueue(); 692 } 693 694 @Override 695 public boolean removeRoadSouth(@NonNull Plot plot, @Nullable QueueCoordinator queue) { 696 Location pos1 = getPlotBottomLocAbs(plot.getId()); 697 Location pos2 = getPlotTopLocAbs(plot.getId()); 698 int sz = pos2.getZ() + 1; 699 int ez = sz + classicPlotWorld.ROAD_WIDTH - 1; 700 int sx = pos1.getX() - 1; 701 int ex = pos2.getX() + 1; 702 703 boolean enqueue = false; 704 if (queue == null) { 705 queue = classicPlotWorld.getQueue(); 706 enqueue = true; 707 } 708 709 queue 710 .setCuboid( 711 Location.at( 712 classicPlotWorld.getWorldName(), 713 sx, 714 classicPlotWorld.schematicStartHeight() + 1, 715 sz 716 ), 717 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.getMaxGenHeight(), ez), 718 BlockTypes.AIR.getDefaultState() 719 ); 720 int startYOffset = classicPlotWorld.PLOT_BEDROCK ? 1 : 0; 721 queue.setCuboid( 722 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.getMinGenHeight() + startYOffset, sz), 723 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.PLOT_HEIGHT - 1, ez), 724 classicPlotWorld.MAIN_BLOCK.toPattern() 725 ); 726 queue.setCuboid( 727 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.PLOT_HEIGHT, sz), 728 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.PLOT_HEIGHT, ez), 729 classicPlotWorld.TOP_BLOCK.toPattern() 730 ); 731 732 return !enqueue || queue.enqueue(); 733 } 734 735 @Override 736 public boolean removeRoadSouthEast(@NonNull Plot plot, @Nullable QueueCoordinator queue) { 737 Location location = getPlotTopLocAbs(plot.getId()); 738 int sx = location.getX() + 1; 739 int ex = sx + classicPlotWorld.ROAD_WIDTH - 1; 740 int sz = location.getZ() + 1; 741 int ez = sz + classicPlotWorld.ROAD_WIDTH - 1; 742 743 boolean enqueue = false; 744 if (queue == null) { 745 queue = classicPlotWorld.getQueue(); 746 enqueue = true; 747 } 748 749 queue 750 .setCuboid( 751 Location.at( 752 classicPlotWorld.getWorldName(), 753 sx, 754 classicPlotWorld.schematicStartHeight() + 1, 755 sz 756 ), 757 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.getMaxGenHeight(), ez), 758 BlockTypes.AIR.getDefaultState() 759 ); 760 int startYOffset = classicPlotWorld.PLOT_BEDROCK ? 1 : 0; 761 queue.setCuboid( 762 Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.getMinGenHeight() + startYOffset, sz), 763 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.PLOT_HEIGHT - 1, ez), 764 classicPlotWorld.MAIN_BLOCK.toPattern() 765 ); 766 queue.setCuboid( 767 Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.PLOT_HEIGHT, sz), 768 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.PLOT_HEIGHT, ez), 769 classicPlotWorld.TOP_BLOCK.toPattern() 770 ); 771 772 return !enqueue || queue.enqueue(); 773 } 774 775 @Override 776 public boolean finishPlotMerge(@NonNull List<PlotId> plotIds, @Nullable QueueCoordinator queue) { 777 final BlockBucket claim = classicPlotWorld.CLAIMED_WALL_BLOCK; 778 if (classicPlotWorld.PLACE_TOP_BLOCK && (!claim.isAir() || !claim.equals(classicPlotWorld.WALL_BLOCK))) { 779 for (PlotId plotId : plotIds) { 780 setWall(plotId, claim.toPattern(), null, queue); 781 } 782 } 783 if (Settings.General.MERGE_REPLACE_WALL) { 784 final BlockBucket wallBlock = classicPlotWorld.WALL_FILLING; 785 for (PlotId id : plotIds) { 786 setWallFilling(id, wallBlock.toPattern(), null, queue); 787 } 788 } 789 return true; 790 } 791 792 @Override 793 public boolean finishPlotUnlink(@NonNull List<PlotId> plotIds, @Nullable QueueCoordinator queue) { 794 final BlockBucket claim = classicPlotWorld.CLAIMED_WALL_BLOCK; 795 if (classicPlotWorld.PLACE_TOP_BLOCK && (!claim.isAir() || !claim.equals(classicPlotWorld.WALL_BLOCK))) { 796 for (PlotId id : plotIds) { 797 setWall(id, claim.toPattern(), null, queue); 798 } 799 } 800 return true; // return false if unlink has been denied 801 } 802 803 @Override 804 public boolean startPlotMerge(@NonNull List<PlotId> plotIds, @Nullable QueueCoordinator queue) { 805 return true; 806 } 807 808 @Override 809 public boolean startPlotUnlink(@NonNull List<PlotId> plotIds, @Nullable QueueCoordinator queue) { 810 return true; 811 } 812 813 @Override 814 public boolean claimPlot(@NonNull Plot plot, @Nullable QueueCoordinator queue) { 815 final BlockBucket claim = classicPlotWorld.CLAIMED_WALL_BLOCK; 816 if (classicPlotWorld.PLACE_TOP_BLOCK && (!claim.isAir() || !claim.equals(classicPlotWorld.WALL_BLOCK))) { 817 return setWall(plot.getId(), claim.toPattern(), null, queue); 818 } 819 return true; 820 } 821 822 @Override 823 public String[] getPlotComponents(@NonNull PlotId plotId) { 824 return ClassicPlotManagerComponent.stringValues(); 825 } 826 827 /** 828 * Retrieves the location of where a sign should be for a plot. 829 * 830 * @param plot The plot 831 * @return The location where a sign should be 832 */ 833 @Override 834 public Location getSignLoc(@NonNull Plot plot) { 835 plot = plot.getBasePlot(false); 836 final Location bot = plot.getBottomAbs(); 837 return Location.at(classicPlotWorld.getWorldName(), bot.getX() - 1, classicPlotWorld.ROAD_HEIGHT + 1, bot.getZ() - 2); 838 } 839 840}