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.util.ChunkUtil;
022import com.plotsquared.core.util.MathMan;
023import com.sk89q.jnbt.CompoundTag;
024import com.sk89q.worldedit.entity.BaseEntity;
025import com.sk89q.worldedit.math.BlockVector3;
026import com.sk89q.worldedit.util.Location;
027import com.sk89q.worldedit.world.biome.BiomeType;
028import com.sk89q.worldedit.world.block.BaseBlock;
029import org.checkerframework.checker.nullness.qual.NonNull;
030
031import java.util.HashMap;
032
033public class LocalChunk {
034
035    private final QueueCoordinator parent;
036    private final int x;
037    private final int z;
038    private final int minSection;
039
040    private final BaseBlock[][] baseblocks;
041    private final BiomeType[][] biomes;
042    private final HashMap<BlockVector3, CompoundTag> tiles = new HashMap<>();
043    private final HashMap<Location, BaseEntity> entities = new HashMap<>();
044
045    public LocalChunk(@NonNull QueueCoordinator parent, int x, int z) {
046        this.parent = parent;
047        this.x = x;
048        this.z = z;
049        this.minSection = parent.getMinLayer();
050        int sections = parent.getMaxLayer() - parent.getMinLayer() + 1;
051        baseblocks = new BaseBlock[sections][];
052        biomes = new BiomeType[sections][];
053    }
054
055    public @NonNull QueueCoordinator getParent() {
056        return this.parent;
057    }
058
059    public int getX() {
060        return this.x;
061    }
062
063    public int getZ() {
064        return this.z;
065    }
066
067    /**
068     * Get the minimum layer position stored (usually -4 or 0).
069     *
070     * @since 6.6.0
071     */
072    public int getMinSection() {
073        return this.minSection;
074    }
075
076    public @NonNull BaseBlock[][] getBaseblocks() {
077        return this.baseblocks;
078    }
079
080    public @NonNull BiomeType[][] getBiomes() {
081        return this.biomes;
082    }
083
084    public @NonNull HashMap<BlockVector3, CompoundTag> getTiles() {
085        return this.tiles;
086    }
087
088    public void setBiome(final int x, final int y, final int z, final @NonNull BiomeType biomeType) {
089        final int i = getLayerIndex(y);
090        final int j = ChunkUtil.getJ(x, y, z);
091        BiomeType[] array = this.biomes[i];
092        if (array == null) {
093            array = this.biomes[i] = new BiomeType[4096];
094        }
095        array[j] = biomeType;
096    }
097
098    @Override
099    public int hashCode() {
100        return MathMan.pair((short) x, (short) z);
101    }
102
103    public void setBlock(final int x, final int y, final int z, final @NonNull BaseBlock baseBlock) {
104        final int i = getLayerIndex(y);
105        final int j = ChunkUtil.getJ(x, y, z);
106        BaseBlock[] array = baseblocks[i];
107        if (array == null) {
108            array = (baseblocks[i] = new BaseBlock[4096]);
109        }
110        array[j] = baseBlock;
111    }
112
113    public void setTile(final int x, final int y, final int z, final @NonNull CompoundTag tag) {
114        tiles.put(BlockVector3.at(x, y, z), tag);
115    }
116
117    public void setEntity(@NonNull Location location, @NonNull BaseEntity entity) {
118        this.entities.put(location, entity);
119    }
120
121    public @NonNull HashMap<Location, BaseEntity> getEntities() {
122        return this.entities;
123    }
124
125    private int getLayerIndex(final int y) {
126        return (y >> 4) - minSection;
127    }
128
129}