mirror of
https://github.com/DieReicheErethons/Brewery.git
synced 2024-09-27 03:52:38 +02:00
cae2b9dfff
Uses Mutex to assure no concurrent loading and saving Merges Loaded data in Main Thread
410 lines
8.6 KiB
Java
410 lines
8.6 KiB
Java
package com.dre.brewery;
|
|
|
|
import com.dre.brewery.utility.BUtil;
|
|
import com.dre.brewery.utility.BoundingBox;
|
|
import com.dre.brewery.utility.LegacyUtil;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.configuration.ConfigurationSection;
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* The Blocks that make up a Barrel in the World
|
|
*/
|
|
public class BarrelBody {
|
|
|
|
private final Barrel barrel;
|
|
private final Block spigot;
|
|
private BoundingBox bounds;
|
|
private byte signoffset;
|
|
|
|
public BarrelBody(Barrel barrel, byte signoffset) {
|
|
this.barrel = barrel;
|
|
this.signoffset = signoffset;
|
|
spigot = barrel.getSpigot();
|
|
this.bounds = new BoundingBox(0, 0, 0, 0, 0, 0);
|
|
}
|
|
|
|
/**
|
|
* Loading from file
|
|
*/
|
|
public BarrelBody(Barrel barrel, byte signoffset, BoundingBox bounds, boolean async) {
|
|
this(barrel, signoffset);
|
|
|
|
if (boundsSeemBad(bounds)) {
|
|
if (async) {
|
|
this.bounds = null;
|
|
return;
|
|
}
|
|
// If loading from old data, or block locations are missing, or other error, regenerate BoundingBox
|
|
// This will only be done in those extreme cases.
|
|
regenerateBounds();
|
|
} else {
|
|
this.bounds = bounds;
|
|
}
|
|
}
|
|
|
|
public Barrel getBarrel() {
|
|
return barrel;
|
|
}
|
|
|
|
public Block getSpigot() {
|
|
return spigot;
|
|
}
|
|
|
|
@NotNull
|
|
public BoundingBox getBounds() {
|
|
return bounds;
|
|
}
|
|
|
|
public void setBounds(@NotNull BoundingBox bounds) {
|
|
Objects.requireNonNull(bounds);
|
|
this.bounds = bounds;
|
|
}
|
|
|
|
public byte getSignoffset() {
|
|
return signoffset;
|
|
}
|
|
|
|
public void setSignoffset(byte signoffset) {
|
|
this.signoffset = signoffset;
|
|
}
|
|
|
|
/**
|
|
* If the Sign of a Large Barrel gets destroyed, set signOffset to 0
|
|
*/
|
|
public void destroySign() {
|
|
signoffset = 0;
|
|
}
|
|
|
|
/**
|
|
* Quick check if the bounds are valid or seem corrupt
|
|
*/
|
|
public static boolean boundsSeemBad(BoundingBox bounds) {
|
|
if (bounds == null) return true;
|
|
long area = bounds.area();
|
|
return area > 64 || area < 4;
|
|
}
|
|
|
|
/**
|
|
* direction of the barrel from the spigot
|
|
*/
|
|
public static int getDirection(Block spigot) {
|
|
int direction = 0;// 1=x+ 2=x- 3=z+ 4=z-
|
|
Material type = spigot.getRelative(0, 0, 1).getType();
|
|
if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) {
|
|
direction = 3;
|
|
}
|
|
type = spigot.getRelative(0, 0, -1).getType();
|
|
if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) {
|
|
if (direction == 0) {
|
|
direction = 4;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
type = spigot.getRelative(1, 0, 0).getType();
|
|
if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) {
|
|
if (direction == 0) {
|
|
direction = 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
type = spigot.getRelative(-1, 0, 0).getType();
|
|
if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) {
|
|
if (direction == 0) {
|
|
direction = 2;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
return direction;
|
|
}
|
|
|
|
/**
|
|
* is this a Large barrel?
|
|
*/
|
|
public boolean isLarge() {
|
|
return barrel.isLarge();
|
|
}
|
|
|
|
/**
|
|
* is this a Small barrel?
|
|
*/
|
|
public boolean isSmall() {
|
|
return barrel.isSmall();
|
|
}
|
|
|
|
/**
|
|
* woodtype of the block the spigot is attached to
|
|
*/
|
|
public byte getWood() {
|
|
Block wood;
|
|
switch (getDirection(spigot)) { // 1=x+ 2=x- 3=z+ 4=z-
|
|
case 0:
|
|
return 0;
|
|
case 1:
|
|
wood = spigot.getRelative(1, 0, 0);
|
|
break;
|
|
case 2:
|
|
wood = spigot.getRelative(-1, 0, 0);
|
|
break;
|
|
case 3:
|
|
wood = spigot.getRelative(0, 0, 1);
|
|
break;
|
|
default:
|
|
wood = spigot.getRelative(0, 0, -1);
|
|
}
|
|
try {
|
|
return LegacyUtil.getWoodType(wood);
|
|
} catch (NoSuchFieldError | NoClassDefFoundError noSuchFieldError) {
|
|
// Using older minecraft versions some fields and classes do not exist
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns true if this Block is part of this Barrel
|
|
*
|
|
* @param block the block to check
|
|
* @return true if the given block is part of this Barrel
|
|
*/
|
|
public boolean hasBlock(Block block) {
|
|
if (block != null) {
|
|
if (spigot.equals(block)) {
|
|
return true;
|
|
}
|
|
if (spigot.getWorld().equals(block.getWorld())) {
|
|
return bounds != null && bounds.contains(block.getX(), block.getY(), block.getZ());
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the Offset of the clicked Sign matches the Barrel.
|
|
* <p>This prevents adding another sign to the barrel and clicking that.
|
|
*/
|
|
public boolean isSignOfBarrel(byte offset) {
|
|
return offset == 0 || signoffset == 0 || signoffset == offset;
|
|
}
|
|
|
|
/**
|
|
* returns the Sign of a large barrel, the spigot if there is none
|
|
*/
|
|
public Block getSignOfSpigot() {
|
|
if (signoffset != 0) {
|
|
if (LegacyUtil.isSign(spigot.getType())) {
|
|
return spigot;
|
|
}
|
|
|
|
if (LegacyUtil.isSign(spigot.getRelative(0, signoffset, 0).getType())) {
|
|
return spigot.getRelative(0, signoffset, 0);
|
|
} else {
|
|
signoffset = 0;
|
|
}
|
|
}
|
|
return spigot;
|
|
}
|
|
|
|
/**
|
|
* returns the fence above/below a block, itself if there is none
|
|
*/
|
|
public static Block getSpigotOfSign(Block block) {
|
|
|
|
int y = -2;
|
|
while (y <= 1) {
|
|
// Fence and Netherfence
|
|
Block relative = block.getRelative(0, y, 0);
|
|
if (LegacyUtil.isFence(relative.getType())) {
|
|
return (relative);
|
|
}
|
|
y++;
|
|
}
|
|
return block;
|
|
}
|
|
|
|
/**
|
|
* Regenerate the Barrel Bounds.
|
|
*
|
|
* @return true if successful, false if Barrel was broken and should be removed.
|
|
*/
|
|
public boolean regenerateBounds() {
|
|
P.p.log("Regenerating Barrel BoundingBox: " + (bounds == null ? "was null" : "area=" + bounds.area()));
|
|
Block broken = getBrokenBlock(true);
|
|
if (broken != null) {
|
|
barrel.remove(broken, null, true);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* returns null if Barrel is correctly placed; the block that is missing when not.
|
|
* <p>the barrel needs to be formed correctly
|
|
*
|
|
* @param force to also check even if chunk is not loaded
|
|
*/
|
|
public Block getBrokenBlock(boolean force) {
|
|
if (force || BUtil.isChunkLoaded(spigot)) {
|
|
//spigot = getSpigotOfSign(spigot);
|
|
if (LegacyUtil.isSign(spigot.getType())) {
|
|
return checkSBarrel();
|
|
} else {
|
|
return checkLBarrel();
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public Block checkSBarrel() {
|
|
int direction = getDirection(spigot);// 1=x+ 2=x- 3=z+ 4=z-
|
|
if (direction == 0) {
|
|
return spigot;
|
|
}
|
|
int startX;
|
|
int startZ;
|
|
int endX;
|
|
int endZ;
|
|
|
|
if (direction == 1) {
|
|
startX = 1;
|
|
startZ = -1;
|
|
} else if (direction == 2) {
|
|
startX = -2;
|
|
startZ = 0;
|
|
} else if (direction == 3) {
|
|
startX = 0;
|
|
startZ = 1;
|
|
} else {
|
|
startX = -1;
|
|
startZ = -2;
|
|
}
|
|
endX = startX + 1;
|
|
endZ = startZ + 1;
|
|
|
|
Material type;
|
|
int x = startX;
|
|
int y = 0;
|
|
int z = startZ;
|
|
while (y <= 1) {
|
|
while (x <= endX) {
|
|
while (z <= endZ) {
|
|
Block block = spigot.getRelative(x, y, z);
|
|
type = block.getType();
|
|
|
|
if (LegacyUtil.isWoodStairs(type)) {
|
|
if (y == 0) {
|
|
// stairs have to be upside down
|
|
if (!LegacyUtil.areStairsInverted(block)) {
|
|
return block;
|
|
}
|
|
}
|
|
z++;
|
|
} else {
|
|
return spigot.getRelative(x, y, z);
|
|
}
|
|
}
|
|
z = startZ;
|
|
x++;
|
|
}
|
|
z = startZ;
|
|
x = startX;
|
|
y++;
|
|
}
|
|
bounds = new BoundingBox(
|
|
spigot.getX() + startX,
|
|
spigot.getY(),
|
|
spigot.getZ() + startZ,
|
|
spigot.getX() + endX,
|
|
spigot.getY() + 1,
|
|
spigot.getZ() + endZ);
|
|
return null;
|
|
}
|
|
|
|
public Block checkLBarrel() {
|
|
int direction = getDirection(spigot);// 1=x+ 2=x- 3=z+ 4=z-
|
|
if (direction == 0) {
|
|
return spigot;
|
|
}
|
|
int startX;
|
|
int startZ;
|
|
int endX;
|
|
int endZ;
|
|
|
|
if (direction == 1) {
|
|
startX = 1;
|
|
startZ = -1;
|
|
} else if (direction == 2) {
|
|
startX = -4;
|
|
startZ = -1;
|
|
} else if (direction == 3) {
|
|
startX = -1;
|
|
startZ = 1;
|
|
} else {
|
|
startX = -1;
|
|
startZ = -4;
|
|
}
|
|
if (direction == 1 || direction == 2) {
|
|
endX = startX + 3;
|
|
endZ = startZ + 2;
|
|
} else {
|
|
endX = startX + 2;
|
|
endZ = startZ + 3;
|
|
}
|
|
|
|
Material type;
|
|
int x = startX;
|
|
int y = 0;
|
|
int z = startZ;
|
|
while (y <= 2) {
|
|
while (x <= endX) {
|
|
while (z <= endZ) {
|
|
Block block = spigot.getRelative(x, y, z);
|
|
type = block.getType();
|
|
if (direction == 1 || direction == 2) {
|
|
if (y == 1 && z == 0) {
|
|
z++;
|
|
continue;
|
|
}
|
|
} else {
|
|
if (y == 1 && x == 0) {
|
|
z++;
|
|
continue;
|
|
}
|
|
}
|
|
if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) {
|
|
z++;
|
|
} else {
|
|
return block;
|
|
}
|
|
}
|
|
z = startZ;
|
|
x++;
|
|
}
|
|
z = startZ;
|
|
x = startX;
|
|
y++;
|
|
}
|
|
bounds = new BoundingBox(
|
|
spigot.getX() + startX,
|
|
spigot.getY(),
|
|
spigot.getZ() + startZ,
|
|
spigot.getX() + endX,
|
|
spigot.getY() + 2,
|
|
spigot.getZ() + endZ);
|
|
|
|
return null;
|
|
}
|
|
|
|
public void save(ConfigurationSection config, String prefix) {
|
|
if (signoffset != 0) {
|
|
config.set(prefix + ".sign", signoffset);
|
|
}
|
|
config.set(prefix + ".bounds", bounds.serialize());
|
|
}
|
|
}
|