package net.minecraft.server;
import com.google.common.collect.Lists;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
public class TileEntityStructure extends TileEntity {
private MinecraftKey structureName;
public String author = "";
public String metadata = "";
public BlockPosition relativePosition = new BlockPosition(0, 1, 0);
public BlockPosition size;
public EnumBlockMirror mirror;
public EnumBlockRotation rotation;
public BlockPropertyStructureMode usageMode;
public boolean ignoreEntities;
private boolean powered;
public boolean showAir;
public boolean showBoundingBox;
public float integrity;
public long seed;
public TileEntityStructure() {
super(TileEntityTypes.STRUCTURE_BLOCK);
this.size = BlockPosition.ZERO;
this.mirror = EnumBlockMirror.NONE;
this.rotation = EnumBlockRotation.NONE;
this.usageMode = BlockPropertyStructureMode.DATA;
this.ignoreEntities = true;
this.showBoundingBox = true;
this.integrity = 1.0F;
}
@Override
public NBTTagCompound save(NBTTagCompound nbttagcompound) {
super.save(nbttagcompound);
nbttagcompound.setString("name", this.getStructureName());
nbttagcompound.setString("author", this.author);
nbttagcompound.setString("metadata", this.metadata);
nbttagcompound.setInt("posX", this.relativePosition.getX());
nbttagcompound.setInt("posY", this.relativePosition.getY());
nbttagcompound.setInt("posZ", this.relativePosition.getZ());
nbttagcompound.setInt("sizeX", this.size.getX());
nbttagcompound.setInt("sizeY", this.size.getY());
nbttagcompound.setInt("sizeZ", this.size.getZ());
nbttagcompound.setString("rotation", this.rotation.toString());
nbttagcompound.setString("mirror", this.mirror.toString());
nbttagcompound.setString("mode", this.usageMode.toString());
nbttagcompound.setBoolean("ignoreEntities", this.ignoreEntities);
nbttagcompound.setBoolean("powered", this.powered);
nbttagcompound.setBoolean("showair", this.showAir);
nbttagcompound.setBoolean("showboundingbox", this.showBoundingBox);
nbttagcompound.setFloat("integrity", this.integrity);
nbttagcompound.setLong("seed", this.seed);
return nbttagcompound;
}
@Override
public void load(NBTTagCompound nbttagcompound) {
super.load(nbttagcompound);
this.setStructureName(nbttagcompound.getString("name"));
this.author = nbttagcompound.getString("author");
this.metadata = nbttagcompound.getString("metadata");
int i = MathHelper.clamp(nbttagcompound.getInt("posX"), -32, 32);
int j = MathHelper.clamp(nbttagcompound.getInt("posY"), -32, 32);
int k = MathHelper.clamp(nbttagcompound.getInt("posZ"), -32, 32);
this.relativePosition = new BlockPosition(i, j, k);
int l = MathHelper.clamp(nbttagcompound.getInt("sizeX"), 0, 32);
int i1 = MathHelper.clamp(nbttagcompound.getInt("sizeY"), 0, 32);
int j1 = MathHelper.clamp(nbttagcompound.getInt("sizeZ"), 0, 32);
this.size = new BlockPosition(l, i1, j1);
try {
this.rotation = EnumBlockRotation.valueOf(nbttagcompound.getString("rotation"));
} catch (IllegalArgumentException illegalargumentexception) {
this.rotation = EnumBlockRotation.NONE;
}
try {
this.mirror = EnumBlockMirror.valueOf(nbttagcompound.getString("mirror"));
} catch (IllegalArgumentException illegalargumentexception1) {
this.mirror = EnumBlockMirror.NONE;
}
try {
this.usageMode = BlockPropertyStructureMode.valueOf(nbttagcompound.getString("mode"));
} catch (IllegalArgumentException illegalargumentexception2) {
this.usageMode = BlockPropertyStructureMode.DATA;
}
this.ignoreEntities = nbttagcompound.getBoolean("ignoreEntities");
this.powered = nbttagcompound.getBoolean("powered");
this.showAir = nbttagcompound.getBoolean("showair");
this.showBoundingBox = nbttagcompound.getBoolean("showboundingbox");
if (nbttagcompound.hasKey("integrity")) {
this.integrity = nbttagcompound.getFloat("integrity");
} else {
this.integrity = 1.0F;
}
this.seed = nbttagcompound.getLong("seed");
this.L();
}
private void L() {
if (this.world != null) {
BlockPosition blockposition = this.getPosition();
IBlockData iblockdata = this.world.getType(blockposition);
if (iblockdata.getBlock() == Blocks.STRUCTURE_BLOCK) {
this.world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockStructure.a, this.usageMode), 2);
}
}
}
@Nullable
@Override
public PacketPlayOutTileEntityData getUpdatePacket() {
return new PacketPlayOutTileEntityData(this.position, 7, this.b());
}
@Override
public NBTTagCompound b() {
return this.save(new NBTTagCompound());
}
public boolean a(EntityHuman entityhuman) {
if (!entityhuman.isCreativeAndOp()) {
return false;
} else {
if (entityhuman.getWorld().isClientSide) {
entityhuman.a(this);
}
return true;
}
}
public String getStructureName() {
return this.structureName == null ? "" : this.structureName.toString();
}
public String f() {
return this.structureName == null ? "" : this.structureName.getKey();
}
public boolean g() {
return this.structureName != null;
}
public void setStructureName(@Nullable String s) {
this.a(UtilColor.b(s) ? null : MinecraftKey.a(s));
}
public void a(@Nullable MinecraftKey minecraftkey) {
this.structureName = minecraftkey;
}
public void setAuthor(EntityLiving entityliving) {
this.author = entityliving.getDisplayName().getString();
}
public BlockPosition h() {
return this.relativePosition;
}
public void b(BlockPosition blockposition) {
this.relativePosition = blockposition;
}
public BlockPosition j() {
return this.size;
}
public void c(BlockPosition blockposition) {
this.size = blockposition;
}
public void b(EnumBlockMirror enumblockmirror) {
this.mirror = enumblockmirror;
}
public void b(EnumBlockRotation enumblockrotation) {
this.rotation = enumblockrotation;
}
public void b(String s) {
this.metadata = s;
}
public BlockPropertyStructureMode getUsageMode() {
return this.usageMode;
}
public void setUsageMode(BlockPropertyStructureMode blockpropertystructuremode) {
this.usageMode = blockpropertystructuremode;
IBlockData iblockdata = this.world.getType(this.getPosition());
if (iblockdata.getBlock() == Blocks.STRUCTURE_BLOCK) {
this.world.setTypeAndData(this.getPosition(), (IBlockData) iblockdata.set(BlockStructure.a, blockpropertystructuremode), 2);
}
}
public void a(boolean flag) {
this.ignoreEntities = flag;
}
public void a(float f) {
this.integrity = f;
}
public void a(long i) {
this.seed = i;
}
public boolean C() {
if (this.usageMode != BlockPropertyStructureMode.SAVE) {
return false;
} else {
BlockPosition blockposition = this.getPosition();
boolean flag = true;
BlockPosition blockposition1 = new BlockPosition(blockposition.getX() - 80, 0, blockposition.getZ() - 80);
BlockPosition blockposition2 = new BlockPosition(blockposition.getX() + 80, 255, blockposition.getZ() + 80);
List<TileEntityStructure> list = this.a(blockposition1, blockposition2);
List<TileEntityStructure> list1 = this.a(list);
if (list1.size() < 1) {
return false;
} else {
StructureBoundingBox structureboundingbox = this.a(blockposition, list1);
if (structureboundingbox.d - structureboundingbox.a > 1 && structureboundingbox.e - structureboundingbox.b > 1 && structureboundingbox.f - structureboundingbox.c > 1) {
this.relativePosition = new BlockPosition(structureboundingbox.a - blockposition.getX() + 1, structureboundingbox.b - blockposition.getY() + 1, structureboundingbox.c - blockposition.getZ() + 1);
this.size = new BlockPosition(structureboundingbox.d - structureboundingbox.a - 1, structureboundingbox.e - structureboundingbox.b - 1, structureboundingbox.f - structureboundingbox.c - 1);
this.update();
IBlockData iblockdata = this.world.getType(blockposition);
this.world.notify(blockposition, iblockdata, iblockdata, 3);
return true;
} else {
return false;
}
}
}
}
private List<TileEntityStructure> a(List<TileEntityStructure> list) {
Predicate<TileEntityStructure> predicate = (tileentitystructure) -> {
return tileentitystructure.usageMode == BlockPropertyStructureMode.CORNER && Objects.equals(this.structureName, tileentitystructure.structureName);
};
return (List) list.stream().filter(predicate).collect(Collectors.toList());
}
private List<TileEntityStructure> a(BlockPosition blockposition, BlockPosition blockposition1) {
List<TileEntityStructure> list = Lists.newArrayList();
Iterator iterator = BlockPosition.a(blockposition, blockposition1).iterator();
while (iterator.hasNext()) {
BlockPosition blockposition2 = (BlockPosition) iterator.next();
IBlockData iblockdata = this.world.getType(blockposition2);
if (iblockdata.getBlock() == Blocks.STRUCTURE_BLOCK) {
TileEntity tileentity = this.world.getTileEntity(blockposition2);
if (tileentity != null && tileentity instanceof TileEntityStructure) {
list.add((TileEntityStructure) tileentity);
}
}
}
return list;
}
private StructureBoundingBox a(BlockPosition blockposition, List<TileEntityStructure> list) {
StructureBoundingBox structureboundingbox;
if (list.size() > 1) {
BlockPosition blockposition1 = ((TileEntityStructure) list.get(0)).getPosition();
structureboundingbox = new StructureBoundingBox(blockposition1, blockposition1);
} else {
structureboundingbox = new StructureBoundingBox(blockposition, blockposition);
}
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
TileEntityStructure tileentitystructure = (TileEntityStructure) iterator.next();
BlockPosition blockposition2 = tileentitystructure.getPosition();
if (blockposition2.getX() < structureboundingbox.a) {
structureboundingbox.a = blockposition2.getX();
} else if (blockposition2.getX() > structureboundingbox.d) {
structureboundingbox.d = blockposition2.getX();
}
if (blockposition2.getY() < structureboundingbox.b) {
structureboundingbox.b = blockposition2.getY();
} else if (blockposition2.getY() > structureboundingbox.e) {
structureboundingbox.e = blockposition2.getY();
}
if (blockposition2.getZ() < structureboundingbox.c) {
structureboundingbox.c = blockposition2.getZ();
} else if (blockposition2.getZ() > structureboundingbox.f) {
structureboundingbox.f = blockposition2.getZ();
}
}
return structureboundingbox;
}
public boolean D() {
return this.b(true);
}
public boolean b(boolean flag) {
if (this.usageMode == BlockPropertyStructureMode.SAVE && !this.world.isClientSide && this.structureName != null) {
BlockPosition blockposition = this.getPosition().a((BaseBlockPosition) this.relativePosition);
WorldServer worldserver = (WorldServer) this.world;
DefinedStructureManager definedstructuremanager = worldserver.r();
DefinedStructure definedstructure;
try {
definedstructure = definedstructuremanager.a(this.structureName);
} catch (ResourceKeyInvalidException resourcekeyinvalidexception) {
return false;
}
definedstructure.a(this.world, blockposition, this.size, !this.ignoreEntities, Blocks.STRUCTURE_VOID);
definedstructure.a(this.author);
if (flag) {
try {
return definedstructuremanager.c(this.structureName);
} catch (ResourceKeyInvalidException resourcekeyinvalidexception1) {
return false;
}
} else {
return true;
}
} else {
return false;
}
}
public boolean E() {
return this.c(true);
}
private static Random b(long i) {
return i == 0L ? new Random(SystemUtils.getMonotonicMillis()) : new Random(i);
}
public boolean c(boolean flag) {
if (this.usageMode == BlockPropertyStructureMode.LOAD && !this.world.isClientSide && this.structureName != null) {
WorldServer worldserver = (WorldServer) this.world;
DefinedStructureManager definedstructuremanager = worldserver.r();
DefinedStructure definedstructure;
try {
definedstructure = definedstructuremanager.b(this.structureName);
} catch (ResourceKeyInvalidException resourcekeyinvalidexception) {
return false;
}
return definedstructure == null ? false : this.a(flag, definedstructure);
} else {
return false;
}
}
public boolean a(boolean flag, DefinedStructure definedstructure) {
BlockPosition blockposition = this.getPosition();
if (!UtilColor.b(definedstructure.b())) {
this.author = definedstructure.b();
}
BlockPosition blockposition1 = definedstructure.a();
boolean flag1 = this.size.equals(blockposition1);
if (!flag1) {
this.size = blockposition1;
this.update();
IBlockData iblockdata = this.world.getType(blockposition);
this.world.notify(blockposition, iblockdata, iblockdata, 3);
}
if (flag && !flag1) {
return false;
} else {
DefinedStructureInfo definedstructureinfo = (new DefinedStructureInfo()).a(this.mirror).a(this.rotation).a(this.ignoreEntities).a((ChunkCoordIntPair) null);
if (this.integrity < 1.0F) {
definedstructureinfo.b().a((DefinedStructureProcessor) (new DefinedStructureProcessorRotation(MathHelper.a(this.integrity, 0.0F, 1.0F)))).a(b(this.seed));
}
BlockPosition blockposition2 = blockposition.a((BaseBlockPosition) this.relativePosition);
definedstructure.a((GeneratorAccess) this.world, blockposition2, definedstructureinfo);
return true;
}
}
public void F() {
if (this.structureName != null) {
WorldServer worldserver = (WorldServer) this.world;
DefinedStructureManager definedstructuremanager = worldserver.r();
definedstructuremanager.d(this.structureName);
}
}
public boolean G() {
if (this.usageMode == BlockPropertyStructureMode.LOAD && !this.world.isClientSide && this.structureName != null) {
WorldServer worldserver = (WorldServer) this.world;
DefinedStructureManager definedstructuremanager = worldserver.r();
try {
return definedstructuremanager.b(this.structureName) != null;
} catch (ResourceKeyInvalidException resourcekeyinvalidexception) {
return false;
}
} else {
return false;
}
}
public boolean H() {
return this.powered;
}
public void d(boolean flag) {
this.powered = flag;
}
public void e(boolean flag) {
this.showAir = flag;
}
public void f(boolean flag) {
this.showBoundingBox = flag;
}
public static enum UpdateType {
UPDATE_DATA, SAVE_AREA, LOAD_AREA, SCAN_AREA;
private UpdateType() {}
}
}