From b272e385566057e93be7f959849997ba1e924486 Mon Sep 17 00:00:00 2001 From: Aether Date: Thu, 17 Oct 2024 19:35:09 -0400 Subject: [PATCH] templates --- .../java/net/minecraft/entity/Entity.java | 45 ++ .../net/minecraft/nbt/NBTTagCompound.java | 15 + .../java/net/minecraft/nbt/NBTTagList.java | 12 + .../java/net/minecraft/util/ChunkPos.java | 128 ++++ .../structure/template/PlacementSettings.java | 146 +++++ .../gen/structure/template/Template.java | 561 ++++++++++++++++++ .../structure/template/TemplateManager.java | 146 +++++ 7 files changed, 1053 insertions(+) create mode 100644 src/game/java/net/minecraft/util/ChunkPos.java create mode 100644 src/game/java/net/minecraft/world/gen/structure/template/PlacementSettings.java create mode 100644 src/game/java/net/minecraft/world/gen/structure/template/Template.java create mode 100644 src/game/java/net/minecraft/world/gen/structure/template/TemplateManager.java diff --git a/src/game/java/net/minecraft/entity/Entity.java b/src/game/java/net/minecraft/entity/Entity.java index b8d93cb..0fc69b1 100644 --- a/src/game/java/net/minecraft/entity/Entity.java +++ b/src/game/java/net/minecraft/entity/Entity.java @@ -49,8 +49,10 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.IChatComponent; import net.minecraft.util.MathHelper; +import net.minecraft.util.Mirror; import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.ReportedException; +import net.minecraft.util.Rotation; import net.minecraft.util.StatCollector; import net.minecraft.util.Vec3; import net.minecraft.world.Explosion; @@ -2655,4 +2657,47 @@ public abstract class Entity implements ICommandSender { } return 0.0f; } + + /** + * Transforms the entity's current yaw with the given Rotation and returns it. This does not have a side-effect. + */ + public float getRotatedYaw(Rotation transformRotation) + { + float f = MathHelper.wrapAngleTo180_float(this.rotationYaw); + + switch (transformRotation) + { + case CLOCKWISE_180: + return f + 180.0F; + + case COUNTERCLOCKWISE_90: + return f + 270.0F; + + case CLOCKWISE_90: + return f + 90.0F; + + default: + return f; + } + } + + /** + * Transforms the entity's current yaw with the given Mirror and returns it. This does not have a side-effect. + */ + public float getMirroredYaw(Mirror transformMirror) + { + float f = MathHelper.wrapAngleTo180_float(this.rotationYaw); + + switch (transformMirror) + { + case LEFT_RIGHT: + return -f; + + case FRONT_BACK: + return 180.0F - f; + + default: + return f; + } + } } \ No newline at end of file diff --git a/src/game/java/net/minecraft/nbt/NBTTagCompound.java b/src/game/java/net/minecraft/nbt/NBTTagCompound.java index 030ffe3..fd7a34a 100644 --- a/src/game/java/net/minecraft/nbt/NBTTagCompound.java +++ b/src/game/java/net/minecraft/nbt/NBTTagCompound.java @@ -8,8 +8,11 @@ import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.Callable; +import javax.annotation.Nullable; + import com.google.common.collect.Maps; +import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID; import net.minecraft.crash.CrashReport; import net.minecraft.crash.CrashReportCategory; import net.minecraft.util.ReportedException; @@ -131,6 +134,18 @@ public class NBTTagCompound extends NBTBase { public void setInteger(String key, int value) { this.tagMap.put(key, new NBTTagInt(value)); } + + public void setUniqueId(String key, EaglercraftUUID value) + { + this.setLong(key + "Most", value.getMostSignificantBits()); + this.setLong(key + "Least", value.getLeastSignificantBits()); + } + + @Nullable + public EaglercraftUUID getUniqueId(String key) + { + return new EaglercraftUUID(this.getLong(key + "Most"), this.getLong(key + "Least")); + } /** * + diff --git a/src/game/java/net/minecraft/nbt/NBTTagList.java b/src/game/java/net/minecraft/nbt/NBTTagList.java index a265285..00945e3 100644 --- a/src/game/java/net/minecraft/nbt/NBTTagList.java +++ b/src/game/java/net/minecraft/nbt/NBTTagList.java @@ -191,6 +191,18 @@ public class NBTTagList extends NBTBase { } } + public int getIntAt(int p_186858_1_) { + if (p_186858_1_ >= 0 && p_186858_1_ < this.tagList.size()) { + NBTBase nbtbase = (NBTBase) this.tagList.get(p_186858_1_); + + if (nbtbase.getId() == 3) { + return ((NBTTagInt) nbtbase).getInt(); + } + } + + return 0; + } + public int[] getIntArrayAt(int i) { if (i >= 0 && i < this.tagList.size()) { NBTBase nbtbase = (NBTBase) this.tagList.get(i); diff --git a/src/game/java/net/minecraft/util/ChunkPos.java b/src/game/java/net/minecraft/util/ChunkPos.java new file mode 100644 index 0000000..07a8392 --- /dev/null +++ b/src/game/java/net/minecraft/util/ChunkPos.java @@ -0,0 +1,128 @@ +package net.minecraft.util; + +import net.minecraft.entity.Entity; + +public class ChunkPos +{ + /** The X position of this Chunk Coordinate Pair */ + public final int chunkXPos; + + /** The Z position of this Chunk Coordinate Pair */ + public final int chunkZPos; + + public ChunkPos(int x, int z) + { + this.chunkXPos = x; + this.chunkZPos = z; + } + + public ChunkPos(BlockPos pos) + { + this.chunkXPos = pos.getX() >> 4; + this.chunkZPos = pos.getZ() >> 4; + } + + /** + * converts a chunk coordinate pair to an integer (suitable for hashing) + */ + public static long chunkXZ2Int(int x, int z) + { + return (long)x & 4294967295L | ((long)z & 4294967295L) << 32; + } + + public int hashCode() + { + int i = 1664525 * this.chunkXPos + 1013904223; + int j = 1664525 * (this.chunkZPos ^ -559038737) + 1013904223; + return i ^ j; + } + + public boolean equals(Object p_equals_1_) + { + if (this == p_equals_1_) + { + return true; + } + else if (!(p_equals_1_ instanceof ChunkPos)) + { + return false; + } + else + { + ChunkPos chunkpos = (ChunkPos)p_equals_1_; + return this.chunkXPos == chunkpos.chunkXPos && this.chunkZPos == chunkpos.chunkZPos; + } + } + + public double getDistanceSq(Entity p_185327_1_) + { + double d0 = (double)(this.chunkXPos * 16 + 8); + double d1 = (double)(this.chunkZPos * 16 + 8); + double d2 = d0 - p_185327_1_.posX; + double d3 = d1 - p_185327_1_.posZ; + return d2 * d2 + d3 * d3; + } + + public int getCenterXPos() + { + return (this.chunkXPos << 4) + 8; + } + + public int getCenterZPosition() + { + return (this.chunkZPos << 4) + 8; + } + + /** + * Get the first world X coordinate that belongs to this Chunk + */ + public int getXStart() + { + return this.chunkXPos << 4; + } + + /** + * Get the first world Z coordinate that belongs to this Chunk + */ + public int getZStart() + { + return this.chunkZPos << 4; + } + + /** + * Get the last world X coordinate that belongs to this Chunk + */ + public int getXEnd() + { + return (this.chunkXPos << 4) + 15; + } + + /** + * Get the last world Z coordinate that belongs to this Chunk + */ + public int getZEnd() + { + return (this.chunkZPos << 4) + 15; + } + + /** + * Get the World coordinates of the Block with the given Chunk coordinates relative to this chunk + */ + public BlockPos getBlock(int x, int y, int z) + { + return new BlockPos((this.chunkXPos << 4) + x, y, (this.chunkZPos << 4) + z); + } + + /** + * Get the coordinates of the Block in the center of this chunk with the given Y coordinate + */ + public BlockPos getCenterBlock(int y) + { + return new BlockPos(this.getCenterXPos(), y, this.getCenterZPosition()); + } + + public String toString() + { + return "[" + this.chunkXPos + ", " + this.chunkZPos + "]"; + } +} diff --git a/src/game/java/net/minecraft/world/gen/structure/template/PlacementSettings.java b/src/game/java/net/minecraft/world/gen/structure/template/PlacementSettings.java new file mode 100644 index 0000000..47a51bf --- /dev/null +++ b/src/game/java/net/minecraft/world/gen/structure/template/PlacementSettings.java @@ -0,0 +1,146 @@ +package net.minecraft.world.gen.structure.template; + +import javax.annotation.Nullable; +import net.minecraft.block.Block; +import net.minecraft.util.Mirror; +import net.minecraft.util.Rotation; +import net.minecraft.util.ChunkPos; +import net.minecraft.world.gen.structure.StructureBoundingBox; + +public class PlacementSettings +{ + private Mirror mirror; + private Rotation rotation; + private boolean ignoreEntities; + + /** + * the type of block in the world that will get replaced by the structure + */ + private Block replacedBlock; + + /** the chunk the structure is within */ + private ChunkPos chunk; + + /** the bounds the structure is contained within */ + private StructureBoundingBox boundingBox; + private boolean ignoreStructureBlock; + + public PlacementSettings() + { + this(Mirror.NONE, Rotation.NONE, false, (Block)null, (StructureBoundingBox)null); + } + + public PlacementSettings(Mirror mirrorIn, Rotation rotationIn, boolean ignoreEntitiesIn, @Nullable Block replacedBlockIn, @Nullable StructureBoundingBox boundingBoxIn) + { + this.rotation = rotationIn; + this.mirror = mirrorIn; + this.ignoreEntities = ignoreEntitiesIn; + this.replacedBlock = replacedBlockIn; + this.chunk = null; + this.boundingBox = boundingBoxIn; + this.ignoreStructureBlock = true; + } + + public PlacementSettings copy() + { + return (new PlacementSettings(this.mirror, this.rotation, this.ignoreEntities, this.replacedBlock, this.boundingBox)).setChunk(this.chunk).setIgnoreStructureBlock(this.ignoreStructureBlock); + } + + public PlacementSettings setMirror(Mirror mirrorIn) + { + this.mirror = mirrorIn; + return this; + } + + public PlacementSettings setRotation(Rotation rotationIn) + { + this.rotation = rotationIn; + return this; + } + + public PlacementSettings setIgnoreEntities(boolean ignoreEntitiesIn) + { + this.ignoreEntities = ignoreEntitiesIn; + return this; + } + + public PlacementSettings setReplacedBlock(Block replacedBlockIn) + { + this.replacedBlock = replacedBlockIn; + return this; + } + + public PlacementSettings setChunk(ChunkPos chunkPosIn) + { + this.chunk = chunkPosIn; + return this; + } + + public PlacementSettings setBoundingBox(StructureBoundingBox boundingBoxIn) + { + this.boundingBox = boundingBoxIn; + return this; + } + + public Mirror getMirror() + { + return this.mirror; + } + + public PlacementSettings setIgnoreStructureBlock(boolean ignoreStructureBlockIn) + { + this.ignoreStructureBlock = ignoreStructureBlockIn; + return this; + } + + public Rotation getRotation() + { + return this.rotation; + } + + public boolean getIgnoreEntities() + { + return this.ignoreEntities; + } + + public Block getReplacedBlock() + { + return this.replacedBlock; + } + + @Nullable + public StructureBoundingBox getBoundingBox() + { + if (this.boundingBox == null && this.chunk != null) + { + this.setBoundingBoxFromChunk(); + } + + return this.boundingBox; + } + + public boolean getIgnoreStructureBlock() + { + return this.ignoreStructureBlock; + } + + void setBoundingBoxFromChunk() + { + this.boundingBox = this.getBoundingBoxFromChunk(this.chunk); + } + + @Nullable + private StructureBoundingBox getBoundingBoxFromChunk(@Nullable ChunkPos pos) + { + if (pos == null) + { + return null; + } + else + { + int i = pos.chunkXPos * 16; + int j = pos.chunkZPos * 16; + return new StructureBoundingBox(i, 0, j, i + 16 - 1, 255, j + 16 - 1); + } + } +} diff --git a/src/game/java/net/minecraft/world/gen/structure/template/Template.java b/src/game/java/net/minecraft/world/gen/structure/template/Template.java new file mode 100644 index 0000000..b62dce0 --- /dev/null +++ b/src/game/java/net/minecraft/world/gen/structure/template/Template.java @@ -0,0 +1,561 @@ +package net.minecraft.world.gen.structure.template; + +import com.google.common.base.Predicate; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import java.util.List; +import java.util.Map; +import javax.annotation.Nullable; + +import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.item.EntityPainting; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.IInventory; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagDouble; +import net.minecraft.nbt.NBTTagInt; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Mirror; +import net.minecraft.util.Rotation; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.BlockPos; +import net.minecraft.util.Vec3; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; + +public class Template +{ + private final List blocks = Lists.newArrayList(); + private final List entities = Lists.newArrayList(); + + /** size of the structure */ + private BlockPos size = BlockPos.ORIGIN; + + /** The author of this template. */ + private String author = "?"; + + public BlockPos getSize() + { + return this.size; + } + + public void setAuthor(String authorIn) + { + this.author = authorIn; + } + + public String getAuthor() + { + return this.author; + } + + /** + * takes blocks from the world and puts the data them into this template + */ + public void takeBlocksFromWorld(World worldIn, BlockPos startPos, BlockPos endPos, boolean takeEntities, @Nullable Block p_186254_5_) + { + if (endPos.getX() >= 1 && endPos.getY() >= 1 && endPos.getZ() >= 1) + { + BlockPos blockpos = startPos.add(endPos).add(-1, -1, -1); + List list = Lists.newArrayList(); + List list1 = Lists.newArrayList(); + List list2 = Lists.newArrayList(); + BlockPos blockpos1 = new BlockPos(Math.min(startPos.getX(), blockpos.getX()), Math.min(startPos.getY(), blockpos.getY()), Math.min(startPos.getZ(), blockpos.getZ())); + BlockPos blockpos2 = new BlockPos(Math.max(startPos.getX(), blockpos.getX()), Math.max(startPos.getY(), blockpos.getY()), Math.max(startPos.getZ(), blockpos.getZ())); + this.size = endPos; + + for (BlockPos.MutableBlockPos blockpos$mutableblockpos : BlockPos.getAllInBoxMutable(blockpos1, blockpos2)) + { + BlockPos blockpos3 = blockpos$mutableblockpos.subtract(blockpos1); + IBlockState iblockstate = worldIn.getBlockState(blockpos$mutableblockpos); + + if (p_186254_5_ == null || p_186254_5_ != iblockstate.getBlock()) + { + TileEntity tileentity = worldIn.getTileEntity(blockpos$mutableblockpos); + + if (tileentity != null) + { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + tileentity.writeToNBT(nbttagcompound); + nbttagcompound.removeTag("x"); + nbttagcompound.removeTag("y"); + nbttagcompound.removeTag("z"); + list1.add(new Template.BlockInfo(blockpos3, iblockstate, nbttagcompound)); + } + else if (!iblockstate.isFullBlock() && !iblockstate.isFullCube()) + { + list2.add(new Template.BlockInfo(blockpos3, iblockstate, (NBTTagCompound)null)); + } + else + { + list.add(new Template.BlockInfo(blockpos3, iblockstate, (NBTTagCompound)null)); + } + } + } + + this.blocks.clear(); + this.blocks.addAll(list); + this.blocks.addAll(list1); + this.blocks.addAll(list2); + + if (takeEntities) + { + this.takeEntitiesFromWorld(worldIn, blockpos1, blockpos2.add(1, 1, 1)); + } + else + { + this.entities.clear(); + } + } + } + + /** + * takes blocks from the world and puts the data them into this template + */ + private void takeEntitiesFromWorld(World worldIn, BlockPos startPos, BlockPos endPos) + { + List list = worldIn.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(startPos, endPos), new Predicate() + { + public boolean apply(@Nullable Entity p_apply_1_) + { + return !(p_apply_1_ instanceof EntityPlayer); + } + }); + this.entities.clear(); + + for (Entity entity : list) + { + Vec3 vec3d = new Vec3(entity.posX - (double)startPos.getX(), entity.posY - (double)startPos.getY(), entity.posZ - (double)startPos.getZ()); + NBTTagCompound nbttagcompound = new NBTTagCompound(); + entity.writeToNBTOptional(nbttagcompound); + BlockPos blockpos; + + if (entity instanceof EntityPainting) + { + blockpos = ((EntityPainting)entity).getHangingPosition().subtract(startPos); + } + else + { + blockpos = new BlockPos(vec3d); + } + + this.entities.add(new Template.EntityInfo(vec3d, blockpos, nbttagcompound)); + } + } + + public Map getDataBlocks(BlockPos pos, PlacementSettings placementIn) + { + Map map = Maps.newHashMap(); + StructureBoundingBox structureboundingbox = placementIn.getBoundingBox(); + + for (Template.BlockInfo template$blockinfo : this.blocks) + { + BlockPos blockpos = transformedBlockPos(placementIn, template$blockinfo.pos).add(pos); + + if (structureboundingbox == null || structureboundingbox.isVecInside(blockpos)) + { + IBlockState iblockstate = template$blockinfo.blockState; + + // if (iblockstate.getBlock() == Blocks.STRUCTURE_BLOCK && template$blockinfo.tileentityData != null) + // { + // TileEntityStructure.Mode tileentitystructure$mode = TileEntityStructure.Mode.valueOf(template$blockinfo.tileentityData.getString("mode")); + + // if (tileentitystructure$mode == TileEntityStructure.Mode.DATA) + // { + // map.put(blockpos, template$blockinfo.tileentityData.getString("metadata")); + // } + // } + } + } + + return map; + } + + public BlockPos calculateConnectedPos(PlacementSettings placementIn, BlockPos p_186262_2_, PlacementSettings p_186262_3_, BlockPos p_186262_4_) + { + BlockPos blockpos = transformedBlockPos(placementIn, p_186262_2_); + BlockPos blockpos1 = transformedBlockPos(p_186262_3_, p_186262_4_); + return blockpos.subtract(blockpos1); + } + + public static BlockPos transformedBlockPos(PlacementSettings placementIn, BlockPos p_186266_1_) + { + return transformedBlockPos(p_186266_1_, placementIn.getMirror(), placementIn.getRotation()); + } + + public void addBlocksToWorldChunk(World worldIn, BlockPos pos, PlacementSettings placementIn) + { + placementIn.setBoundingBoxFromChunk(); + this.addBlocksToWorld(worldIn, pos, placementIn); + } + + /** + * This takes the data stored in this instance and puts them into the world. + */ + public void addBlocksToWorld(World worldIn, BlockPos pos, PlacementSettings placementIn) + { + if (!this.blocks.isEmpty() && this.size.getX() >= 1 && this.size.getY() >= 1 && this.size.getZ() >= 1) + { + Block block = placementIn.getReplacedBlock(); + StructureBoundingBox structureboundingbox = placementIn.getBoundingBox(); + + for (Template.BlockInfo template$blockinfo : this.blocks) + { + Block block1 = template$blockinfo.blockState.getBlock(); + + if ((block == null || block != block1) && (!placementIn.getIgnoreStructureBlock())) + { + BlockPos blockpos = transformedBlockPos(placementIn, template$blockinfo.pos).add(pos); + + if (structureboundingbox == null || structureboundingbox.isVecInside(blockpos)) + { + IBlockState iblockstate = template$blockinfo.blockState.withMirror(placementIn.getMirror()); + IBlockState iblockstate1 = iblockstate.withRotation(placementIn.getRotation()); + + if (template$blockinfo.tileentityData != null) + { + TileEntity tileentity = worldIn.getTileEntity(blockpos); + + if (tileentity != null) + { + if (tileentity instanceof IInventory) + { + ((IInventory)tileentity).clear(); + } + + worldIn.setBlockState(blockpos, Blocks.barrier.getDefaultState(), 4); + } + } + + if (worldIn.setBlockState(blockpos, iblockstate1, 2) && template$blockinfo.tileentityData != null) + { + TileEntity tileentity2 = worldIn.getTileEntity(blockpos); + + if (tileentity2 != null) + { + template$blockinfo.tileentityData.setInteger("x", blockpos.getX()); + template$blockinfo.tileentityData.setInteger("y", blockpos.getY()); + template$blockinfo.tileentityData.setInteger("z", blockpos.getZ()); + tileentity2.readFromNBT(template$blockinfo.tileentityData); + } + } + } + } + } + + for (Template.BlockInfo template$blockinfo1 : this.blocks) + { + if (block == null || block != template$blockinfo1.blockState.getBlock()) + { + BlockPos blockpos1 = transformedBlockPos(placementIn, template$blockinfo1.pos).add(pos); + + if (structureboundingbox == null || structureboundingbox.isVecInside(blockpos1)) + { + worldIn.notifyNeighborsRespectDebug(blockpos1, template$blockinfo1.blockState.getBlock()); + + if (template$blockinfo1.tileentityData != null) + { + TileEntity tileentity1 = worldIn.getTileEntity(blockpos1); + + if (tileentity1 != null) + { + tileentity1.markDirty(); + } + } + } + } + } + + if (!placementIn.getIgnoreEntities()) + { + this.addEntitiesToWorld(worldIn, pos, placementIn.getMirror(), placementIn.getRotation(), structureboundingbox); + } + } + } + + private void addEntitiesToWorld(World worldIn, BlockPos pos, Mirror mirrorIn, Rotation rotationIn, @Nullable StructureBoundingBox aabb) + { + for (Template.EntityInfo template$entityinfo : this.entities) + { + BlockPos blockpos = transformedBlockPos(template$entityinfo.blockPos, mirrorIn, rotationIn).add(pos); + + if (aabb == null || aabb.isVecInside(blockpos)) + { + NBTTagCompound nbttagcompound = template$entityinfo.entityData; + Vec3 vec3d = transformedVec3d(template$entityinfo.pos, mirrorIn, rotationIn); + Vec3 vec3d1 = vec3d.addVector((double)pos.getX(), (double)pos.getY(), (double)pos.getZ()); + NBTTagList nbttaglist = new NBTTagList(); + nbttaglist.appendTag(new NBTTagDouble(vec3d1.xCoord)); + nbttaglist.appendTag(new NBTTagDouble(vec3d1.yCoord)); + nbttaglist.appendTag(new NBTTagDouble(vec3d1.zCoord)); + nbttagcompound.setTag("Pos", nbttaglist); + nbttagcompound.setUniqueId("UUID", EaglercraftUUID.randomUUID()); + Entity entity; + + try + { + entity = EntityList.createEntityFromNBT(nbttagcompound, worldIn); + } + catch (Exception var15) + { + entity = null; + } + + if (entity != null) + { + if (entity instanceof EntityPainting) + { + entity.getMirroredYaw(mirrorIn); + entity.getRotatedYaw(rotationIn); + entity.setPosition((double)blockpos.getX(), (double)blockpos.getY(), (double)blockpos.getZ()); + entity.setLocationAndAngles(vec3d1.xCoord, vec3d1.yCoord, vec3d1.zCoord, entity.rotationYaw, entity.rotationPitch); + } + else + { + float f = entity.getMirroredYaw(mirrorIn); + f = f + (entity.rotationYaw - entity.getRotatedYaw(rotationIn)); + entity.setLocationAndAngles(vec3d1.xCoord, vec3d1.yCoord, vec3d1.zCoord, f, entity.rotationPitch); + } + + worldIn.spawnEntityInWorld(entity); + } + } + } + } + + public BlockPos transformedSize(Rotation rotationIn) + { + switch (rotationIn) + { + case COUNTERCLOCKWISE_90: + case CLOCKWISE_90: + return new BlockPos(this.size.getZ(), this.size.getY(), this.size.getX()); + + default: + return this.size; + } + } + + private static BlockPos transformedBlockPos(BlockPos pos, Mirror mirrorIn, Rotation rotationIn) + { + int i = pos.getX(); + int j = pos.getY(); + int k = pos.getZ(); + boolean flag = true; + + switch (mirrorIn) + { + case LEFT_RIGHT: + k = -k; + break; + + case FRONT_BACK: + i = -i; + break; + + default: + flag = false; + } + + switch (rotationIn) + { + case COUNTERCLOCKWISE_90: + return new BlockPos(k, j, -i); + + case CLOCKWISE_90: + return new BlockPos(-k, j, i); + + case CLOCKWISE_180: + return new BlockPos(-i, j, -k); + + default: + return flag ? new BlockPos(i, j, k) : pos; + } + } + + private static Vec3 transformedVec3d(Vec3 vec, Mirror mirrorIn, Rotation rotationIn) + { + double d0 = vec.xCoord; + double d1 = vec.yCoord; + double d2 = vec.zCoord; + boolean flag = true; + + switch (mirrorIn) + { + case LEFT_RIGHT: + d2 = 1.0D - d2; + break; + + case FRONT_BACK: + d0 = 1.0D - d0; + break; + + default: + flag = false; + } + + switch (rotationIn) + { + case COUNTERCLOCKWISE_90: + return new Vec3(d2, d1, 1.0D - d0); + + case CLOCKWISE_90: + return new Vec3(1.0D - d2, d1, d0); + + case CLOCKWISE_180: + return new Vec3(1.0D - d0, d1, 1.0D - d2); + + default: + return flag ? new Vec3(d0, d1, d2) : vec; + } + } + + public NBTTagCompound func_189552_a(NBTTagCompound p_189552_1_) + { + NBTTagList nbttaglist = new NBTTagList(); + + for (Template.BlockInfo template$blockinfo : this.blocks) + { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + nbttagcompound.setTag("pos", this.writeInts(new int[] {template$blockinfo.pos.getX(), template$blockinfo.pos.getY(), template$blockinfo.pos.getZ()})); + nbttagcompound.setInteger("state", Block.getStateId(template$blockinfo.blockState)); + + if (template$blockinfo.tileentityData != null) + { + nbttagcompound.setTag("nbt", template$blockinfo.tileentityData); + } + + nbttaglist.appendTag(nbttagcompound); + } + + NBTTagList nbttaglist1 = new NBTTagList(); + + for (Template.EntityInfo template$entityinfo : this.entities) + { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setTag("pos", this.writeDoubles(new double[] {template$entityinfo.pos.xCoord, template$entityinfo.pos.yCoord, template$entityinfo.pos.zCoord})); + nbttagcompound1.setTag("blockPos", this.writeInts(new int[] {template$entityinfo.blockPos.getX(), template$entityinfo.blockPos.getY(), template$entityinfo.blockPos.getZ()})); + + if (template$entityinfo.entityData != null) + { + nbttagcompound1.setTag("nbt", template$entityinfo.entityData); + } + + nbttaglist1.appendTag(nbttagcompound1); + } + + p_189552_1_.setTag("blocks", nbttaglist); + p_189552_1_.setTag("entities", nbttaglist1); + p_189552_1_.setTag("size", this.writeInts(new int[] {this.size.getX(), this.size.getY(), this.size.getZ()})); + p_189552_1_.setInteger("version", 1); + p_189552_1_.setString("author", this.author); + return p_189552_1_; + } + + public void read(NBTTagCompound compound) + { + this.blocks.clear(); + this.entities.clear(); + NBTTagList nbttaglist = compound.getTagList("size", 3); + this.size = new BlockPos(nbttaglist.getIntAt(0), nbttaglist.getIntAt(1), nbttaglist.getIntAt(2)); + this.author = compound.getString("author"); + NBTTagList nbttaglist1 = compound.getTagList("blocks", 10); + + for (int i = 0; i < nbttaglist1.tagCount(); ++i) + { + NBTTagCompound nbttagcompound = nbttaglist1.getCompoundTagAt(i); + NBTTagList nbttaglist2 = nbttagcompound.getTagList("pos", 3); + BlockPos blockpos = new BlockPos(nbttaglist2.getIntAt(0), nbttaglist2.getIntAt(1), nbttaglist2.getIntAt(2)); + int j = nbttagcompound.getInteger("state"); + IBlockState iblockstate = Block.getStateById(j); + NBTTagCompound nbttagcompound1; + + if (nbttagcompound.hasKey("nbt")) + { + nbttagcompound1 = nbttagcompound.getCompoundTag("nbt"); + } + else + { + nbttagcompound1 = null; + } + + this.blocks.add(new Template.BlockInfo(blockpos, iblockstate, nbttagcompound1)); + } + + NBTTagList nbttaglist3 = compound.getTagList("entities", 10); + + for (int k = 0; k < nbttaglist3.tagCount(); ++k) + { + NBTTagCompound nbttagcompound3 = nbttaglist3.getCompoundTagAt(k); + NBTTagList nbttaglist4 = nbttagcompound3.getTagList("pos", 6); + Vec3 vec3d = new Vec3(nbttaglist4.getDoubleAt(0), nbttaglist4.getDoubleAt(1), nbttaglist4.getDoubleAt(2)); + NBTTagList nbttaglist5 = nbttagcompound3.getTagList("blockPos", 3); + BlockPos blockpos1 = new BlockPos(nbttaglist5.getIntAt(0), nbttaglist5.getIntAt(1), nbttaglist5.getIntAt(2)); + + if (nbttagcompound3.hasKey("nbt")) + { + NBTTagCompound nbttagcompound2 = nbttagcompound3.getCompoundTag("nbt"); + this.entities.add(new Template.EntityInfo(vec3d, blockpos1, nbttagcompound2)); + } + } + } + + private NBTTagList writeInts(int... values) + { + NBTTagList nbttaglist = new NBTTagList(); + + for (int i : values) + { + nbttaglist.appendTag(new NBTTagInt(i)); + } + + return nbttaglist; + } + + private NBTTagList writeDoubles(double... values) + { + NBTTagList nbttaglist = new NBTTagList(); + + for (double d0 : values) + { + nbttaglist.appendTag(new NBTTagDouble(d0)); + } + + return nbttaglist; + } + + static class BlockInfo + { + public final BlockPos pos; + public final IBlockState blockState; + public final NBTTagCompound tileentityData; + + private BlockInfo(BlockPos posIn, IBlockState stateIn, @Nullable NBTTagCompound compoundIn) + { + this.pos = posIn; + this.blockState = stateIn; + this.tileentityData = compoundIn; + } + } + + static class EntityInfo + { + public final Vec3 pos; + public final BlockPos blockPos; + public final NBTTagCompound entityData; + + private EntityInfo(Vec3 vecIn, BlockPos posIn, NBTTagCompound compoundIn) + { + this.pos = vecIn; + this.blockPos = posIn; + this.entityData = compoundIn; + } + } +} diff --git a/src/game/java/net/minecraft/world/gen/structure/template/TemplateManager.java b/src/game/java/net/minecraft/world/gen/structure/template/TemplateManager.java new file mode 100644 index 0000000..d80b8f5 --- /dev/null +++ b/src/game/java/net/minecraft/world/gen/structure/template/TemplateManager.java @@ -0,0 +1,146 @@ +package net.minecraft.world.gen.structure.template; + +import com.google.common.collect.Maps; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import javax.annotation.Nullable; + +import net.hoosiertransfer.ServerAssets; +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ResourceLocation; +import org.apache.commons.io.IOUtils; + +public class TemplateManager +{ + private final Map templates; + + /** + * the folder in the assets folder where the structure templates are found. + */ + private final String baseFolder; + + public TemplateManager() + { + this("structures"); + } + + public TemplateManager(String basefolderIn) + { + this.templates = Maps.newHashMap(); + this.baseFolder = basefolderIn; + } + + public Template getTemplate(@Nullable MinecraftServer server, ResourceLocation id) + { + String s = id.getResourcePath(); + + if (this.templates.containsKey(s)) + { + return (Template)this.templates.get(s); + } + else + { + if (server != null) + { + this.readTemplate(server, id); + } + else + { + this.readTemplateFromJar(id); + } + + if (this.templates.containsKey(s)) + { + return (Template)this.templates.get(s); + } + else + { + Template template = new Template(); + this.templates.put(s, template); + return template; + } + } + } + + /** + * This reads a structure template from the given location and stores it. + * This first attempts get the template from an external folder. + * If it isn't there then it attempts to take it from the minecraft jar. + */ + public boolean readTemplate(MinecraftServer server, ResourceLocation id) + { + // String s = id.getResourcePath(); + // File file1 = server.getFile(this.baseFolder); + // File file2 = new File(file1, s + ".nbt"); + + // if (!file2.exists()) + // { + return this.readTemplateFromJar(id); + // } + // else + // { + // InputStream inputstream = null; + // boolean flag; + + // try + // { + // inputstream = new FileInputStream(file2); + // this.readTemplateFromStream(s, inputstream); + // return true; + // } + // catch (Throwable var12) + // { + // flag = false; + // } + // finally + // { + // IOUtils.closeQuietly(inputstream); + // } + + // return flag; + // } + } + + /** + * reads a template from the minecraft jar + */ + private boolean readTemplateFromJar(ResourceLocation id) + { + String s = id.getResourceDomain(); + String s1 = id.getResourcePath(); + InputStream inputstream = null; + boolean flag; + + try + { + // inputstream = MinecraftServer.class.getResourceAsStream("/assets/" + s + "/structures/" + s1 + ".nbt"); + inputstream = ServerAssets.getAssetStream("/assets/" + s + "/structures/" + s1 + ".nbt"); + this.readTemplateFromStream(s1, inputstream); + return true; + } + catch (Throwable var10) + { + flag = false; + } + finally + { + IOUtils.closeQuietly(inputstream); + } + + return flag; + } + + /** + * reads a template from an inputstream + */ + private void readTemplateFromStream(String id, InputStream stream) throws IOException + { + NBTTagCompound nbttagcompound = CompressedStreamTools.readCompressed(stream); + Template template = new Template(); + template.read(nbttagcompound); + this.templates.put(id, template); + } +}