2022-07-30 15:21:11 +02:00
|
|
|
/**
|
|
|
|
|
* Copyright (C) 2022 FalsePattern
|
|
|
|
|
* All Rights Reserved
|
|
|
|
|
*
|
|
|
|
|
* The above copyright notice, this permission notice and the word "SNEED"
|
|
|
|
|
* shall be included in all copies or substantial portions of the Software.
|
|
|
|
|
*
|
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU Lesser 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 Lesser General Public License
|
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
2022-05-06 17:41:02 +02:00
|
|
|
package com.falsepattern.lib.compat;
|
|
|
|
|
|
2022-05-06 23:53:11 +02:00
|
|
|
import com.falsepattern.lib.StableAPI;
|
2022-07-30 20:26:34 +02:00
|
|
|
import com.falsepattern.lib.util.MathUtil;
|
2022-05-06 17:41:02 +02:00
|
|
|
import com.google.common.collect.AbstractIterator;
|
|
|
|
|
import cpw.mods.fml.relauncher.Side;
|
|
|
|
|
import cpw.mods.fml.relauncher.SideOnly;
|
2022-06-08 16:01:06 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import javax.annotation.concurrent.Immutable;
|
|
|
|
|
import lombok.Getter;
|
|
|
|
|
import lombok.NonNull;
|
|
|
|
|
import lombok.Setter;
|
|
|
|
|
import lombok.val;
|
2022-05-06 17:41:02 +02:00
|
|
|
import net.minecraft.entity.Entity;
|
|
|
|
|
import net.minecraft.util.EnumFacing;
|
|
|
|
|
import net.minecraft.util.Vec3;
|
|
|
|
|
import org.apache.logging.log4j.LogManager;
|
|
|
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
|
|
2022-06-08 16:01:06 +02:00
|
|
|
import static net.minecraft.util.EnumFacing.DOWN;
|
|
|
|
|
import static net.minecraft.util.EnumFacing.EAST;
|
|
|
|
|
import static net.minecraft.util.EnumFacing.NORTH;
|
|
|
|
|
import static net.minecraft.util.EnumFacing.SOUTH;
|
|
|
|
|
import static net.minecraft.util.EnumFacing.UP;
|
|
|
|
|
import static net.minecraft.util.EnumFacing.WEST;
|
2022-05-31 14:24:40 +01:00
|
|
|
|
2022-05-06 17:41:02 +02:00
|
|
|
@Immutable
|
2022-05-06 23:53:11 +02:00
|
|
|
@StableAPI(since = "0.6.0")
|
2022-05-06 17:41:02 +02:00
|
|
|
public class BlockPos extends Vec3i {
|
|
|
|
|
/**
|
|
|
|
|
* An immutable block pos with zero as all coordinates.
|
|
|
|
|
*/
|
|
|
|
|
public static final BlockPos ORIGIN = new BlockPos(0, 0, 0);
|
|
|
|
|
private static final Logger LOGGER = LogManager.getLogger();
|
2022-07-30 20:26:34 +02:00
|
|
|
private static final int NUM_X_BITS = 1 + MathUtil.log2(MathUtil.smallestEncompassingPowerOfTwo(30000000));
|
2022-05-06 17:41:02 +02:00
|
|
|
private static final int NUM_Z_BITS = NUM_X_BITS;
|
|
|
|
|
private static final int NUM_Y_BITS = 64 - NUM_X_BITS - NUM_Z_BITS;
|
|
|
|
|
private static final long Y_MASK = (1L << NUM_Y_BITS) - 1L;
|
|
|
|
|
private static final int Y_SHIFT = NUM_Z_BITS;
|
|
|
|
|
private static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS;
|
|
|
|
|
private static final long Z_MASK = (1L << NUM_Z_BITS) - 1L;
|
|
|
|
|
private static final long X_MASK = (1L << NUM_X_BITS) - 1L;
|
|
|
|
|
|
2022-06-08 16:01:06 +02:00
|
|
|
public BlockPos(@NonNull Entity source) {
|
|
|
|
|
this(source.posX, source.posY, source.posZ);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public BlockPos(double x, double y, double z) {
|
|
|
|
|
super(x, y, z);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos(@NonNull Vec3 vec) {
|
2022-05-06 17:41:02 +02:00
|
|
|
this(vec.xCoord, vec.yCoord, vec.zCoord);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos(@NonNull Vec3i source) {
|
2022-05-06 17:41:02 +02:00
|
|
|
this(source.getX(), source.getY(), source.getZ());
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-08 16:01:06 +02:00
|
|
|
public BlockPos(int x, int y, int z) {
|
|
|
|
|
super(x, y, z);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-06 17:41:02 +02:00
|
|
|
/**
|
|
|
|
|
* Create a BlockPos from a serialized long value (created by toLong)
|
|
|
|
|
*/
|
|
|
|
|
public static BlockPos fromLong(long serialized) {
|
2022-06-08 16:01:06 +02:00
|
|
|
return new BlockPos((int) (serialized << 64 - X_SHIFT - NUM_X_BITS >> 64 - NUM_X_BITS),
|
|
|
|
|
(int) (serialized << 64 - Y_SHIFT - NUM_Y_BITS >> 64 - NUM_Y_BITS),
|
|
|
|
|
(int) (serialized << 64 - NUM_Z_BITS >> 64 - NUM_Z_BITS));
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create an Iterable that returns all positions in the box specified by the given corners. There is no requirement
|
|
|
|
|
* that one corner is greater than the other; individual coordinates will be swapped as needed.
|
|
|
|
|
* <p>
|
2022-06-08 16:01:06 +02:00
|
|
|
* In situations where it is usable, prefer
|
|
|
|
|
* {@link #getAllInBoxMutable(BlockPos, BlockPos) instead as it has better performance (fewer allocations)
|
2022-05-06 17:41:02 +02:00
|
|
|
*
|
|
|
|
|
* @param from One corner of the box
|
|
|
|
|
* @param to Another corner of the box
|
2022-06-08 16:01:06 +02:00
|
|
|
*
|
2022-05-06 17:41:02 +02:00
|
|
|
* @see #getAllInBox(int, int, int, int, int, int)
|
|
|
|
|
* @see #getAllInBoxMutable(BlockPos, BlockPos)
|
|
|
|
|
*/
|
2022-05-31 14:24:40 +01:00
|
|
|
public static Iterable<BlockPos> getAllInBox(@NonNull BlockPos from, @NonNull BlockPos to) {
|
2022-06-08 16:01:06 +02:00
|
|
|
return getAllInBox(Math.min(from.getX(), to.getX()),
|
|
|
|
|
Math.min(from.getY(), to.getY()),
|
|
|
|
|
Math.min(from.getZ(), to.getZ()),
|
|
|
|
|
Math.max(from.getX(), to.getX()),
|
|
|
|
|
Math.max(from.getY(), to.getY()),
|
|
|
|
|
Math.max(from.getZ(), to.getZ()));
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create an Iterable that returns all positions in the box specified by the coordinates. <strong>Coordinates must
|
2022-05-31 14:24:40 +01:00
|
|
|
* be in order</strong>; e.g. x0 <= x1.
|
2022-05-06 17:41:02 +02:00
|
|
|
* <p>
|
2022-06-08 16:01:06 +02:00
|
|
|
* In situations where it is usable, prefer
|
|
|
|
|
* {@link #getAllInBoxMutable(BlockPos, BlockPos) instead as it has better performance (fewer allocations)
|
2022-05-06 17:41:02 +02:00
|
|
|
*
|
2022-05-31 14:24:40 +01:00
|
|
|
* @param x0 The lower x coordinate
|
|
|
|
|
* @param y0 The lower y coordinate
|
|
|
|
|
* @param z0 The lower z coordinate
|
|
|
|
|
* @param x1 The upper x coordinate
|
|
|
|
|
* @param y1 The upper y coordinate
|
|
|
|
|
* @param z1 The upper z coordinate
|
2022-06-08 16:01:06 +02:00
|
|
|
*
|
2022-05-06 17:41:02 +02:00
|
|
|
* @see #getAllInBox(BlockPos, BlockPos)
|
|
|
|
|
* @see #getAllInBoxMutable(BlockPos, BlockPos)
|
|
|
|
|
*/
|
2022-06-08 16:01:06 +02:00
|
|
|
public static Iterable<BlockPos> getAllInBox(final int x0,
|
|
|
|
|
final int y0,
|
|
|
|
|
final int z0,
|
|
|
|
|
final int x1,
|
|
|
|
|
final int y1,
|
|
|
|
|
final int z1) {
|
2022-05-31 14:24:40 +01:00
|
|
|
return () -> new AbstractIterator<BlockPos>() {
|
|
|
|
|
private boolean first = true;
|
|
|
|
|
private int lastX;
|
|
|
|
|
private int lastY;
|
|
|
|
|
private int lastZ;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected BlockPos computeNext() {
|
|
|
|
|
if (first) {
|
|
|
|
|
first = false;
|
|
|
|
|
lastX = x0;
|
|
|
|
|
lastY = y0;
|
|
|
|
|
lastZ = z0;
|
|
|
|
|
return new BlockPos(x0, y0, z0);
|
|
|
|
|
}
|
2022-06-08 16:01:06 +02:00
|
|
|
if (lastX == x1 && lastY == y1 && lastZ == z1) {
|
2022-05-31 14:24:40 +01:00
|
|
|
return endOfData();
|
2022-06-08 16:01:06 +02:00
|
|
|
}
|
2022-05-31 14:24:40 +01:00
|
|
|
if (lastX < x1) {
|
|
|
|
|
lastX++;
|
|
|
|
|
} else if (lastY < y1) {
|
|
|
|
|
lastX = x0;
|
|
|
|
|
lastY++;
|
|
|
|
|
} else if (lastZ < z1) {
|
|
|
|
|
lastX = x0;
|
|
|
|
|
lastY = y0;
|
|
|
|
|
lastZ++;
|
|
|
|
|
}
|
|
|
|
|
return new BlockPos(lastX, lastY, lastZ);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates an Iterable that returns all positions in the box specified by the given corners. There is no requirement
|
|
|
|
|
* that one corner is greater than the other; individual coordinates will be swapped as needed.
|
|
|
|
|
* <p>
|
|
|
|
|
* This method uses {@link BlockPos.MutableBlockPos MutableBlockPos} instead of regular BlockPos, which grants
|
|
|
|
|
* better performance. However, the resulting BlockPos instances can only be used inside the iteration loop (as
|
|
|
|
|
* otherwise the value will change), unless {@link #toImmutable()} is called. This method is ideal for searching
|
|
|
|
|
* large areas and only storing a few locations.
|
|
|
|
|
*
|
|
|
|
|
* @param from One corner of the box
|
|
|
|
|
* @param to Another corner of the box
|
2022-06-08 16:01:06 +02:00
|
|
|
*
|
2022-05-06 17:41:02 +02:00
|
|
|
* @see #getAllInBox(BlockPos, BlockPos)
|
|
|
|
|
* @see #getAllInBox(int, int, int, int, int, int)
|
|
|
|
|
* @see #getAllInBoxMutable(BlockPos, BlockPos)
|
|
|
|
|
*/
|
2022-05-31 14:24:40 +01:00
|
|
|
public static Iterable<BlockPos.MutableBlockPos> getAllInBoxMutable(@NonNull BlockPos from, @NonNull BlockPos to) {
|
2022-06-08 16:01:06 +02:00
|
|
|
return getAllInBoxMutable(Math.min(from.getX(), to.getX()),
|
|
|
|
|
Math.min(from.getY(), to.getY()),
|
|
|
|
|
Math.min(from.getZ(), to.getZ()),
|
|
|
|
|
Math.max(from.getX(), to.getX()),
|
|
|
|
|
Math.max(from.getY(), to.getY()),
|
|
|
|
|
Math.max(from.getZ(), to.getZ()));
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates an Iterable that returns all positions in the box specified by the given corners. <strong>Coordinates
|
2022-05-31 14:24:40 +01:00
|
|
|
* must be in order</strong>; e.g. x0 <= x1.
|
2022-05-06 17:41:02 +02:00
|
|
|
* <p>
|
|
|
|
|
* This method uses {@link BlockPos.MutableBlockPos MutableBlockPos} instead of regular BlockPos, which grants
|
|
|
|
|
* better performance. However, the resulting BlockPos instances can only be used inside the iteration loop (as
|
|
|
|
|
* otherwise the value will change), unless {@link #toImmutable()} is called. This method is ideal for searching
|
|
|
|
|
* large areas and only storing a few locations.
|
|
|
|
|
*
|
2022-05-31 14:24:40 +01:00
|
|
|
* @param x0 The lower x coordinate
|
|
|
|
|
* @param y0 The lower y coordinate
|
|
|
|
|
* @param z0 The lower z coordinate
|
|
|
|
|
* @param x1 The upper x coordinate
|
|
|
|
|
* @param y1 The upper y coordinate
|
|
|
|
|
* @param z1 The upper z coordinate
|
2022-06-08 16:01:06 +02:00
|
|
|
*
|
2022-05-06 17:41:02 +02:00
|
|
|
* @see #getAllInBox(BlockPos, BlockPos)
|
|
|
|
|
* @see #getAllInBox(int, int, int, int, int, int)
|
|
|
|
|
* @see #getAllInBoxMutable(BlockPos, BlockPos)
|
|
|
|
|
*/
|
2022-06-08 16:01:06 +02:00
|
|
|
public static Iterable<BlockPos.MutableBlockPos> getAllInBoxMutable(final int x0,
|
|
|
|
|
final int y0,
|
|
|
|
|
final int z0,
|
|
|
|
|
final int x1,
|
|
|
|
|
final int y1,
|
|
|
|
|
final int z1) {
|
2022-05-31 14:24:40 +01:00
|
|
|
return () -> new AbstractIterator<MutableBlockPos>() {
|
|
|
|
|
private MutableBlockPos pos;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected MutableBlockPos computeNext() {
|
|
|
|
|
if (pos == null) {
|
|
|
|
|
pos = new MutableBlockPos(x0, y0, z0);
|
|
|
|
|
return pos;
|
|
|
|
|
} else if (pos.x == x1 && pos.y == y1 && pos.z == z1) {
|
|
|
|
|
return endOfData();
|
|
|
|
|
} else {
|
|
|
|
|
if (pos.x < x1) {
|
|
|
|
|
pos.x++;
|
|
|
|
|
} else if (pos.y < y1) {
|
|
|
|
|
pos.x = x0;
|
|
|
|
|
pos.y++;
|
|
|
|
|
} else if (pos.z < z1) {
|
|
|
|
|
pos.x = x0;
|
|
|
|
|
pos.y = y0;
|
|
|
|
|
pos.z++;
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
2022-05-31 14:24:40 +01:00
|
|
|
return pos;
|
|
|
|
|
}
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-08 16:01:06 +02:00
|
|
|
public long toLong() {
|
|
|
|
|
return ((long) x & X_MASK) << X_SHIFT | ((long) y & Y_MASK) << Y_SHIFT | ((long) z & Z_MASK);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Add the given coordinates to the coordinates of this BlockPos
|
|
|
|
|
*/
|
2022-06-08 16:01:06 +02:00
|
|
|
public BlockPos add(double x, double y, double z) {
|
|
|
|
|
if (x == 0.0D && y == 0.0D && z == 0.0D) {
|
2022-05-31 14:24:40 +01:00
|
|
|
return this;
|
2022-06-08 16:01:06 +02:00
|
|
|
}
|
2022-05-31 14:24:40 +01:00
|
|
|
return new BlockPos(this.x + x, this.y + y, this.z + z);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Add the given Vector to this BlockPos
|
|
|
|
|
*/
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos add(@NonNull Vec3i vec) {
|
|
|
|
|
return add(vec.getX(), vec.getY(), vec.getZ());
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-08 16:01:06 +02:00
|
|
|
/**
|
|
|
|
|
* Add the given coordinates to the coordinates of this BlockPos
|
|
|
|
|
*/
|
|
|
|
|
public BlockPos add(int x, int y, int z) {
|
|
|
|
|
if (x == 0 && y == 0 && z == 0) {
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
return new BlockPos(this.x + x, this.y + y, this.z + z);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-06 17:41:02 +02:00
|
|
|
/**
|
|
|
|
|
* Subtract the given Vector from this BlockPos
|
|
|
|
|
*/
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos subtract(@NonNull Vec3i vec) {
|
|
|
|
|
return add(-vec.getX(), -vec.getY(), -vec.getZ());
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public BlockPos up() {
|
2022-05-31 14:24:40 +01:00
|
|
|
return up(1);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos up(int blocks) {
|
|
|
|
|
return offset(UP, blocks);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-08 16:01:06 +02:00
|
|
|
public BlockPos offset(@NonNull EnumFacing facing, int blocks) {
|
|
|
|
|
if (blocks == 0) {
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
return new BlockPos(x + facing.getFrontOffsetX() * blocks,
|
|
|
|
|
y + facing.getFrontOffsetY() * blocks,
|
|
|
|
|
z + facing.getFrontOffsetZ() * blocks);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-06 17:41:02 +02:00
|
|
|
public BlockPos down() {
|
2022-05-31 14:24:40 +01:00
|
|
|
return down(1);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos down(int blocks) {
|
|
|
|
|
return offset(DOWN, blocks);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public BlockPos north() {
|
2022-05-31 14:24:40 +01:00
|
|
|
return north(1);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos north(int blocks) {
|
|
|
|
|
return offset(NORTH, blocks);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public BlockPos south() {
|
2022-05-31 14:24:40 +01:00
|
|
|
return south(1);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos south(int blocks) {
|
|
|
|
|
return offset(SOUTH, blocks);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public BlockPos west() {
|
2022-05-31 14:24:40 +01:00
|
|
|
return west(1);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos west(int blocks) {
|
|
|
|
|
return offset(WEST, blocks);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public BlockPos east() {
|
2022-05-31 14:24:40 +01:00
|
|
|
return east(1);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos east(int blocks) {
|
|
|
|
|
return offset(EAST, blocks);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos offset(@NonNull EnumFacing facing) {
|
|
|
|
|
return offset(facing, 1);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos rotate(@NonNull Rotation rotation) {
|
|
|
|
|
switch (rotation) {
|
2022-05-06 17:41:02 +02:00
|
|
|
case NONE:
|
|
|
|
|
default:
|
|
|
|
|
return this;
|
|
|
|
|
case CLOCKWISE_90:
|
|
|
|
|
return new BlockPos(-this.getZ(), this.getY(), this.getX());
|
|
|
|
|
case CLOCKWISE_180:
|
|
|
|
|
return new BlockPos(-this.getX(), this.getY(), -this.getZ());
|
|
|
|
|
case COUNTERCLOCKWISE_90:
|
|
|
|
|
return new BlockPos(this.getZ(), this.getY(), -this.getX());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
@Override
|
|
|
|
|
public BlockPos crossProduct(@NonNull Vec3i vec) {
|
2022-06-08 16:01:06 +02:00
|
|
|
return new BlockPos(y * vec.getZ() - z * vec.getY(),
|
|
|
|
|
z * vec.getX() - x * vec.getZ(),
|
|
|
|
|
x * vec.getY() - y * vec.getX());
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public BlockPos toImmutable() {
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
@Setter
|
|
|
|
|
@Getter
|
2022-05-06 17:41:02 +02:00
|
|
|
public static class MutableBlockPos extends BlockPos {
|
|
|
|
|
/**
|
|
|
|
|
* Mutable X Coordinate
|
|
|
|
|
*/
|
|
|
|
|
protected int x;
|
|
|
|
|
/**
|
|
|
|
|
* Mutable Y Coordinate
|
|
|
|
|
*/
|
|
|
|
|
protected int y;
|
|
|
|
|
/**
|
|
|
|
|
* Mutable Z Coordinate
|
|
|
|
|
*/
|
|
|
|
|
protected int z;
|
|
|
|
|
|
|
|
|
|
public MutableBlockPos() {
|
2022-05-31 14:24:40 +01:00
|
|
|
this(ORIGIN);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public MutableBlockPos(@NonNull BlockPos blockPos) {
|
|
|
|
|
this(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public MutableBlockPos(int x, int y, int z) {
|
|
|
|
|
super(ORIGIN);
|
|
|
|
|
this.x = x;
|
|
|
|
|
this.y = y;
|
|
|
|
|
this.z = z;
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
@Override
|
2022-05-06 17:41:02 +02:00
|
|
|
public BlockPos add(double x, double y, double z) {
|
|
|
|
|
return super.add(x, y, z).toImmutable();
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
@Override
|
2022-05-06 17:41:02 +02:00
|
|
|
public BlockPos add(int x, int y, int z) {
|
|
|
|
|
return super.add(x, y, z).toImmutable();
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
@Override
|
|
|
|
|
public BlockPos offset(@NonNull EnumFacing facing, int blocks) {
|
|
|
|
|
return super.offset(facing, blocks).toImmutable();
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
@Override
|
|
|
|
|
public BlockPos rotate(@NonNull Rotation rotation) {
|
|
|
|
|
return super.rotate(rotation).toImmutable();
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-08 16:01:06 +02:00
|
|
|
public BlockPos toImmutable() {
|
|
|
|
|
return new BlockPos(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
|
|
|
public BlockPos.MutableBlockPos setPos(@NonNull Entity entity) {
|
|
|
|
|
return this.setPos(entity.posX, entity.posY, entity.posZ);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos.MutableBlockPos setPos(double x, double y, double z) {
|
2022-07-30 20:26:34 +02:00
|
|
|
return setPos(MathUtil.floor(x), MathUtil.floor(y), MathUtil.floor(z));
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos.MutableBlockPos setPos(int x, int y, int z) {
|
|
|
|
|
this.x = x;
|
|
|
|
|
this.y = y;
|
|
|
|
|
this.z = z;
|
2022-05-06 17:41:02 +02:00
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos.MutableBlockPos setPos(@NonNull Vec3i vec) {
|
2022-05-06 17:41:02 +02:00
|
|
|
return this.setPos(vec.getX(), vec.getY(), vec.getZ());
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos.MutableBlockPos move(@NonNull EnumFacing facing) {
|
2022-05-06 17:41:02 +02:00
|
|
|
return this.move(facing, 1);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos.MutableBlockPos move(@NonNull EnumFacing facing, int blocks) {
|
2022-06-08 16:01:06 +02:00
|
|
|
return this.setPos(x + facing.getFrontOffsetX() * blocks,
|
|
|
|
|
y + facing.getFrontOffsetY() * blocks,
|
|
|
|
|
z + facing.getFrontOffsetZ() * blocks);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static final class PooledMutableBlockPos extends BlockPos.MutableBlockPos {
|
2022-05-31 14:24:40 +01:00
|
|
|
private static final List<BlockPos.PooledMutableBlockPos> POOL = new ArrayList<>();
|
2022-05-06 17:41:02 +02:00
|
|
|
private boolean released;
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
private PooledMutableBlockPos(int x, int y, int z) {
|
|
|
|
|
super(x, y, z);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static BlockPos.PooledMutableBlockPos retain() {
|
|
|
|
|
return retain(0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
public static BlockPos.PooledMutableBlockPos retain(int x, int y, int z) {
|
2022-05-06 17:41:02 +02:00
|
|
|
synchronized (POOL) {
|
|
|
|
|
if (!POOL.isEmpty()) {
|
2022-05-31 14:24:40 +01:00
|
|
|
val pos = POOL.remove(POOL.size() - 1);
|
2022-05-06 17:41:02 +02:00
|
|
|
if (pos != null && pos.released) {
|
|
|
|
|
pos.released = false;
|
2022-05-31 14:24:40 +01:00
|
|
|
pos.setPos(x, y, z);
|
2022-05-06 17:41:02 +02:00
|
|
|
return pos;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-05-31 14:24:40 +01:00
|
|
|
return new BlockPos.PooledMutableBlockPos(x, y, z);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-08 16:01:06 +02:00
|
|
|
public static BlockPos.PooledMutableBlockPos retain(double x, double y, double z) {
|
2022-07-30 20:26:34 +02:00
|
|
|
return retain(MathUtil.floor(x), MathUtil.floor(y), MathUtil.floor(z));
|
2022-06-08 16:01:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
|
|
|
public static BlockPos.PooledMutableBlockPos retain(@NonNull Vec3i vec) {
|
|
|
|
|
return retain(vec.getX(), vec.getY(), vec.getZ());
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-06 17:41:02 +02:00
|
|
|
public void release() {
|
|
|
|
|
synchronized (POOL) {
|
|
|
|
|
if (POOL.size() < 100) {
|
|
|
|
|
POOL.add(this);
|
|
|
|
|
}
|
|
|
|
|
this.released = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
@Override
|
2022-05-06 17:41:02 +02:00
|
|
|
@SideOnly(Side.CLIENT)
|
2022-05-31 14:24:40 +01:00
|
|
|
public BlockPos.PooledMutableBlockPos setPos(@NonNull Entity entity) {
|
|
|
|
|
return (BlockPos.PooledMutableBlockPos) super.setPos(entity);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
@Override
|
|
|
|
|
public BlockPos.PooledMutableBlockPos setPos(double x, double y, double z) {
|
|
|
|
|
return (BlockPos.PooledMutableBlockPos) super.setPos(x, y, z);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-08 16:01:06 +02:00
|
|
|
@Override
|
|
|
|
|
public BlockPos.PooledMutableBlockPos setPos(int x, int y, int z) {
|
|
|
|
|
if (released) {
|
|
|
|
|
BlockPos.LOGGER.error("PooledMutableBlockPosition modified after it was released.", new Throwable());
|
|
|
|
|
released = false;
|
|
|
|
|
}
|
|
|
|
|
return (BlockPos.PooledMutableBlockPos) super.setPos(x, y, z);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
@Override
|
|
|
|
|
public BlockPos.PooledMutableBlockPos setPos(@NonNull Vec3i vec) {
|
2022-05-06 17:41:02 +02:00
|
|
|
return (BlockPos.PooledMutableBlockPos) super.setPos(vec);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
@Override
|
|
|
|
|
public BlockPos.PooledMutableBlockPos move(@NonNull EnumFacing facing) {
|
2022-05-06 17:41:02 +02:00
|
|
|
return (BlockPos.PooledMutableBlockPos) super.move(facing);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 14:24:40 +01:00
|
|
|
@Override
|
|
|
|
|
public BlockPos.PooledMutableBlockPos move(@NonNull EnumFacing facing, int blocks) {
|
|
|
|
|
return (BlockPos.PooledMutableBlockPos) super.move(facing, blocks);
|
2022-05-06 17:41:02 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|