mirror of
				https://github.com/IntellectualSites/PlotSquared.git
				synced 2025-10-22 14:13:44 +02:00 
			
		
		
		
	Compare commits
	
		
			9 Commits
		
	
	
		
			6.9.2
			...
			feature/v6
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 70baca7145 | ||
|   | 2a90015037 | ||
|   | f17aa377b7 | ||
|   | e159fa054d | ||
|   | 058c65e34c | ||
|   | 8608604306 | ||
|   | 8d0cc68721 | ||
|   | 2a79c0a419 | ||
|   | 90d42b8b9f | 
| @@ -25,17 +25,18 @@ | |||||||
|  */ |  */ | ||||||
| package com.plotsquared.bukkit.generator; | package com.plotsquared.bukkit.generator; | ||||||
|  |  | ||||||
| import com.plotsquared.core.PlotSquared; | import com.plotsquared.bukkit.queue.LimitedRegionWrapperQueue; | ||||||
|  | import com.plotsquared.core.generator.HybridPlotWorld; | ||||||
| import com.plotsquared.core.generator.IndependentPlotGenerator; | import com.plotsquared.core.generator.IndependentPlotGenerator; | ||||||
| import com.plotsquared.core.location.ChunkWrapper; | import com.plotsquared.core.location.Location; | ||||||
|  | import com.plotsquared.core.location.UncheckedWorldLocation; | ||||||
| import com.plotsquared.core.plot.PlotArea; | import com.plotsquared.core.plot.PlotArea; | ||||||
| import com.plotsquared.core.plot.world.PlotAreaManager; | import com.plotsquared.core.plot.world.PlotAreaManager; | ||||||
| import com.plotsquared.core.queue.QueueCoordinator; | import com.plotsquared.core.plot.world.SinglePlotArea; | ||||||
| import com.plotsquared.core.queue.ScopedQueueCoordinator; | import com.plotsquared.core.queue.ScopedQueueCoordinator; | ||||||
| import com.sk89q.worldedit.bukkit.BukkitWorld; |  | ||||||
| import org.bukkit.Chunk; |  | ||||||
| import org.bukkit.World; |  | ||||||
| import org.bukkit.generator.BlockPopulator; | import org.bukkit.generator.BlockPopulator; | ||||||
|  | import org.bukkit.generator.LimitedRegion; | ||||||
|  | import org.bukkit.generator.WorldInfo; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
| import java.util.Random; | import java.util.Random; | ||||||
| @@ -43,35 +44,51 @@ import java.util.Random; | |||||||
| final class BlockStatePopulator extends BlockPopulator { | final class BlockStatePopulator extends BlockPopulator { | ||||||
|  |  | ||||||
|     private final IndependentPlotGenerator plotGenerator; |     private final IndependentPlotGenerator plotGenerator; | ||||||
|     private final PlotAreaManager plotAreaManager; |  | ||||||
|  |  | ||||||
|     private QueueCoordinator queue; |     /** | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     public BlockStatePopulator( | ||||||
|  |             final @NonNull IndependentPlotGenerator plotGenerator | ||||||
|  |     ) { | ||||||
|  |         this.plotGenerator = plotGenerator; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @deprecated Use {@link BlockStatePopulator#BlockStatePopulator(IndependentPlotGenerator)} as plotAreManager is unused | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public BlockStatePopulator( |     public BlockStatePopulator( | ||||||
|             final @NonNull IndependentPlotGenerator plotGenerator, |             final @NonNull IndependentPlotGenerator plotGenerator, | ||||||
|             final @NonNull PlotAreaManager plotAreaManager |             final @NonNull PlotAreaManager plotAreaManager | ||||||
|     ) { |     ) { | ||||||
|         this.plotGenerator = plotGenerator; |         this.plotGenerator = plotGenerator; | ||||||
|         this.plotAreaManager = plotAreaManager; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void populate(final @NonNull World world, final @NonNull Random random, final @NonNull Chunk source) { |     public void populate( | ||||||
|         if (this.queue == null) { |             @NonNull final WorldInfo worldInfo, | ||||||
|             this.queue = PlotSquared.platform().globalBlockQueue().getNewQueue(new BukkitWorld(world)); |             @NonNull final Random random, | ||||||
|         } |             final int chunkX, | ||||||
|         final PlotArea area = this.plotAreaManager.getPlotArea(world.getName(), null); |             final int chunkZ, | ||||||
|         if (area == null) { |             @NonNull final LimitedRegion limitedRegion | ||||||
|  |     ) { | ||||||
|  |         PlotArea area = UncheckedWorldLocation.at(worldInfo.getName(), chunkX << 4, 0, chunkZ << 4).getPlotArea(); | ||||||
|  |         if (area == null || (area instanceof HybridPlotWorld hpw && !hpw.populationNeeded()) || area instanceof SinglePlotArea) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         final ChunkWrapper wrap = new ChunkWrapper(area.getWorldName(), source.getX(), source.getZ()); |         LimitedRegionWrapperQueue wrapped = new LimitedRegionWrapperQueue(limitedRegion); | ||||||
|         final ScopedQueueCoordinator chunk = this.queue.getForChunk(wrap.x, wrap.z, |         // It is possible for the region to be larger than the chunk, but there is no reason for P2 to need to populate | ||||||
|                 com.plotsquared.bukkit.util.BukkitWorld.getMinWorldHeight(world), |         // outside of the actual chunk area. | ||||||
|                 com.plotsquared.bukkit.util.BukkitWorld.getMaxWorldHeight(world) - 1 |         Location min = UncheckedWorldLocation.at(worldInfo.getName(), chunkX << 4, worldInfo.getMinHeight(), chunkZ << 4); | ||||||
|  |         Location max = UncheckedWorldLocation.at( | ||||||
|  |                 worldInfo.getName(), | ||||||
|  |                 (chunkX << 4) + 15, | ||||||
|  |                 worldInfo.getMaxHeight(), | ||||||
|  |                 (chunkZ << 4) + 15 | ||||||
|         ); |         ); | ||||||
|         if (this.plotGenerator.populateChunk(chunk, area)) { |         ScopedQueueCoordinator offsetChunkQueue = new ScopedQueueCoordinator(wrapped, min, max); | ||||||
|             this.queue.enqueue(); |         this.plotGenerator.populateChunk(offsetChunkQueue, area); | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -49,8 +49,7 @@ import java.util.List; | |||||||
| import java.util.Random; | import java.util.Random; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
|  |  | ||||||
| public class BukkitPlotGenerator extends ChunkGenerator | public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrapper<ChunkGenerator> { | ||||||
|         implements GeneratorWrapper<ChunkGenerator> { |  | ||||||
|  |  | ||||||
|     @SuppressWarnings("unused") |     @SuppressWarnings("unused") | ||||||
|     public final boolean PAPER_ASYNC_SAFE = true; |     public final boolean PAPER_ASYNC_SAFE = true; | ||||||
| @@ -73,7 +72,12 @@ public class BukkitPlotGenerator extends ChunkGenerator | |||||||
|         this.plotGenerator = generator; |         this.plotGenerator = generator; | ||||||
|         this.platformGenerator = this; |         this.platformGenerator = this; | ||||||
|         this.populators = new ArrayList<>(); |         this.populators = new ArrayList<>(); | ||||||
|         this.populators.add(new BlockStatePopulator(this.plotGenerator, this.plotAreaManager)); |         int minecraftMinorVersion = PlotSquared.platform().serverVersion()[1]; | ||||||
|  |         if (minecraftMinorVersion >= 17) { | ||||||
|  |             this.populators.add(new BlockStatePopulator(this.plotGenerator)); | ||||||
|  |         } else { | ||||||
|  |             this.populators.add(new LegacyBlockStatePopulator(this.plotGenerator)); | ||||||
|  |         } | ||||||
|         this.full = true; |         this.full = true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -159,7 +163,6 @@ public class BukkitPlotGenerator extends ChunkGenerator | |||||||
|             @NonNull World world, @NonNull Random random, int x, int z, |             @NonNull World world, @NonNull Random random, int x, int z, | ||||||
|             @NonNull BiomeGrid biome |             @NonNull BiomeGrid biome | ||||||
|     ) { |     ) { | ||||||
|  |  | ||||||
|         int minY = BukkitWorld.getMinWorldHeight(world); |         int minY = BukkitWorld.getMinWorldHeight(world); | ||||||
|         int maxY = BukkitWorld.getMaxWorldHeight(world); |         int maxY = BukkitWorld.getMaxWorldHeight(world); | ||||||
|         GenChunk result = new GenChunk(minY, maxY); |         GenChunk result = new GenChunk(minY, maxY); | ||||||
|   | |||||||
| @@ -0,0 +1,81 @@ | |||||||
|  | /* | ||||||
|  |  *       _____  _       _    _____                                _ | ||||||
|  |  *      |  __ \| |     | |  / ____|                              | | | ||||||
|  |  *      | |__) | | ___ | |_| (___   __ _ _   _  __ _ _ __ ___  __| | | ||||||
|  |  *      |  ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | | ||||||
|  |  *      | |    | | (_) | |_ ____) | (_| | |_| | (_| | | |  __/ (_| | | ||||||
|  |  *      |_|    |_|\___/ \__|_____/ \__, |\__,_|\__,_|_|  \___|\__,_| | ||||||
|  |  *                                    | | | ||||||
|  |  *                                    |_| | ||||||
|  |  *            PlotSquared plot management system for Minecraft | ||||||
|  |  *               Copyright (C) 2014 - 2022 IntellectualSites | ||||||
|  |  * | ||||||
|  |  *     This program is free software: you can redistribute it and/or modify | ||||||
|  |  *     it under the terms of the GNU General Public License as published by | ||||||
|  |  *     the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  *     (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  *     This program is distributed in the hope that it will be useful, | ||||||
|  |  *     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  *     GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  *     You should have received a copy of the GNU General Public License | ||||||
|  |  *     along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||||
|  |  */ | ||||||
|  | package com.plotsquared.bukkit.generator; | ||||||
|  |  | ||||||
|  | import com.plotsquared.core.PlotSquared; | ||||||
|  | import com.plotsquared.core.generator.HybridPlotWorld; | ||||||
|  | import com.plotsquared.core.generator.IndependentPlotGenerator; | ||||||
|  | import com.plotsquared.core.location.Location; | ||||||
|  | import com.plotsquared.core.location.UncheckedWorldLocation; | ||||||
|  | import com.plotsquared.core.plot.PlotArea; | ||||||
|  | import com.plotsquared.core.plot.world.SinglePlotArea; | ||||||
|  | import com.plotsquared.core.queue.QueueCoordinator; | ||||||
|  | import com.plotsquared.core.queue.ScopedQueueCoordinator; | ||||||
|  | import com.sk89q.worldedit.bukkit.BukkitWorld; | ||||||
|  | import com.sk89q.worldedit.util.SideEffectSet; | ||||||
|  | import org.bukkit.Chunk; | ||||||
|  | import org.bukkit.World; | ||||||
|  | import org.bukkit.generator.BlockPopulator; | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  | import org.jetbrains.annotations.NotNull; | ||||||
|  |  | ||||||
|  | import java.util.Random; | ||||||
|  |  | ||||||
|  | final class LegacyBlockStatePopulator extends BlockPopulator { | ||||||
|  |  | ||||||
|  |     private final IndependentPlotGenerator plotGenerator; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     public LegacyBlockStatePopulator( | ||||||
|  |             final @NonNull IndependentPlotGenerator plotGenerator | ||||||
|  |     ) { | ||||||
|  |         this.plotGenerator = plotGenerator; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void populate(@NotNull final World world, @NotNull final Random random, @NotNull final Chunk source) { | ||||||
|  |         int chunkMinX = source.getX() << 4; | ||||||
|  |         int chunkMinZ = source.getZ() << 4; | ||||||
|  |         PlotArea area = Location.at(world.getName(), chunkMinX, 0, chunkMinZ).getPlotArea(); | ||||||
|  |         if (area == null || (area instanceof HybridPlotWorld hpw && !hpw.populationNeeded()) || area instanceof SinglePlotArea) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         QueueCoordinator queue = PlotSquared.platform().globalBlockQueue().getNewQueue(new BukkitWorld(world)); | ||||||
|  |         queue.setForceSync(true); | ||||||
|  |         queue.setSideEffectSet(SideEffectSet.none()); | ||||||
|  |         queue.setBiomesEnabled(false); | ||||||
|  |         queue.setChunkObject(source); | ||||||
|  |         Location min = UncheckedWorldLocation.at(world.getName(), chunkMinX, world.getMinHeight(), chunkMinZ); | ||||||
|  |         Location max = UncheckedWorldLocation.at(world.getName(), chunkMinX + 15, world.getMaxHeight(), chunkMinZ + 15); | ||||||
|  |         ScopedQueueCoordinator offsetChunkQueue = new ScopedQueueCoordinator(queue, min, max); | ||||||
|  |         this.plotGenerator.populateChunk(offsetChunkQueue, area); | ||||||
|  |         queue.enqueue(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,128 @@ | |||||||
|  | /* | ||||||
|  |  *       _____  _       _    _____                                _ | ||||||
|  |  *      |  __ \| |     | |  / ____|                              | | | ||||||
|  |  *      | |__) | | ___ | |_| (___   __ _ _   _  __ _ _ __ ___  __| | | ||||||
|  |  *      |  ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | | ||||||
|  |  *      | |    | | (_) | |_ ____) | (_| | |_| | (_| | | |  __/ (_| | | ||||||
|  |  *      |_|    |_|\___/ \__|_____/ \__, |\__,_|\__,_|_|  \___|\__,_| | ||||||
|  |  *                                    | | | ||||||
|  |  *                                    |_| | ||||||
|  |  *            PlotSquared plot management system for Minecraft | ||||||
|  |  *               Copyright (C) 2014 - 2022 IntellectualSites | ||||||
|  |  * | ||||||
|  |  *     This program is free software: you can redistribute it and/or modify | ||||||
|  |  *     it under the terms of the GNU General Public License as published by | ||||||
|  |  *     the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  *     (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  *     This program is distributed in the hope that it will be useful, | ||||||
|  |  *     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  *     GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  *     You should have received a copy of the GNU General Public License | ||||||
|  |  *     along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||||
|  |  */ | ||||||
|  | package com.plotsquared.bukkit.queue; | ||||||
|  |  | ||||||
|  | import com.plotsquared.bukkit.schematic.StateWrapper; | ||||||
|  | import com.plotsquared.core.queue.DelegateQueueCoordinator; | ||||||
|  | import com.sk89q.jnbt.CompoundTag; | ||||||
|  | import com.sk89q.worldedit.bukkit.BukkitAdapter; | ||||||
|  | import com.sk89q.worldedit.entity.Entity; | ||||||
|  | import com.sk89q.worldedit.function.pattern.Pattern; | ||||||
|  | import com.sk89q.worldedit.math.BlockVector3; | ||||||
|  | import com.sk89q.worldedit.world.block.BaseBlock; | ||||||
|  | import com.sk89q.worldedit.world.block.BlockState; | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.bukkit.Location; | ||||||
|  | import org.bukkit.entity.EntityType; | ||||||
|  | import org.bukkit.generator.LimitedRegion; | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Wraps a {@link LimitedRegion} inside a {@link com.plotsquared.core.queue.QueueCoordinator} so it can be written to. | ||||||
|  |  * | ||||||
|  |  * @since TODO | ||||||
|  |  */ | ||||||
|  | public class LimitedRegionWrapperQueue extends DelegateQueueCoordinator { | ||||||
|  |  | ||||||
|  |     private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + LimitedRegionWrapperQueue.class.getSimpleName()); | ||||||
|  |  | ||||||
|  |     private final LimitedRegion limitedRegion; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     public LimitedRegionWrapperQueue(LimitedRegion limitedRegion) { | ||||||
|  |         super(null); | ||||||
|  |         this.limitedRegion = limitedRegion; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean setBlock(final int x, final int y, final int z, @NonNull final Pattern pattern) { | ||||||
|  |         return setBlock(x, y, z, pattern.applyBlock(BlockVector3.at(x, y, z))); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean setBlock(final int x, final int y, final int z, @NonNull final BaseBlock id) { | ||||||
|  |         boolean result = setBlock(x, y, z, id.toImmutableState()); | ||||||
|  |         if (result && id.hasNbtData()) { | ||||||
|  |             CompoundTag tag = id.getNbtData(); | ||||||
|  |             StateWrapper sw = new StateWrapper(tag); | ||||||
|  |             try { | ||||||
|  |                 sw.restoreTag(limitedRegion.getBlockState(x, y, z).getBlock()); | ||||||
|  |             } catch (IllegalArgumentException e) { | ||||||
|  |                 LOGGER.error("Error attempting to populate tile entity into the world at location {},{},{}", x, y, z, e); | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean setBlock(final int x, final int y, final int z, @NonNull final BlockState id) { | ||||||
|  |         try { | ||||||
|  |             limitedRegion.setType(x, y, z, BukkitAdapter.adapt(id.getBlockType())); | ||||||
|  |             limitedRegion.setBlockData(x, y, z, BukkitAdapter.adapt(id)); | ||||||
|  |         } catch (IllegalArgumentException e) { | ||||||
|  |             LOGGER.error("Error attempting to populate block into the world at location {},{},{}", x, y, z, e); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean setEntity(@NonNull final Entity entity) { | ||||||
|  |         EntityType type = BukkitAdapter.adapt(entity.getState().getType()); | ||||||
|  |         double x = entity.getLocation().getX(); | ||||||
|  |         double y = entity.getLocation().getY(); | ||||||
|  |         double z = entity.getLocation().getZ(); | ||||||
|  |         Location location = new Location(limitedRegion.getWorld(), x, y, z); | ||||||
|  |         try { | ||||||
|  |             limitedRegion.spawnEntity(location, type); | ||||||
|  |         } catch (IllegalArgumentException e) { | ||||||
|  |             LOGGER.error("Error attempting to populate entity into the world at location {},{},{}", (int) x, (int) y, (int) z, e); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean setTile(final int x, final int y, final int z, @NonNull final CompoundTag tag) { | ||||||
|  |         StateWrapper sw = new StateWrapper(tag); | ||||||
|  |         try { | ||||||
|  |             return sw.restoreTag(limitedRegion.getBlockState(x, y, z).getBlock()); | ||||||
|  |         } catch (IllegalArgumentException e) { | ||||||
|  |             LOGGER.error("Error attempting to populate tile entity into the world at location {},{},{}", x, y, z, e); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean isSettingTiles() { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -35,11 +35,13 @@ import com.sk89q.jnbt.Tag; | |||||||
| import com.sk89q.worldedit.blocks.BaseItemStack; | import com.sk89q.worldedit.blocks.BaseItemStack; | ||||||
| import com.sk89q.worldedit.bukkit.BukkitAdapter; | import com.sk89q.worldedit.bukkit.BukkitAdapter; | ||||||
| import com.sk89q.worldedit.world.item.ItemType; | import com.sk89q.worldedit.world.item.ItemType; | ||||||
|  | import org.bukkit.Bukkit; | ||||||
| import org.bukkit.ChatColor; | import org.bukkit.ChatColor; | ||||||
| import org.bukkit.World; | import org.bukkit.World; | ||||||
| import org.bukkit.block.Block; | import org.bukkit.block.Block; | ||||||
| import org.bukkit.block.Container; | import org.bukkit.block.Container; | ||||||
| import org.bukkit.block.Sign; | import org.bukkit.block.Sign; | ||||||
|  | import org.bukkit.block.Skull; | ||||||
| import org.bukkit.enchantments.Enchantment; | import org.bukkit.enchantments.Enchantment; | ||||||
| import org.bukkit.inventory.Inventory; | import org.bukkit.inventory.Inventory; | ||||||
| import org.bukkit.inventory.InventoryHolder; | import org.bukkit.inventory.InventoryHolder; | ||||||
| @@ -57,6 +59,11 @@ public class StateWrapper { | |||||||
|     public org.bukkit.block.BlockState state = null; |     public org.bukkit.block.BlockState state = null; | ||||||
|     public CompoundTag tag = null; |     public CompoundTag tag = null; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @deprecated in favour of using WE methods for obtaining NBT, specifically by obtaining a | ||||||
|  |      *         {@link com.sk89q.worldedit.world.block.BaseBlock} and then using {@link com.sk89q.worldedit.world.block.BaseBlock#getNbtData()} | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public StateWrapper(org.bukkit.block.BlockState state) { |     public StateWrapper(org.bukkit.block.BlockState state) { | ||||||
|         this.state = state; |         this.state = state; | ||||||
|     } |     } | ||||||
| @@ -230,10 +237,37 @@ public class StateWrapper { | |||||||
|                 } |                 } | ||||||
|                 return false; |                 return false; | ||||||
|             } |             } | ||||||
|  |             case "skull" -> { | ||||||
|  |                 if (state instanceof Skull skull) { | ||||||
|  |                     CompoundTag skullOwner = ((CompoundTag) this.tag.getValue().get("SkullOwner")); | ||||||
|  |                     if (skullOwner == null) { | ||||||
|  |                         return true; | ||||||
|  |                     } | ||||||
|  |                     String player = skullOwner.getString("Name"); | ||||||
|  |                     if (player == null || player.isEmpty()) { | ||||||
|  |                         return false; | ||||||
|  |                     } | ||||||
|  |                     try { | ||||||
|  |                         skull.setOwningPlayer(Bukkit.getOfflinePlayer(player)); | ||||||
|  |                         skull.update(true); | ||||||
|  |                     } catch (Exception e) { | ||||||
|  |                         e.printStackTrace(); | ||||||
|  |                     } | ||||||
|  |                     return true; | ||||||
|  |                 } | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get a CompoundTag of the contents of a block's inventory (chest, furnace, etc.). | ||||||
|  |      * | ||||||
|  |      * @deprecated in favour of using WorldEdit methods for obtaining NBT, specifically by obtaining a | ||||||
|  |      *         {@link com.sk89q.worldedit.world.block.BaseBlock} and then using {@link com.sk89q.worldedit.world.block.BaseBlock#getNbtData()} | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public CompoundTag getTag() { |     public CompoundTag getTag() { | ||||||
|         if (this.tag != null) { |         if (this.tag != null) { | ||||||
|             return this.tag; |             return this.tag; | ||||||
|   | |||||||
| @@ -35,13 +35,23 @@ import com.plotsquared.core.plot.PlotArea; | |||||||
| import com.plotsquared.core.plot.PlotId; | import com.plotsquared.core.plot.PlotId; | ||||||
| import com.plotsquared.core.queue.ScopedQueueCoordinator; | import com.plotsquared.core.queue.ScopedQueueCoordinator; | ||||||
| import com.plotsquared.core.util.MathMan; | import com.plotsquared.core.util.MathMan; | ||||||
|  | import com.sk89q.worldedit.entity.BaseEntity; | ||||||
|  | import com.sk89q.worldedit.entity.Entity; | ||||||
|  | import com.sk89q.worldedit.extent.Extent; | ||||||
|  | import com.sk89q.worldedit.math.BlockVector3; | ||||||
|  | import com.sk89q.worldedit.math.Vector3; | ||||||
|  | import com.sk89q.worldedit.regions.CuboidRegion; | ||||||
|  | import com.sk89q.worldedit.regions.RegionOperationException; | ||||||
|  | import com.sk89q.worldedit.world.NullWorld; | ||||||
| import com.sk89q.worldedit.world.biome.BiomeType; | import com.sk89q.worldedit.world.biome.BiomeType; | ||||||
| import com.sk89q.worldedit.world.block.BaseBlock; | import com.sk89q.worldedit.world.block.BaseBlock; | ||||||
| import com.sk89q.worldedit.world.block.BlockTypes; | import com.sk89q.worldedit.world.block.BlockTypes; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  | import org.checkerframework.checker.nullness.qual.Nullable; | ||||||
|  |  | ||||||
| public class HybridGen extends IndependentPlotGenerator { | public class HybridGen extends IndependentPlotGenerator { | ||||||
|  |  | ||||||
|  |     private static final CuboidRegion CHUNK = new CuboidRegion(BlockVector3.ZERO, BlockVector3.at(15, 396, 15)); | ||||||
|     private final HybridPlotWorldFactory hybridPlotWorldFactory; |     private final HybridPlotWorldFactory hybridPlotWorldFactory; | ||||||
|  |  | ||||||
|     @Inject |     @Inject | ||||||
| @@ -55,12 +65,17 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void placeSchem( |     private void placeSchem( | ||||||
|             HybridPlotWorld world, ScopedQueueCoordinator result, short relativeX, |             HybridPlotWorld world, | ||||||
|             short relativeZ, int x, int z, boolean isRoad |             ScopedQueueCoordinator result, | ||||||
|  |             short relativeX, | ||||||
|  |             short relativeZ, | ||||||
|  |             int x, | ||||||
|  |             int z, | ||||||
|  |             boolean isRoad, | ||||||
|  |             boolean isPopulating | ||||||
|     ) { |     ) { | ||||||
|         int minY; // Math.min(world.PLOT_HEIGHT, world.ROAD_HEIGHT); |         int minY; // Math.min(world.PLOT_HEIGHT, world.ROAD_HEIGHT); | ||||||
|         if ((isRoad && Settings.Schematics.PASTE_ROAD_ON_TOP) || (!isRoad |         if ((isRoad && Settings.Schematics.PASTE_ROAD_ON_TOP) || (!isRoad && Settings.Schematics.PASTE_ON_TOP)) { | ||||||
|                 && Settings.Schematics.PASTE_ON_TOP)) { |  | ||||||
|             minY = world.SCHEM_Y; |             minY = world.SCHEM_Y; | ||||||
|         } else { |         } else { | ||||||
|             minY = world.getMinBuildHeight(); |             minY = world.getMinBuildHeight(); | ||||||
| @@ -69,7 +84,9 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|         if (blocks != null) { |         if (blocks != null) { | ||||||
|             for (int y = 0; y < blocks.length; y++) { |             for (int y = 0; y < blocks.length; y++) { | ||||||
|                 if (blocks[y] != null) { |                 if (blocks[y] != null) { | ||||||
|                     result.setBlock(x, minY + y, z, blocks[y]); |                     if (!isPopulating || blocks[y].hasNbtData()) { | ||||||
|  |                         result.setBlock(x, minY + y, z, blocks[y]); | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @@ -121,42 +138,38 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|         short[] relativeX = new short[16]; |         short[] relativeX = new short[16]; | ||||||
|         boolean[] insideRoadX = new boolean[16]; |         boolean[] insideRoadX = new boolean[16]; | ||||||
|         boolean[] insideWallX = new boolean[16]; |         boolean[] insideWallX = new boolean[16]; | ||||||
|  |         short offsetX = relativeOffsetX; | ||||||
|         for (short i = 0; i < 16; i++) { |         for (short i = 0; i < 16; i++) { | ||||||
|             short v = (short) (relativeOffsetX + i); |             if (offsetX >= hybridPlotWorld.SIZE) { | ||||||
|             while (v >= hybridPlotWorld.SIZE) { |                 offsetX -= hybridPlotWorld.SIZE; | ||||||
|                 v -= hybridPlotWorld.SIZE; |  | ||||||
|             } |             } | ||||||
|             relativeX[i] = v; |             relativeX[i] = offsetX; | ||||||
|             if (hybridPlotWorld.ROAD_WIDTH != 0) { |             if (hybridPlotWorld.ROAD_WIDTH != 0) { | ||||||
|                 insideRoadX[i] = |                 insideRoadX[i] = offsetX < hybridPlotWorld.PATH_WIDTH_LOWER || offsetX > hybridPlotWorld.PATH_WIDTH_UPPER; | ||||||
|                         v < hybridPlotWorld.PATH_WIDTH_LOWER || v > hybridPlotWorld.PATH_WIDTH_UPPER; |                 insideWallX[i] = offsetX == hybridPlotWorld.PATH_WIDTH_LOWER || offsetX == hybridPlotWorld.PATH_WIDTH_UPPER; | ||||||
|                 insideWallX[i] = |  | ||||||
|                         v == hybridPlotWorld.PATH_WIDTH_LOWER || v == hybridPlotWorld.PATH_WIDTH_UPPER; |  | ||||||
|             } |             } | ||||||
|  |             offsetX++; | ||||||
|         } |         } | ||||||
|         // The Z-coordinate of a given Z coordinate, relative to the |         // The Z-coordinate of a given Z coordinate, relative to the | ||||||
|         // plot (Counting from the corner with the least positive |         // plot (Counting from the corner with the least positive | ||||||
|         // coordinates) |         // coordinates) | ||||||
|         short[] relativeZ = new short[16]; |         short[] relativeZ = new short[16]; | ||||||
|         // Whether or not the given Z coordinate belongs to the road |  | ||||||
|         boolean[] insideRoadZ = new boolean[16]; |         boolean[] insideRoadZ = new boolean[16]; | ||||||
|         // Whether or not the given Z coordinate belongs to the wall |  | ||||||
|         boolean[] insideWallZ = new boolean[16]; |         boolean[] insideWallZ = new boolean[16]; | ||||||
|  |         short offsetZ = relativeOffsetZ; | ||||||
|         for (short i = 0; i < 16; i++) { |         for (short i = 0; i < 16; i++) { | ||||||
|             short v = (short) (relativeOffsetZ + i); |             if (offsetZ >= hybridPlotWorld.SIZE) { | ||||||
|             while (v >= hybridPlotWorld.SIZE) { |                 offsetZ -= hybridPlotWorld.SIZE; | ||||||
|                 v -= hybridPlotWorld.SIZE; |  | ||||||
|             } |             } | ||||||
|             relativeZ[i] = v; |             relativeZ[i] = offsetZ; | ||||||
|             if (hybridPlotWorld.ROAD_WIDTH != 0) { |             if (hybridPlotWorld.ROAD_WIDTH != 0) { | ||||||
|                 insideRoadZ[i] = |                 insideRoadZ[i] = offsetZ < hybridPlotWorld.PATH_WIDTH_LOWER || offsetZ > hybridPlotWorld.PATH_WIDTH_UPPER; | ||||||
|                         v < hybridPlotWorld.PATH_WIDTH_LOWER || v > hybridPlotWorld.PATH_WIDTH_UPPER; |                 insideWallZ[i] = offsetZ == hybridPlotWorld.PATH_WIDTH_LOWER || offsetZ == hybridPlotWorld.PATH_WIDTH_UPPER; | ||||||
|                 insideWallZ[i] = |  | ||||||
|                         v == hybridPlotWorld.PATH_WIDTH_LOWER || v == hybridPlotWorld.PATH_WIDTH_UPPER; |  | ||||||
|             } |             } | ||||||
|  |             offsetZ++; | ||||||
|         } |         } | ||||||
|         // generation |         // generation | ||||||
|         int startY = hybridPlotWorld.getMinGenHeight() + (hybridPlotWorld.PLOT_BEDROCK ? 1: 0); |         int startY = hybridPlotWorld.getMinGenHeight() + (hybridPlotWorld.PLOT_BEDROCK ? 1 : 0); | ||||||
|         for (short x = 0; x < 16; x++) { |         for (short x = 0; x < 16; x++) { | ||||||
|             if (insideRoadX[x]) { |             if (insideRoadX[x]) { | ||||||
|                 for (short z = 0; z < 16; z++) { |                 for (short z = 0; z < 16; z++) { | ||||||
| @@ -165,7 +178,7 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                         result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); |                         result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); | ||||||
|                     } |                     } | ||||||
|                     if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |                     if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true); |                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } else if (insideWallX[x]) { |             } else if (insideWallX[x]) { | ||||||
| @@ -176,9 +189,7 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                             result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); |                             result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); | ||||||
|                         } |                         } | ||||||
|                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); | ||||||
|                                     true |  | ||||||
|                             ); |  | ||||||
|                         } |                         } | ||||||
|                     } else { |                     } else { | ||||||
|                         // wall |                         // wall | ||||||
| @@ -187,14 +198,10 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                         } |                         } | ||||||
|                         if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |                         if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|                             if (hybridPlotWorld.PLACE_TOP_BLOCK) { |                             if (hybridPlotWorld.PLACE_TOP_BLOCK) { | ||||||
|                                 result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, |                                 result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, hybridPlotWorld.WALL_BLOCK.toPattern()); | ||||||
|                                         hybridPlotWorld.WALL_BLOCK.toPattern() |  | ||||||
|                                 ); |  | ||||||
|                             } |                             } | ||||||
|                         } else { |                         } else { | ||||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); | ||||||
|                                     true |  | ||||||
|                             ); |  | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| @@ -206,9 +213,7 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                             result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); |                             result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); | ||||||
|                         } |                         } | ||||||
|                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); | ||||||
|                                     true |  | ||||||
|                             ); |  | ||||||
|                         } |                         } | ||||||
|                     } else if (insideWallZ[z]) { |                     } else if (insideWallZ[z]) { | ||||||
|                         // wall |                         // wall | ||||||
| @@ -217,27 +222,19 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                         } |                         } | ||||||
|                         if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |                         if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|                             if (hybridPlotWorld.PLACE_TOP_BLOCK) { |                             if (hybridPlotWorld.PLACE_TOP_BLOCK) { | ||||||
|                                 result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, |                                 result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, hybridPlotWorld.WALL_BLOCK.toPattern()); | ||||||
|                                         hybridPlotWorld.WALL_BLOCK.toPattern() |  | ||||||
|                                 ); |  | ||||||
|                             } |                             } | ||||||
|                         } else { |                         } else { | ||||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); | ||||||
|                                     true |  | ||||||
|                             ); |  | ||||||
|                         } |                         } | ||||||
|                     } else { |                     } else { | ||||||
|                         // plot |                         // plot | ||||||
|                         for (int y = startY; y < hybridPlotWorld.PLOT_HEIGHT; y++) { |                         for (int y = startY; y < hybridPlotWorld.PLOT_HEIGHT; y++) { | ||||||
|                             result.setBlock(x, y, z, hybridPlotWorld.MAIN_BLOCK.toPattern()); |                             result.setBlock(x, y, z, hybridPlotWorld.MAIN_BLOCK.toPattern()); | ||||||
|                         } |                         } | ||||||
|                         result.setBlock(x, hybridPlotWorld.PLOT_HEIGHT, z, |                         result.setBlock(x, hybridPlotWorld.PLOT_HEIGHT, z, hybridPlotWorld.TOP_BLOCK.toPattern()); | ||||||
|                                 hybridPlotWorld.TOP_BLOCK.toPattern() |  | ||||||
|                         ); |  | ||||||
|                         if (hybridPlotWorld.PLOT_SCHEMATIC) { |                         if (hybridPlotWorld.PLOT_SCHEMATIC) { | ||||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, false, false); | ||||||
|                                     false |  | ||||||
|                             ); |  | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| @@ -245,6 +242,138 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean populateChunk(final ScopedQueueCoordinator result, final PlotArea settings) { | ||||||
|  |         HybridPlotWorld hybridPlotWorld = (HybridPlotWorld) settings; | ||||||
|  |         if (!hybridPlotWorld.populationNeeded()) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         // Coords | ||||||
|  |         Location min = result.getMin(); | ||||||
|  |         int bx = min.getX() - hybridPlotWorld.ROAD_OFFSET_X; | ||||||
|  |         int bz = min.getZ() - hybridPlotWorld.ROAD_OFFSET_Z; | ||||||
|  |         // The relative X-coordinate (within the plot) of the minimum X coordinate | ||||||
|  |         // contained in the scoped queue | ||||||
|  |         short relativeOffsetX; | ||||||
|  |         if (bx < 0) { | ||||||
|  |             relativeOffsetX = (short) (hybridPlotWorld.SIZE + (bx % hybridPlotWorld.SIZE)); | ||||||
|  |         } else { | ||||||
|  |             relativeOffsetX = (short) (bx % hybridPlotWorld.SIZE); | ||||||
|  |         } | ||||||
|  |         // The relative Z-coordinate (within the plot) of the minimum Z coordinate | ||||||
|  |         // contained in the scoped queue | ||||||
|  |         short relativeOffsetZ; | ||||||
|  |         if (bz < 0) { | ||||||
|  |             relativeOffsetZ = (short) (hybridPlotWorld.SIZE + (bz % hybridPlotWorld.SIZE)); | ||||||
|  |         } else { | ||||||
|  |             relativeOffsetZ = (short) (bz % hybridPlotWorld.SIZE); | ||||||
|  |         } | ||||||
|  |         boolean allRoad = true; | ||||||
|  |         boolean overlap = false; | ||||||
|  |  | ||||||
|  |         // The X-coordinate of a given X coordinate, relative to the | ||||||
|  |         // plot (Counting from the corner with the least positive | ||||||
|  |         // coordinates) | ||||||
|  |         short[] relativeX = new short[16]; | ||||||
|  |         boolean[] insideRoadX = new boolean[16]; | ||||||
|  |         boolean[] insideWallX = new boolean[16]; | ||||||
|  |         short offsetX = relativeOffsetX; | ||||||
|  |         for (short i = 0; i < 16; i++) { | ||||||
|  |             if (offsetX >= hybridPlotWorld.SIZE) { | ||||||
|  |                 offsetX -= hybridPlotWorld.SIZE; | ||||||
|  |                 overlap = true; | ||||||
|  |             } | ||||||
|  |             relativeX[i] = offsetX; | ||||||
|  |             if (hybridPlotWorld.ROAD_WIDTH != 0) { | ||||||
|  |                 boolean insideRoad = offsetX < hybridPlotWorld.PATH_WIDTH_LOWER || offsetX > hybridPlotWorld.PATH_WIDTH_UPPER; | ||||||
|  |                 boolean insideWall = offsetX == hybridPlotWorld.PATH_WIDTH_LOWER || offsetX == hybridPlotWorld.PATH_WIDTH_UPPER; | ||||||
|  |                 insideRoadX[i] = insideRoad; | ||||||
|  |                 insideWallX[i] = insideWall; | ||||||
|  |                 allRoad &= insideRoad && insideWall; | ||||||
|  |             } | ||||||
|  |             offsetX++; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // The Z-coordinate of a given Z coordinate, relative to the | ||||||
|  |         // plot (Counting from the corner with the least positive | ||||||
|  |         // coordinates) | ||||||
|  |         short[] relativeZ = new short[16]; | ||||||
|  |         boolean[] insideRoadZ = new boolean[16]; | ||||||
|  |         boolean[] insideWallZ = new boolean[16]; | ||||||
|  |         short offsetZ = relativeOffsetZ; | ||||||
|  |         for (short i = 0; i < 16; i++) { | ||||||
|  |             if (offsetZ >= hybridPlotWorld.SIZE) { | ||||||
|  |                 offsetZ -= hybridPlotWorld.SIZE; | ||||||
|  |                 overlap = true; | ||||||
|  |             } | ||||||
|  |             relativeZ[i] = offsetZ; | ||||||
|  |             if (hybridPlotWorld.ROAD_WIDTH != 0) { | ||||||
|  |                 boolean insideRoad = offsetZ < hybridPlotWorld.PATH_WIDTH_LOWER || offsetZ > hybridPlotWorld.PATH_WIDTH_UPPER; | ||||||
|  |                 boolean insideWall = offsetZ == hybridPlotWorld.PATH_WIDTH_LOWER || offsetZ == hybridPlotWorld.PATH_WIDTH_UPPER; | ||||||
|  |                 insideRoadZ[i] = insideRoad; | ||||||
|  |                 insideWallZ[i] = insideWall; | ||||||
|  |                 allRoad &= insideRoad && insideWall; | ||||||
|  |             } | ||||||
|  |             offsetZ++; | ||||||
|  |         } | ||||||
|  |         for (short x = 0; x < 16; x++) { | ||||||
|  |             if (insideRoadX[x] || insideWallX[x]) { | ||||||
|  |                 if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|  |                     for (short z = 0; z < 16; z++) { | ||||||
|  |                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, true); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 for (short z = 0; z < 16; z++) { | ||||||
|  |                     if (insideRoadZ[z] || insideWallZ[z]) { | ||||||
|  |                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|  |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, true); | ||||||
|  |                         } | ||||||
|  |                     } else if (hybridPlotWorld.PLOT_SCHEMATIC) { | ||||||
|  |                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, false, true); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         if (!allRoad && hybridPlotWorld.getPlotSchematicEntities() != null && !hybridPlotWorld | ||||||
|  |                 .getPlotSchematicEntities() | ||||||
|  |                 .isEmpty()) { | ||||||
|  |             CuboidRegion region = CHUNK.clone(); | ||||||
|  |             try { | ||||||
|  |                 region.shift(hybridPlotWorld | ||||||
|  |                         .getPlotSchematicMinPoint() | ||||||
|  |                         .add(relativeOffsetX, 0, relativeOffsetZ) | ||||||
|  |                         .subtract(hybridPlotWorld.PATH_WIDTH_LOWER + 1, 0, hybridPlotWorld.PATH_WIDTH_LOWER + 1)); | ||||||
|  |                 for (Entity entity : hybridPlotWorld.getPlotSchematicEntities()) { | ||||||
|  |                     if (region.contains(entity.getLocation().toVector().toBlockPoint())) { | ||||||
|  |                         Vector3 pos = (entity.getLocation().toVector() | ||||||
|  |                                 .subtract(region.getMinimumPoint().withY(hybridPlotWorld.getPlotSchematicMinPoint().getY()).toVector3())) | ||||||
|  |                                 .add(min.getBlockVector3().withY(hybridPlotWorld.SCHEM_Y).toVector3()); | ||||||
|  |                         result.setEntity(new PopulatingEntity( | ||||||
|  |                                 entity, | ||||||
|  |                                 new com.sk89q.worldedit.util.Location(NullWorld.getInstance(), pos) | ||||||
|  |                         )); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } catch (RegionOperationException e) { | ||||||
|  |                 throw new RuntimeException(e); | ||||||
|  |             } | ||||||
|  |             if (overlap) { | ||||||
|  |                 try { | ||||||
|  |                     region.shift(BlockVector3.at(-hybridPlotWorld.SIZE, 0, -hybridPlotWorld.SIZE)); | ||||||
|  |                     for (Entity entity : hybridPlotWorld.getPlotSchematicEntities()) { | ||||||
|  |                         if (region.contains(entity.getLocation().toVector().toBlockPoint())) { | ||||||
|  |                             result.setEntity(entity); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } catch (RegionOperationException e) { | ||||||
|  |                     throw new RuntimeException(e); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public PlotArea getNewPlotArea(String world, String id, PlotId min, PlotId max) { |     public PlotArea getNewPlotArea(String world, String id, PlotId min, PlotId max) { | ||||||
|         return this.hybridPlotWorldFactory.create(world, id, this, min, max); |         return this.hybridPlotWorldFactory.create(world, id, this, min, max); | ||||||
| @@ -255,4 +384,58 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|         // All initialization is done in the PlotArea class |         // All initialization is done in the PlotArea class | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Wrapper to allow a WorldEdit {@link Entity} to effectively have a mutable location as the location in its NBT should be changed | ||||||
|  |      * when set to the world. | ||||||
|  |      * | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     private static final class PopulatingEntity implements Entity { | ||||||
|  |  | ||||||
|  |         private final Entity parent; | ||||||
|  |         private com.sk89q.worldedit.util.Location location; | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |          * @since TODO | ||||||
|  |          */ | ||||||
|  |         private PopulatingEntity(Entity parent, com.sk89q.worldedit.util.Location location) { | ||||||
|  |             this.parent = parent; | ||||||
|  |             this.location = location; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Nullable | ||||||
|  |         @Override | ||||||
|  |         public BaseEntity getState() { | ||||||
|  |             return parent.getState(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public boolean remove() { | ||||||
|  |             return parent.remove(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public com.sk89q.worldedit.util.Location getLocation() { | ||||||
|  |             return location; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public boolean setLocation(final com.sk89q.worldedit.util.Location location) { | ||||||
|  |             this.location = location; | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public Extent getExtent() { | ||||||
|  |             return parent.getExtent(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Nullable | ||||||
|  |         @Override | ||||||
|  |         public <T> T getFacet(final Class<? extends T> cls) { | ||||||
|  |             return parent.getFacet(cls); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -40,11 +40,13 @@ import com.plotsquared.core.plot.PlotId; | |||||||
| import com.plotsquared.core.plot.PlotManager; | import com.plotsquared.core.plot.PlotManager; | ||||||
| import com.plotsquared.core.plot.schematic.Schematic; | import com.plotsquared.core.plot.schematic.Schematic; | ||||||
| import com.plotsquared.core.queue.GlobalBlockQueue; | import com.plotsquared.core.queue.GlobalBlockQueue; | ||||||
|  | import com.plotsquared.core.util.AnnotationHelper; | ||||||
| import com.plotsquared.core.util.FileUtils; | import com.plotsquared.core.util.FileUtils; | ||||||
| import com.plotsquared.core.util.MathMan; | import com.plotsquared.core.util.MathMan; | ||||||
| import com.plotsquared.core.util.SchematicHandler; | import com.plotsquared.core.util.SchematicHandler; | ||||||
| import com.sk89q.jnbt.CompoundTag; | import com.sk89q.jnbt.CompoundTag; | ||||||
| import com.sk89q.jnbt.CompoundTagBuilder; | import com.sk89q.jnbt.CompoundTagBuilder; | ||||||
|  | import com.sk89q.worldedit.entity.Entity; | ||||||
| import com.sk89q.worldedit.extent.clipboard.Clipboard; | import com.sk89q.worldedit.extent.clipboard.Clipboard; | ||||||
| import com.sk89q.worldedit.extent.transform.BlockTransformExtent; | import com.sk89q.worldedit.extent.transform.BlockTransformExtent; | ||||||
| import com.sk89q.worldedit.internal.helper.MCDirections; | import com.sk89q.worldedit.internal.helper.MCDirections; | ||||||
| @@ -58,11 +60,13 @@ import com.sk89q.worldedit.world.block.BaseBlock; | |||||||
| import org.apache.logging.log4j.LogManager; | import org.apache.logging.log4j.LogManager; | ||||||
| import org.apache.logging.log4j.Logger; | import org.apache.logging.log4j.Logger; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  | import org.checkerframework.checker.nullness.qual.Nullable; | ||||||
|  |  | ||||||
| import javax.annotation.Nullable; |  | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.lang.reflect.Field; | import java.lang.reflect.Field; | ||||||
|  | import java.util.ArrayList; | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
|  | import java.util.List; | ||||||
| import java.util.Locale; | import java.util.Locale; | ||||||
|  |  | ||||||
| public class HybridPlotWorld extends ClassicPlotWorld { | public class HybridPlotWorld extends ClassicPlotWorld { | ||||||
| @@ -71,6 +75,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|     private static final AffineTransform transform = new AffineTransform().rotateY(90); |     private static final AffineTransform transform = new AffineTransform().rotateY(90); | ||||||
|     public boolean ROAD_SCHEMATIC_ENABLED; |     public boolean ROAD_SCHEMATIC_ENABLED; | ||||||
|     public boolean PLOT_SCHEMATIC = false; |     public boolean PLOT_SCHEMATIC = false; | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public int PLOT_SCHEMATIC_HEIGHT = -1; |     public int PLOT_SCHEMATIC_HEIGHT = -1; | ||||||
|     public short PATH_WIDTH_LOWER; |     public short PATH_WIDTH_LOWER; | ||||||
|     public short PATH_WIDTH_UPPER; |     public short PATH_WIDTH_UPPER; | ||||||
| @@ -80,6 +85,11 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|     private Location SIGN_LOCATION; |     private Location SIGN_LOCATION; | ||||||
|     private File root = null; |     private File root = null; | ||||||
|     private int lastOverlayHeightError = Integer.MIN_VALUE; |     private int lastOverlayHeightError = Integer.MIN_VALUE; | ||||||
|  |     private List<Entity> schem3Entities = null; | ||||||
|  |     private BlockVector3 schem3MinPoint = null; | ||||||
|  |     private boolean schem1PopulationNeeded = false; | ||||||
|  |     private boolean schem2PopulationNeeded = false; | ||||||
|  |     private boolean schem3PopulationNeeded = false; | ||||||
|  |  | ||||||
|     @Inject |     @Inject | ||||||
|     private SchematicHandler schematicHandler; |     private SchematicHandler schematicHandler; | ||||||
| @@ -98,6 +108,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|         PlotSquared.platform().injector().injectMembers(this); |         PlotSquared.platform().injector().injectMembers(this); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public static byte wrap(byte data, int start) { |     public static byte wrap(byte data, int start) { | ||||||
|         if ((data >= start) && (data < (start + 4))) { |         if ((data >= start) && (data < (start + 4))) { | ||||||
|             data = (byte) ((((data - start) + 2) & 3) + start); |             data = (byte) ((((data - start) + 2) & 3) + start); | ||||||
| @@ -105,6 +116,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|         return data; |         return data; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public static byte wrap2(byte data, int start) { |     public static byte wrap2(byte data, int start) { | ||||||
|         if ((data >= start) && (data < (start + 2))) { |         if ((data >= start) && (data < (start + 2))) { | ||||||
|             data = (byte) ((((data - start) + 1) & 1) + start); |             data = (byte) ((((data - start) + 1) & 1) + start); | ||||||
| @@ -112,8 +124,6 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|         return data; |         return data; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // FIXME depends on block ids |  | ||||||
|     // Possibly make abstract? |  | ||||||
|     public static BaseBlock rotate(BaseBlock id) { |     public static BaseBlock rotate(BaseBlock id) { | ||||||
|  |  | ||||||
|         CompoundTag tag = id.getNbtData(); |         CompoundTag tag = id.getNbtData(); | ||||||
| @@ -251,6 +261,14 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|         Schematic schematic1 = this.schematicHandler.getSchematic(schematic1File); |         Schematic schematic1 = this.schematicHandler.getSchematic(schematic1File); | ||||||
|         Schematic schematic2 = this.schematicHandler.getSchematic(schematic2File); |         Schematic schematic2 = this.schematicHandler.getSchematic(schematic2File); | ||||||
|         Schematic schematic3 = this.schematicHandler.getSchematic(schematic3File); |         Schematic schematic3 = this.schematicHandler.getSchematic(schematic3File); | ||||||
|  |  | ||||||
|  |         // If the plot schematic contains entities, then they need to be populated upon generation. | ||||||
|  |         if (schematic3 != null && !schematic3.getClipboard().getEntities().isEmpty()) { | ||||||
|  |             this.schem3Entities = new ArrayList<>(schematic3.getClipboard().getEntities()); | ||||||
|  |             this.schem3MinPoint = schematic3.getClipboard().getMinimumPoint(); | ||||||
|  |             this.schem3PopulationNeeded = true; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         int shift = this.ROAD_WIDTH / 2; |         int shift = this.ROAD_WIDTH / 2; | ||||||
|         int oddshift = (this.ROAD_WIDTH & 1); |         int oddshift = (this.ROAD_WIDTH & 1); | ||||||
|  |  | ||||||
| @@ -314,24 +332,34 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|             for (short x = 0; x < w3; x++) { |             for (short x = 0; x < w3; x++) { | ||||||
|                 for (short z = 0; z < l3; z++) { |                 for (short z = 0; z < l3; z++) { | ||||||
|                     for (short y = 0; y < h3; y++) { |                     for (short y = 0; y < h3; y++) { | ||||||
|                         BaseBlock id = |                         BaseBlock id = blockArrayClipboard3.getFullBlock(BlockVector3.at( | ||||||
|                                 blockArrayClipboard3.getFullBlock(BlockVector3.at( |                                 x + min.getBlockX(), | ||||||
|                                         x + min.getBlockX(), |                                 y + min.getBlockY(), | ||||||
|                                         y + min.getBlockY(), |                                 z + min.getBlockZ() | ||||||
|                                         z + min.getBlockZ() |                         )); | ||||||
|                                 )); |  | ||||||
|                         if (!id.getBlockType().getMaterial().isAir()) { |                         if (!id.getBlockType().getMaterial().isAir()) { | ||||||
|                             addOverlayBlock((short) (x + shift + oddshift + centerShiftX), (short) (y + plotY), |                             schem3PopulationNeeded |= id.hasNbtData(); | ||||||
|                                     (short) (z + shift + oddshift + centerShiftZ), id, false, h3 |                             addOverlayBlock( | ||||||
|  |                                     (short) (x + shift + oddshift + centerShiftX), | ||||||
|  |                                     (short) (y + plotY), | ||||||
|  |                                     (short) (z + shift + oddshift + centerShiftZ), | ||||||
|  |                                     id, | ||||||
|  |                                     false, | ||||||
|  |                                     h3 | ||||||
|                             ); |                             ); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                     BiomeType biome = blockArrayClipboard3.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); |                     if (blockArrayClipboard3.hasBiomes()) { | ||||||
|                     addOverlayBiome( |                         BiomeType biome = blockArrayClipboard3.getBiome(BlockVector2.at( | ||||||
|                             (short) (x + shift + oddshift + centerShiftX), |                                 x + min.getBlockX(), | ||||||
|                             (short) (z + shift + oddshift + centerShiftZ), |                                 z + min.getBlockZ() | ||||||
|                             biome |                         )); | ||||||
|                     ); |                         addOverlayBiome( | ||||||
|  |                                 (short) (x + shift + oddshift + centerShiftX), | ||||||
|  |                                 (short) (z + shift + oddshift + centerShiftZ), | ||||||
|  |                                 biome | ||||||
|  |                         ); | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -339,7 +367,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|                 LOGGER.info("- plot schematic: {}", schematic3File.getPath()); |                 LOGGER.info("- plot schematic: {}", schematic3File.getPath()); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         if ((schematic1 == null&& schematic2 == null) || this.ROAD_WIDTH == 0) { |         if ((schematic1 == null && schematic2 == null) || this.ROAD_WIDTH == 0) { | ||||||
|             if (Settings.DEBUG) { |             if (Settings.DEBUG) { | ||||||
|                 LOGGER.info("- schematic: false"); |                 LOGGER.info("- schematic: false"); | ||||||
|             } |             } | ||||||
| @@ -370,6 +398,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|                             z + min.getBlockZ() |                             z + min.getBlockZ() | ||||||
|                     )); |                     )); | ||||||
|                     if (!id.getBlockType().getMaterial().isAir()) { |                     if (!id.getBlockType().getMaterial().isAir()) { | ||||||
|  |                         schem1PopulationNeeded |= id.hasNbtData(); | ||||||
|                         addOverlayBlock((short) (x - shift), (short) (y + roadY), (short) (z + shift + oddshift), id, false, h1); |                         addOverlayBlock((short) (x - shift), (short) (y + roadY), (short) (z + shift + oddshift), id, false, h1); | ||||||
|                         addOverlayBlock( |                         addOverlayBlock( | ||||||
|                                 (short) (z + shift + oddshift), |                                 (short) (z + shift + oddshift), | ||||||
| @@ -381,9 +410,11 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|                         ); |                         ); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 BiomeType biome = blockArrayClipboard1.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); |                 if (blockArrayClipboard1.hasBiomes()) { | ||||||
|                 addOverlayBiome((short) (x - shift), (short) (z + shift + oddshift), biome); |                     BiomeType biome = blockArrayClipboard1.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); | ||||||
|                 addOverlayBiome((short) (z + shift + oddshift), (short) (shift - x + (oddshift - 1)), biome); |                     addOverlayBiome((short) (x - shift), (short) (z + shift + oddshift), biome); | ||||||
|  |                     addOverlayBiome((short) (z + shift + oddshift), (short) (shift - x + (oddshift - 1)), biome); | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -406,11 +437,14 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|                             z + min.getBlockZ() |                             z + min.getBlockZ() | ||||||
|                     )); |                     )); | ||||||
|                     if (!id.getBlockType().getMaterial().isAir()) { |                     if (!id.getBlockType().getMaterial().isAir()) { | ||||||
|  |                         schem2PopulationNeeded |= id.hasNbtData(); | ||||||
|                         addOverlayBlock((short) (x - shift), (short) (y + roadY), (short) (z - shift), id, false, h2); |                         addOverlayBlock((short) (x - shift), (short) (y + roadY), (short) (z - shift), id, false, h2); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 BiomeType biome = blockArrayClipboard2.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); |                 if (blockArrayClipboard2.hasBiomes()) { | ||||||
|                 addOverlayBiome((short) (x - shift), (short) (z - shift), biome); |                     BiomeType biome = blockArrayClipboard2.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); | ||||||
|  |                     addOverlayBiome((short) (x - shift), (short) (z - shift), biome); | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -456,8 +490,52 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|         this.G_SCH_B.put(pair, id); |         this.G_SCH_B.put(pair, id); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the entities contained within the plot schematic for generation. Intended for internal use only. | ||||||
|  |      * | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||||
|  |     public @Nullable List<Entity> getPlotSchematicEntities() { | ||||||
|  |         return schem3Entities; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the minimum point of the plot schematic for generation. Intended for internal use only. | ||||||
|  |      * | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||||
|  |     public @Nullable BlockVector3 getPlotSchematicMinPoint() { | ||||||
|  |         return schem3MinPoint; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get if post-generation population of chunks with tiles/entities is needed for this world. Not for public API use. | ||||||
|  |      * | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||||
|  |     public boolean populationNeeded() { | ||||||
|  |         return schem1PopulationNeeded || schem2PopulationNeeded || schem3PopulationNeeded; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @deprecated in favour of {@link HybridPlotWorld#getSchematicRoot()} | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public File getRoot() { |     public File getRoot() { | ||||||
|         return this.root; |         return this.root; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the root folder for this world's generation schematics. May be null if schematics not initialised via | ||||||
|  |      * {@link HybridPlotWorld#setupSchematics()} | ||||||
|  |      * | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     public @Nullable File getSchematicRoot() { | ||||||
|  |         return this.root; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -47,9 +47,7 @@ public abstract class IndependentPlotGenerator { | |||||||
|     public abstract String getName(); |     public abstract String getName(); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Use the setBlock or setBiome method of the PlotChunk result parameter to make changes. |      * Generate chunk block data | ||||||
|      * The PlotArea settings is the same one this was initialized with. |  | ||||||
|      * The PseudoRandom random is a fast random object. |  | ||||||
|      * |      * | ||||||
|      * @param result   queue |      * @param result   queue | ||||||
|      * @param settings PlotArea (settings) |      * @param settings PlotArea (settings) | ||||||
| @@ -59,10 +57,15 @@ public abstract class IndependentPlotGenerator { | |||||||
|     public abstract void generateChunk(ScopedQueueCoordinator result, PlotArea settings); |     public abstract void generateChunk(ScopedQueueCoordinator result, PlotArea settings); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Populates the queue representing a chunk area with tile entities and entities | ||||||
|  |      * | ||||||
|  |      * @param result   Queue to write to | ||||||
|  |      * @param settings PlotArea (settings) | ||||||
|  |      * @return True if any population occurred | ||||||
|      * @deprecated {@link ScopedQueueCoordinator} will be renamed in v7. |      * @deprecated {@link ScopedQueueCoordinator} will be renamed in v7. | ||||||
|      */ |      */ | ||||||
|     @Deprecated(forRemoval = true, since = "TODO") |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public boolean populateChunk(ScopedQueueCoordinator result, PlotArea setting) { |     public boolean populateChunk(ScopedQueueCoordinator result, PlotArea settings) { | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -41,14 +41,17 @@ import org.khelekore.prtree.SimpleMBR; | |||||||
|  * An unmodifiable 6-tuple (world,x,y,z,yaw,pitch) |  * An unmodifiable 6-tuple (world,x,y,z,yaw,pitch) | ||||||
|  */ |  */ | ||||||
| @SuppressWarnings("unused") | @SuppressWarnings("unused") | ||||||
| public final class Location extends BlockLoc implements Comparable<Location> { | public sealed class Location extends BlockLoc implements Comparable<Location> permits UncheckedWorldLocation { | ||||||
|  |  | ||||||
|     private final float yaw; |     private final float yaw; | ||||||
|     private final float pitch; |     private final float pitch; | ||||||
|     private final BlockVector3 blockVector3; |     private final BlockVector3 blockVector3; | ||||||
|     private final World<?> world; |     private final World<?> world; | ||||||
|  |  | ||||||
|     private Location( |     /** | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     protected Location( | ||||||
|             final @NonNull World<?> world, final @NonNull BlockVector3 blockVector3, |             final @NonNull World<?> world, final @NonNull BlockVector3 blockVector3, | ||||||
|             final float yaw, final float pitch |             final float yaw, final float pitch | ||||||
|     ) { |     ) { | ||||||
|   | |||||||
| @@ -0,0 +1,77 @@ | |||||||
|  | /* | ||||||
|  |  *       _____  _       _    _____                                _ | ||||||
|  |  *      |  __ \| |     | |  / ____|                              | | | ||||||
|  |  *      | |__) | | ___ | |_| (___   __ _ _   _  __ _ _ __ ___  __| | | ||||||
|  |  *      |  ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | | ||||||
|  |  *      | |    | | (_) | |_ ____) | (_| | |_| | (_| | | |  __/ (_| | | ||||||
|  |  *      |_|    |_|\___/ \__|_____/ \__, |\__,_|\__,_|_|  \___|\__,_| | ||||||
|  |  *                                    | | | ||||||
|  |  *                                    |_| | ||||||
|  |  *            PlotSquared plot management system for Minecraft | ||||||
|  |  *               Copyright (C) 2014 - 2022 IntellectualSites | ||||||
|  |  * | ||||||
|  |  *     This program is free software: you can redistribute it and/or modify | ||||||
|  |  *     it under the terms of the GNU General Public License as published by | ||||||
|  |  *     the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  *     (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  *     This program is distributed in the hope that it will be useful, | ||||||
|  |  *     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  *     GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  *     You should have received a copy of the GNU General Public License | ||||||
|  |  *     along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||||
|  |  */ | ||||||
|  | package com.plotsquared.core.location; | ||||||
|  |  | ||||||
|  | import com.plotsquared.core.util.AnnotationHelper; | ||||||
|  | import com.sk89q.worldedit.math.BlockVector3; | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Used internally for generation to reference locations in worlds that "don't exist yet". There is no guarantee that the world | ||||||
|  |  * name provided by {@link UncheckedWorldLocation#getWorldName()} exists on the server. | ||||||
|  |  * | ||||||
|  |  * @since TODO | ||||||
|  |  */ | ||||||
|  | @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||||
|  | public final class UncheckedWorldLocation extends Location { | ||||||
|  |  | ||||||
|  |     private final String worldName; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     private UncheckedWorldLocation( | ||||||
|  |             final @NonNull String worldName, final int x, final int y, final int z | ||||||
|  |     ) { | ||||||
|  |         super(World.nullWorld(), BlockVector3.at(x, y, z), 0f, 0f); | ||||||
|  |         this.worldName = worldName; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Construct a new location with yaw and pitch equal to 0 | ||||||
|  |      * | ||||||
|  |      * @param world World | ||||||
|  |      * @param x     X coordinate | ||||||
|  |      * @param y     Y coordinate | ||||||
|  |      * @param z     Z coordinate | ||||||
|  |      * @return New location | ||||||
|  |      * | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||||
|  |     public static @NonNull UncheckedWorldLocation at( | ||||||
|  |             final @NonNull String world, final int x, final int y, final int z | ||||||
|  |     ) { | ||||||
|  |         return new UncheckedWorldLocation(world, x, y, z); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||||
|  |     public @NonNull String getWorldName() { | ||||||
|  |         return this.worldName; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user