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.queue; 020 021import com.intellectualsites.annotations.DoNotUse; 022import com.plotsquared.core.location.Location; 023import com.sk89q.jnbt.CompoundTag; 024import com.sk89q.worldedit.function.pattern.Pattern; 025import com.sk89q.worldedit.math.BlockVector3; 026import com.sk89q.worldedit.world.biome.BiomeType; 027import com.sk89q.worldedit.world.block.BaseBlock; 028import com.sk89q.worldedit.world.block.BlockState; 029import org.checkerframework.checker.nullness.qual.NonNull; 030import org.checkerframework.checker.nullness.qual.Nullable; 031 032/** 033 * {@link QueueCoordinator} that caches all blocks set to it in a given array of form BlockState[][][]. An offset can be 034 * applied to blocks set to it, and the scope limited. This should have blocks set to it one chunk at a time, based on the 035 * result of {@link BlockArrayCacheScopedQueueCoordinator#getMin()} and {@link BlockArrayCacheScopedQueueCoordinator#getMax()}. 036 * The min and max points of this queue are offset according to the minimum point given in the constructor, and the offsets set 037 * in {@link BlockArrayCacheScopedQueueCoordinator#setOffsetX(int)} and 038 * {@link BlockArrayCacheScopedQueueCoordinator#setOffsetZ(int)} 039 */ 040@DoNotUse 041public class BlockArrayCacheScopedQueueCoordinator extends ScopedQueueCoordinator { 042 043 private final BlockState[][][] blockStates; 044 private final int height; 045 private final int width; 046 private final int length; 047 private final int minY; 048 private final int maxY; 049 private final int scopeMinX; 050 private final int scopeMinZ; 051 private final int scopeMaxX; 052 private final int scopeMaxZ; 053 private int offsetX = 0; 054 private int offsetZ = 0; 055 /** 056 * Construct a new instance 057 * 058 * @param min Inclusive location of the minimum point to limit the scope to. 059 * @param max Inclusive location of the maximum point to limit the scope to. 060 * @since 6.8.0 061 */ 062 public BlockArrayCacheScopedQueueCoordinator(Location min, Location max) { 063 super(null, min, max); 064 this.width = max.getX() - min.getX() + 1; 065 this.length = max.getZ() - min.getZ() + 1; 066 this.minY = min.getY(); 067 this.maxY = max.getY(); 068 this.height = maxY - minY + 1; 069 070 this.scopeMinX = min.getX() & 15; 071 this.scopeMinZ = min.getZ() & 15; 072 this.scopeMaxX = scopeMinX + width; 073 this.scopeMaxZ = scopeMinZ + length; 074 this.blockStates = new BlockState[height][width][length]; 075 } 076 077 public BlockState[][][] getBlockStates() { 078 return blockStates; 079 } 080 081 @Override 082 public boolean setBlock(int x, final int y, int z, final @NonNull BlockState id) { 083 x += offsetX; 084 z += offsetZ; 085 if (x >= scopeMinX && x < scopeMaxX && y >= minY && y <= maxY && z >= scopeMinZ && z < scopeMaxZ) { 086 blockStates[y - minY][x - scopeMinX][z - scopeMinZ] = id; 087 } 088 return false; 089 } 090 091 @Override 092 public boolean setBlock(final int x, final int y, final int z, @NonNull final Pattern pattern) { 093 int rx = x + offsetX; 094 int rz = z + offsetZ; 095 if (rx >= scopeMinX && rx < scopeMaxX && y >= minY && y <= maxY && rz >= scopeMinZ && rz < scopeMaxZ) { 096 BlockState state = pattern 097 .applyBlock(super.getMin().getBlockVector3().add(BlockVector3.at(x, y, z))) 098 .toImmutableState(); 099 blockStates[y - minY][rx - scopeMinX][rz - scopeMinZ] = state; 100 } 101 return false; 102 } 103 104 @Override 105 public @NonNull Location getMin() { 106 return super.getMin().add(offsetX - scopeMinX, 0, offsetZ - scopeMinZ); 107 } 108 109 @Override 110 public @NonNull Location getMax() { 111 return getMin().add(15, 0, 15).withY(maxY); 112 } 113 114 @Override 115 public boolean setBlock(int x, int y, int z, final @NonNull BaseBlock id) { 116 x += offsetX; 117 z += offsetZ; 118 if (x >= scopeMinX && x < scopeMaxX && y >= minY && y <= maxY && z >= scopeMinZ && z < scopeMaxZ) { 119 blockStates[y - minY][x - scopeMinX][z - scopeMinZ] = id.toImmutableState(); 120 } 121 return false; 122 } 123 124 @Override 125 public @Nullable BlockState getBlock(final int x, final int y, final int z) { 126 if (x >= 0 && x < width && y >= minY && y <= maxY && z >= 0 && z < length) { 127 return blockStates[y - minY][x][z]; 128 } 129 return null; 130 } 131 132 public void setOffsetX(final int offsetX) { 133 this.offsetX = offsetX; 134 } 135 136 public void setOffsetZ(final int offsetZ) { 137 this.offsetZ = offsetZ; 138 } 139 140 @Override 141 public int size() { 142 return height * width * length; 143 } 144 145 @Override 146 public boolean setBiome(final int x, final int z, @NonNull final BiomeType biome) { 147 //do nothing 148 return false; 149 } 150 151 @Override 152 public boolean setBiome(final int x, final int y, final int z, @NonNull final BiomeType biome) { 153 //do nothing 154 return false; 155 } 156 157 @Override 158 public void fillBiome(final BiomeType biome) { 159 //do nothing 160 } 161 162 @Override 163 public boolean setTile(final int x, final int y, final int z, @NonNull final CompoundTag tag) { 164 //do nothing 165 return false; 166 } 167 168}