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.plotsquared.core.location.Location;
022import com.sk89q.worldedit.function.pattern.Pattern;
023import com.sk89q.worldedit.math.BlockVector3;
024import com.sk89q.worldedit.world.World;
025import com.sk89q.worldedit.world.biome.BiomeType;
026import com.sk89q.worldedit.world.block.BaseBlock;
027import com.sk89q.worldedit.world.block.BlockState;
028import org.checkerframework.checker.nullness.qual.NonNull;
029import org.checkerframework.checker.nullness.qual.Nullable;
030
031/**
032 * Queue that is limited to a single chunk. It does not allow a delegate queue and should be treated as a cache for changes to
033 * be set to. Does not support tile entities or entities.
034 *
035 * @deprecated This class is poorly designed and will no longer be used in PlotSquared
036 */
037@Deprecated(forRemoval = true, since = "6.8.0")
038public class ChunkQueueCoordinator extends ScopedQueueCoordinator {
039
040    public final BiomeType[][][] biomeResult;
041    public final BlockState[][][] result;
042    private final int width;
043    private final int length;
044    private final BlockVector3 bot;
045    private final BlockVector3 top;
046    private final World weWorld;
047
048    public ChunkQueueCoordinator(
049            final @NonNull World weWorld,
050            @NonNull BlockVector3 bot,
051            @NonNull BlockVector3 top,
052            boolean biomes
053    ) {
054        super(null, Location.at("", 0, weWorld.getMinY(), 0), Location.at("", 15, weWorld.getMaxY(), 15));
055        this.weWorld = weWorld;
056        this.width = top.getX() - bot.getX() + 1;
057        this.length = top.getZ() - bot.getZ() + 1;
058        this.result = new BlockState[weWorld.getMaxY() - weWorld.getMinY() + 1][width][length];
059        this.biomeResult = biomes ? new BiomeType[weWorld.getMaxY() - weWorld.getMinY() + 1][width][length] : null;
060        this.bot = bot;
061        this.top = top;
062    }
063
064    public @NonNull BlockState[][][] getBlocks() {
065        return result;
066    }
067
068    @Override
069    public boolean setBiome(int x, int z, @NonNull BiomeType biomeType) {
070        if (this.biomeResult != null) {
071            for (int y = weWorld.getMinY(); y <= weWorld.getMaxY(); y++) {
072                this.storeCacheBiome(x, y, z, biomeType);
073            }
074            return true;
075        }
076        return false;
077    }
078
079    @Override
080    public boolean setBiome(int x, int y, int z, @NonNull BiomeType biomeType) {
081        if (this.biomeResult != null) {
082            this.storeCacheBiome(x, y, z, biomeType);
083            return true;
084        }
085        return false;
086    }
087
088    @Override
089    public boolean setBlock(int x, int y, int z, @NonNull BlockState id) {
090        this.storeCache(x, y, z, id);
091        return true;
092    }
093
094    @Override
095    public boolean setBlock(int x, int y, int z, @NonNull Pattern pattern) {
096        this.storeCache(x, y, z, pattern.applyBlock(BlockVector3.at(x, y, z)).toImmutableState());
097        return true;
098    }
099
100    private void storeCache(final int x, final int y, final int z, final @NonNull BlockState id) {
101        int yIndex = getYIndex(y);
102        BlockState[][] resultY = result[yIndex];
103        if (resultY == null) {
104            result[yIndex] = resultY = new BlockState[length][];
105        }
106        BlockState[] resultYZ = resultY[z];
107        if (resultYZ == null) {
108            resultY[z] = resultYZ = new BlockState[width];
109        }
110        resultYZ[x] = id;
111    }
112
113    private void storeCacheBiome(final int x, final int y, final int z, final @NonNull BiomeType id) {
114        int yIndex = getYIndex(y);
115        BiomeType[][] resultY = biomeResult[yIndex];
116        if (resultY == null) {
117            biomeResult[yIndex] = resultY = new BiomeType[length][];
118        }
119        BiomeType[] resultYZ = resultY[z];
120        if (resultYZ == null) {
121            resultY[z] = resultYZ = new BiomeType[width];
122        }
123        resultYZ[x] = id;
124    }
125
126    @Override
127    public boolean setBlock(int x, int y, int z, final @NonNull BaseBlock id) {
128        this.storeCache(x, y, z, id.toImmutableState());
129        return true;
130    }
131
132    @Override
133    public @Nullable BlockState getBlock(int x, int y, int z) {
134        BlockState[][] blocksY = result[getYIndex(y)];
135        if (blocksY != null) {
136            BlockState[] blocksYZ = blocksY[z];
137            if (blocksYZ != null) {
138                return blocksYZ[x];
139            }
140        }
141        return null;
142    }
143
144    @Override
145    public @Nullable World getWorld() {
146        return weWorld;
147    }
148
149    @Override
150    public @NonNull Location getMax() {
151        return Location.at(getWorld().getName(), top.getX(), top.getY(), top.getZ());
152    }
153
154    @Override
155    public @NonNull Location getMin() {
156        return Location.at(getWorld().getName(), bot.getX(), bot.getY(), bot.getZ());
157    }
158
159    private int getYIndex(int y) {
160        return y - weWorld.getMinY();
161    }
162
163}