Skip to content

Instantly share code, notes, and snippets.

@Lanse505
Last active May 20, 2020 17:08
Show Gist options
  • Save Lanse505/9a9345980c48b342507a005fc68d2d51 to your computer and use it in GitHub Desktop.
Save Lanse505/9a9345980c48b342507a005fc68d2d51 to your computer and use it in GitHub Desktop.
package net.minecraft.world.gen.feature.structure;
import com.google.common.collect.Lists;
import java.util.List;
import java.util.Random;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.ItemFrameEntity;
import net.minecraft.entity.monster.ShulkerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.LockableLootTileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Rotation;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MutableBoundingBox;
import net.minecraft.world.IWorld;
import net.minecraft.world.gen.feature.template.BlockIgnoreStructureProcessor;
import net.minecraft.world.gen.feature.template.PlacementSettings;
import net.minecraft.world.gen.feature.template.Template;
import net.minecraft.world.gen.feature.template.TemplateManager;
import net.minecraft.world.storage.loot.LootTables;
public class EndCityPieces {
private static final PlacementSettings OVERWRITE = (new PlacementSettings()).setIgnoreEntities(true).addProcessor(BlockIgnoreStructureProcessor.STRUCTURE_BLOCK);
private static final PlacementSettings INSERT = (new PlacementSettings()).setIgnoreEntities(true).addProcessor(BlockIgnoreStructureProcessor.AIR_AND_STRUCTURE_BLOCK);
private static final EndCityPieces.IGenerator HOUSE_TOWER_GENERATOR = new EndCityPieces.IGenerator() {
public void init() {
}
public boolean generate(TemplateManager p_191086_1_, int p_191086_2_, EndCityPieces.CityTemplate p_191086_3_, BlockPos p_191086_4_, List<StructurePiece> p_191086_5_, Random p_191086_6_) {
if (p_191086_2_ > 8) {
return false;
} else {
Rotation rotation = p_191086_3_.placeSettings.getRotation();
EndCityPieces.CityTemplate endcitypieces$citytemplate = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, p_191086_3_, p_191086_4_, "base_floor", rotation, true));
int i = p_191086_6_.nextInt(3);
if (i == 0) {
EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, endcitypieces$citytemplate, new BlockPos(-1, 4, -1), "base_roof", rotation, true));
} else if (i == 1) {
endcitypieces$citytemplate = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, endcitypieces$citytemplate, new BlockPos(-1, 0, -1), "second_floor_2", rotation, false));
endcitypieces$citytemplate = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, endcitypieces$citytemplate, new BlockPos(-1, 8, -1), "second_roof", rotation, false));
EndCityPieces.recursiveChildren(p_191086_1_, EndCityPieces.TOWER_GENERATOR, p_191086_2_ + 1, endcitypieces$citytemplate, (BlockPos)null, p_191086_5_, p_191086_6_);
} else if (i == 2) {
endcitypieces$citytemplate = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, endcitypieces$citytemplate, new BlockPos(-1, 0, -1), "second_floor_2", rotation, false));
endcitypieces$citytemplate = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, endcitypieces$citytemplate, new BlockPos(-1, 4, -1), "third_floor_2", rotation, false));
endcitypieces$citytemplate = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, endcitypieces$citytemplate, new BlockPos(-1, 8, -1), "third_roof", rotation, true));
EndCityPieces.recursiveChildren(p_191086_1_, EndCityPieces.TOWER_GENERATOR, p_191086_2_ + 1, endcitypieces$citytemplate, (BlockPos)null, p_191086_5_, p_191086_6_);
}
return true;
}
}
};
private static final List<Tuple<Rotation, BlockPos>> TOWER_BRIDGES = Lists.newArrayList(new Tuple<>(Rotation.NONE, new BlockPos(1, -1, 0)), new Tuple<>(Rotation.CLOCKWISE_90, new BlockPos(6, -1, 1)), new Tuple<>(Rotation.COUNTERCLOCKWISE_90, new BlockPos(0, -1, 5)), new Tuple<>(Rotation.CLOCKWISE_180, new BlockPos(5, -1, 6)));
private static final EndCityPieces.IGenerator TOWER_GENERATOR = new EndCityPieces.IGenerator() {
public void init() {
}
public boolean generate(TemplateManager p_191086_1_, int p_191086_2_, EndCityPieces.CityTemplate p_191086_3_, BlockPos p_191086_4_, List<StructurePiece> p_191086_5_, Random p_191086_6_) {
Rotation rotation = p_191086_3_.placeSettings.getRotation();
EndCityPieces.CityTemplate lvt_8_1_ = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, p_191086_3_, new BlockPos(3 + p_191086_6_.nextInt(2), -3, 3 + p_191086_6_.nextInt(2)), "tower_base", rotation, true));
lvt_8_1_ = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, lvt_8_1_, new BlockPos(0, 7, 0), "tower_piece", rotation, true));
EndCityPieces.CityTemplate endcitypieces$citytemplate1 = p_191086_6_.nextInt(3) == 0 ? lvt_8_1_ : null;
int i = 1 + p_191086_6_.nextInt(3);
for(int j = 0; j < i; ++j) {
lvt_8_1_ = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, lvt_8_1_, new BlockPos(0, 4, 0), "tower_piece", rotation, true));
if (j < i - 1 && p_191086_6_.nextBoolean()) {
endcitypieces$citytemplate1 = lvt_8_1_;
}
}
if (endcitypieces$citytemplate1 != null) {
for(Tuple<Rotation, BlockPos> tuple : EndCityPieces.TOWER_BRIDGES) {
if (p_191086_6_.nextBoolean()) {
EndCityPieces.CityTemplate endcitypieces$citytemplate2 = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, endcitypieces$citytemplate1, tuple.getB(), "bridge_end", rotation.add(tuple.getA()), true));
EndCityPieces.recursiveChildren(p_191086_1_, EndCityPieces.TOWER_BRIDGE_GENERATOR, p_191086_2_ + 1, endcitypieces$citytemplate2, (BlockPos)null, p_191086_5_, p_191086_6_);
}
}
EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, lvt_8_1_, new BlockPos(-1, 4, -1), "tower_top", rotation, true));
} else {
if (p_191086_2_ != 7) {
return EndCityPieces.recursiveChildren(p_191086_1_, EndCityPieces.FAT_TOWER_GENERATOR, p_191086_2_ + 1, lvt_8_1_, (BlockPos)null, p_191086_5_, p_191086_6_);
}
EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, lvt_8_1_, new BlockPos(-1, 4, -1), "tower_top", rotation, true));
}
return true;
}
};
private static final EndCityPieces.IGenerator TOWER_BRIDGE_GENERATOR = new EndCityPieces.IGenerator() {
public boolean shipCreated;
public void init() {
this.shipCreated = false;
}
public boolean generate(TemplateManager p_191086_1_, int p_191086_2_, EndCityPieces.CityTemplate p_191086_3_, BlockPos p_191086_4_, List<StructurePiece> p_191086_5_, Random p_191086_6_) {
Rotation rotation = p_191086_3_.placeSettings.getRotation();
int i = p_191086_6_.nextInt(4) + 1;
EndCityPieces.CityTemplate endcitypieces$citytemplate = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, p_191086_3_, new BlockPos(0, 0, -4), "bridge_piece", rotation, true));
endcitypieces$citytemplate.componentType = -1;
int j = 0;
for(int k = 0; k < i; ++k) {
if (p_191086_6_.nextBoolean()) {
endcitypieces$citytemplate = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, endcitypieces$citytemplate, new BlockPos(0, j, -4), "bridge_piece", rotation, true));
j = 0;
} else {
if (p_191086_6_.nextBoolean()) {
endcitypieces$citytemplate = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, endcitypieces$citytemplate, new BlockPos(0, j, -4), "bridge_steep_stairs", rotation, true));
} else {
endcitypieces$citytemplate = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, endcitypieces$citytemplate, new BlockPos(0, j, -8), "bridge_gentle_stairs", rotation, true));
}
j = 4;
}
}
if (!this.shipCreated && p_191086_6_.nextInt(10 - p_191086_2_) == 0) {
EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, endcitypieces$citytemplate, new BlockPos(-8 + p_191086_6_.nextInt(8), j, -70 + p_191086_6_.nextInt(10)), "ship", rotation, true));
this.shipCreated = true;
} else if (!EndCityPieces.recursiveChildren(p_191086_1_, EndCityPieces.HOUSE_TOWER_GENERATOR, p_191086_2_ + 1, endcitypieces$citytemplate, new BlockPos(-3, j + 1, -11), p_191086_5_, p_191086_6_)) {
return false;
}
endcitypieces$citytemplate = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, endcitypieces$citytemplate, new BlockPos(4, j, 0), "bridge_end", rotation.add(Rotation.CLOCKWISE_180), true));
endcitypieces$citytemplate.componentType = -1;
return true;
}
};
private static final List<Tuple<Rotation, BlockPos>> FAT_TOWER_BRIDGES = Lists.newArrayList(new Tuple<>(Rotation.NONE, new BlockPos(4, -1, 0)), new Tuple<>(Rotation.CLOCKWISE_90, new BlockPos(12, -1, 4)), new Tuple<>(Rotation.COUNTERCLOCKWISE_90, new BlockPos(0, -1, 8)), new Tuple<>(Rotation.CLOCKWISE_180, new BlockPos(8, -1, 12)));
private static final EndCityPieces.IGenerator FAT_TOWER_GENERATOR = new EndCityPieces.IGenerator() {
public void init() {
}
public boolean generate(TemplateManager p_191086_1_, int p_191086_2_, EndCityPieces.CityTemplate p_191086_3_, BlockPos p_191086_4_, List<StructurePiece> p_191086_5_, Random p_191086_6_) {
Rotation rotation = p_191086_3_.placeSettings.getRotation();
EndCityPieces.CityTemplate endcitypieces$citytemplate = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, p_191086_3_, new BlockPos(-3, 4, -3), "fat_tower_base", rotation, true));
endcitypieces$citytemplate = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, endcitypieces$citytemplate, new BlockPos(0, 4, 0), "fat_tower_middle", rotation, true));
for(int i = 0; i < 2 && p_191086_6_.nextInt(3) != 0; ++i) {
endcitypieces$citytemplate = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, endcitypieces$citytemplate, new BlockPos(0, 8, 0), "fat_tower_middle", rotation, true));
for(Tuple<Rotation, BlockPos> tuple : EndCityPieces.FAT_TOWER_BRIDGES) {
if (p_191086_6_.nextBoolean()) {
EndCityPieces.CityTemplate endcitypieces$citytemplate1 = EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, endcitypieces$citytemplate, tuple.getB(), "bridge_end", rotation.add(tuple.getA()), true));
EndCityPieces.recursiveChildren(p_191086_1_, EndCityPieces.TOWER_BRIDGE_GENERATOR, p_191086_2_ + 1, endcitypieces$citytemplate1, (BlockPos)null, p_191086_5_, p_191086_6_);
}
}
}
EndCityPieces.addHelper(p_191086_5_, EndCityPieces.addPiece(p_191086_1_, endcitypieces$citytemplate, new BlockPos(-2, 8, -2), "fat_tower_top", rotation, true));
return true;
}
};
private static EndCityPieces.CityTemplate addPiece(TemplateManager p_191090_0_, EndCityPieces.CityTemplate p_191090_1_, BlockPos p_191090_2_, String p_191090_3_, Rotation p_191090_4_, boolean owerwrite) {
EndCityPieces.CityTemplate endcitypieces$citytemplate = new EndCityPieces.CityTemplate(p_191090_0_, p_191090_3_, p_191090_1_.templatePosition, p_191090_4_, owerwrite);
BlockPos blockpos = p_191090_1_.template.calculateConnectedPos(p_191090_1_.placeSettings, p_191090_2_, endcitypieces$citytemplate.placeSettings, BlockPos.ZERO);
endcitypieces$citytemplate.offset(blockpos.getX(), blockpos.getY(), blockpos.getZ());
return endcitypieces$citytemplate;
}
public static void startHouseTower(TemplateManager p_191087_0_, BlockPos p_191087_1_, Rotation p_191087_2_, List<StructurePiece> p_191087_3_, Random p_191087_4_) {
FAT_TOWER_GENERATOR.init();
HOUSE_TOWER_GENERATOR.init();
TOWER_BRIDGE_GENERATOR.init();
TOWER_GENERATOR.init();
EndCityPieces.CityTemplate endcitypieces$citytemplate = addHelper(p_191087_3_, new EndCityPieces.CityTemplate(p_191087_0_, "base_floor", p_191087_1_, p_191087_2_, true));
endcitypieces$citytemplate = addHelper(p_191087_3_, addPiece(p_191087_0_, endcitypieces$citytemplate, new BlockPos(-1, 0, -1), "second_floor_1", p_191087_2_, false));
endcitypieces$citytemplate = addHelper(p_191087_3_, addPiece(p_191087_0_, endcitypieces$citytemplate, new BlockPos(-1, 4, -1), "third_floor_1", p_191087_2_, false));
endcitypieces$citytemplate = addHelper(p_191087_3_, addPiece(p_191087_0_, endcitypieces$citytemplate, new BlockPos(-1, 8, -1), "third_roof", p_191087_2_, true));
recursiveChildren(p_191087_0_, TOWER_GENERATOR, 1, endcitypieces$citytemplate, (BlockPos)null, p_191087_3_, p_191087_4_);
}
private static EndCityPieces.CityTemplate addHelper(List<StructurePiece> p_189935_0_, EndCityPieces.CityTemplate p_189935_1_) {
p_189935_0_.add(p_189935_1_);
return p_189935_1_;
}
private static boolean recursiveChildren(TemplateManager p_191088_0_, EndCityPieces.IGenerator p_191088_1_, int p_191088_2_, EndCityPieces.CityTemplate p_191088_3_, BlockPos p_191088_4_, List<StructurePiece> p_191088_5_, Random p_191088_6_) {
if (p_191088_2_ > 8) {
return false;
} else {
List<StructurePiece> list = Lists.newArrayList();
if (p_191088_1_.generate(p_191088_0_, p_191088_2_, p_191088_3_, p_191088_4_, list, p_191088_6_)) {
boolean flag = false;
int i = p_191088_6_.nextInt();
for(StructurePiece structurepiece : list) {
structurepiece.componentType = i;
StructurePiece structurepiece1 = StructurePiece.findIntersecting(p_191088_5_, structurepiece.getBoundingBox());
if (structurepiece1 != null && structurepiece1.componentType != p_191088_3_.componentType) {
flag = true;
break;
}
}
if (!flag) {
p_191088_5_.addAll(list);
return true;
}
}
return false;
}
}
public static class CityTemplate extends TemplateStructurePiece {
private final String pieceName;
private final Rotation rotation;
private final boolean overwrite;
public CityTemplate(TemplateManager p_i47214_1_, String p_i47214_2_, BlockPos p_i47214_3_, Rotation p_i47214_4_, boolean overwriteIn) {
super(IStructurePieceType.ECP, 0);
this.pieceName = p_i47214_2_;
this.templatePosition = p_i47214_3_;
this.rotation = p_i47214_4_;
this.overwrite = overwriteIn;
this.loadTemplate(p_i47214_1_);
}
public CityTemplate(TemplateManager p_i50598_1_, CompoundNBT p_i50598_2_) {
super(IStructurePieceType.ECP, p_i50598_2_);
this.pieceName = p_i50598_2_.getString("Template");
this.rotation = Rotation.valueOf(p_i50598_2_.getString("Rot"));
this.overwrite = p_i50598_2_.getBoolean("OW");
this.loadTemplate(p_i50598_1_);
}
private void loadTemplate(TemplateManager p_191085_1_) {
Template template = p_191085_1_.getTemplateDefaulted(new ResourceLocation("end_city/" + this.pieceName));
PlacementSettings placementsettings = (this.overwrite ? EndCityPieces.OVERWRITE : EndCityPieces.INSERT).copy().setRotation(this.rotation);
this.setup(template, this.templatePosition, placementsettings);
}
/**
* (abstract) Helper method to read subclass data from NBT
*/
protected void readAdditional(CompoundNBT tagCompound) {
super.readAdditional(tagCompound);
tagCompound.putString("Template", this.pieceName);
tagCompound.putString("Rot", this.rotation.name());
tagCompound.putBoolean("OW", this.overwrite);
}
protected void handleDataMarker(String function, BlockPos pos, IWorld worldIn, Random rand, MutableBoundingBox sbb) {
if (function.startsWith("Chest")) {
BlockPos blockpos = pos.down();
if (sbb.isVecInside(blockpos)) {
LockableLootTileEntity.setLootTable(worldIn, rand, blockpos, LootTables.CHESTS_END_CITY_TREASURE);
}
} else if (function.startsWith("Sentry")) {
ShulkerEntity shulkerentity = EntityType.SHULKER.create(worldIn.getWorld());
shulkerentity.setPosition((double)pos.getX() + 0.5D, (double)pos.getY() + 0.5D, (double)pos.getZ() + 0.5D);
shulkerentity.setAttachmentPos(pos);
worldIn.addEntity(shulkerentity);
} else if (function.startsWith("Elytra")) {
ItemFrameEntity itemframeentity = new ItemFrameEntity(worldIn.getWorld(), pos, this.rotation.rotate(Direction.SOUTH));
itemframeentity.setDisplayedItemWithUpdate(new ItemStack(Items.ELYTRA), false);
worldIn.addEntity(itemframeentity);
}
}
}
interface IGenerator {
void init();
boolean generate(TemplateManager p_191086_1_, int p_191086_2_, EndCityPieces.CityTemplate p_191086_3_, BlockPos p_191086_4_, List<StructurePiece> p_191086_5_, Random p_191086_6_);
}
}
package net.minecraft.world.gen.feature.structure;
import com.mojang.datafixers.Dynamic;
import java.util.Random;
import java.util.function.Function;
import net.minecraft.util.Rotation;
import net.minecraft.util.SharedSeedRandom;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MutableBoundingBox;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeManager;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.gen.feature.NoFeatureConfig;
import net.minecraft.world.gen.feature.template.TemplateManager;
public class EndCityStructure extends Structure<NoFeatureConfig> {
public EndCityStructure(Function<Dynamic<?>, ? extends NoFeatureConfig> p_i49883_1_) {
super(p_i49883_1_);
}
protected ChunkPos getStartPositionForPosition(ChunkGenerator<?> chunkGenerator, Random random, int x, int z, int spacingOffsetsX, int spacingOffsetsZ) {
int i = chunkGenerator.getSettings().getEndCityDistance();
int j = chunkGenerator.getSettings().getEndCitySeparation();
int k = x + i * spacingOffsetsX;
int l = z + i * spacingOffsetsZ;
int i1 = k < 0 ? k - i + 1 : k;
int j1 = l < 0 ? l - i + 1 : l;
int k1 = i1 / i;
int l1 = j1 / i;
((SharedSeedRandom)random).setLargeFeatureSeedWithSalt(chunkGenerator.getSeed(), k1, l1, 10387313);
k1 = k1 * i;
l1 = l1 * i;
k1 = k1 + (random.nextInt(i - j) + random.nextInt(i - j)) / 2;
l1 = l1 + (random.nextInt(i - j) + random.nextInt(i - j)) / 2;
return new ChunkPos(k1, l1);
}
public boolean func_225558_a_(BiomeManager biomeManagerIn, ChunkGenerator<?> generatorIn, Random randIn, int chunkX, int chunkZ, Biome biomeIn) {
ChunkPos chunkpos = this.getStartPositionForPosition(generatorIn, randIn, chunkX, chunkZ, 0, 0);
if (chunkX == chunkpos.x && chunkZ == chunkpos.z) {
if (!generatorIn.hasStructure(biomeIn, this)) {
return false;
} else {
int i = getYPosForStructure(chunkX, chunkZ, generatorIn);
return i >= 60;
}
} else {
return false;
}
}
public Structure.IStartFactory getStartFactory() {
return EndCityStructure.Start::new;
}
public String getStructureName() {
return "EndCity";
}
public int getSize() {
return 8;
}
private static int getYPosForStructure(int chunkX, int chunkY, ChunkGenerator<?> generatorIn) {
Random random = new Random((long)(chunkX + chunkY * 10387313));
Rotation rotation = Rotation.values()[random.nextInt(Rotation.values().length)];
int i = 5;
int j = 5;
if (rotation == Rotation.CLOCKWISE_90) {
i = -5;
} else if (rotation == Rotation.CLOCKWISE_180) {
i = -5;
j = -5;
} else if (rotation == Rotation.COUNTERCLOCKWISE_90) {
j = -5;
}
int k = (chunkX << 4) + 7;
int l = (chunkY << 4) + 7;
int i1 = generatorIn.func_222531_c(k, l, Heightmap.Type.WORLD_SURFACE_WG);
int j1 = generatorIn.func_222531_c(k, l + j, Heightmap.Type.WORLD_SURFACE_WG);
int k1 = generatorIn.func_222531_c(k + i, l, Heightmap.Type.WORLD_SURFACE_WG);
int l1 = generatorIn.func_222531_c(k + i, l + j, Heightmap.Type.WORLD_SURFACE_WG);
return Math.min(Math.min(i1, j1), Math.min(k1, l1));
}
public static class Start extends StructureStart {
public Start(Structure<?> p_i225802_1_, int p_i225802_2_, int p_i225802_3_, MutableBoundingBox p_i225802_4_, int p_i225802_5_, long p_i225802_6_) {
super(p_i225802_1_, p_i225802_2_, p_i225802_3_, p_i225802_4_, p_i225802_5_, p_i225802_6_);
}
public void init(ChunkGenerator<?> generator, TemplateManager templateManagerIn, int chunkX, int chunkZ, Biome biomeIn) {
Rotation rotation = Rotation.values()[this.rand.nextInt(Rotation.values().length)];
int i = EndCityStructure.getYPosForStructure(chunkX, chunkZ, generator);
if (i >= 60) {
BlockPos blockpos = new BlockPos(chunkX * 16 + 8, i, chunkZ * 16 + 8);
EndCityPieces.startHouseTower(templateManagerIn, blockpos, rotation, this.components, this.rand);
this.recalculateStructureSize();
}
}
}
}
package net.minecraft.world.gen.feature.structure;
import com.google.common.collect.ImmutableSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.DispenserBlock;
import net.minecraft.block.HorizontalBlock;
import net.minecraft.fluid.IFluidState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.ChestTileEntity;
import net.minecraft.tileentity.DispenserTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.Mirror;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MutableBoundingBox;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.Heightmap;
public abstract class StructurePiece {
protected static final BlockState CAVE_AIR = Blocks.CAVE_AIR.getDefaultState();
protected MutableBoundingBox boundingBox;
@Nullable
private Direction coordBaseMode;
private Mirror mirror;
private Rotation rotation;
protected int componentType;
private final IStructurePieceType structurePieceType;
private static final Set<Block> BLOCKS_NEEDING_POSTPROCESSING = ImmutableSet.<Block>builder().add(Blocks.NETHER_BRICK_FENCE).add(Blocks.TORCH).add(Blocks.WALL_TORCH).add(Blocks.OAK_FENCE).add(Blocks.SPRUCE_FENCE).add(Blocks.DARK_OAK_FENCE).add(Blocks.ACACIA_FENCE).add(Blocks.BIRCH_FENCE).add(Blocks.JUNGLE_FENCE).add(Blocks.LADDER).add(Blocks.IRON_BARS).build();
protected StructurePiece(IStructurePieceType structurePieceTypeIn, int componentTypeIn) {
this.structurePieceType = structurePieceTypeIn;
this.componentType = componentTypeIn;
}
public StructurePiece(IStructurePieceType structurePierceTypeIn, CompoundNBT nbt) {
this(structurePierceTypeIn, nbt.getInt("GD"));
if (nbt.contains("BB")) {
this.boundingBox = new MutableBoundingBox(nbt.getIntArray("BB"));
}
int i = nbt.getInt("O");
this.setCoordBaseMode(i == -1 ? null : Direction.byHorizontalIndex(i));
}
/**
* Writes structure base data (id, boundingbox, {@link
* net.minecraft.world.gen.structure.StructureComponent#coordBaseMode coordBase} and {@link
* net.minecraft.world.gen.structure.StructureComponent#componentType componentType}) to new NBTTagCompound and
* returns it.
*/
public final CompoundNBT write() {
if (Registry.STRUCTURE_PIECE.getKey(this.getStructurePieceType()) == null) { // FORGE: Friendlier error then the Null String error below.
throw new RuntimeException("StructurePiece \"" + this.getClass().getName() + "\": \"" + this.getStructurePieceType() + "\" missing ID Mapping, Modder see MapGenStructureIO");
}
CompoundNBT compoundnbt = new CompoundNBT();
compoundnbt.putString("id", Registry.STRUCTURE_PIECE.getKey(this.getStructurePieceType()).toString());
compoundnbt.put("BB", this.boundingBox.toNBTTagIntArray());
Direction direction = this.getCoordBaseMode();
compoundnbt.putInt("O", direction == null ? -1 : direction.getHorizontalIndex());
compoundnbt.putInt("GD", this.componentType);
this.readAdditional(compoundnbt);
return compoundnbt;
}
/**
* (abstract) Helper method to read subclass data from NBT
*/
protected abstract void readAdditional(CompoundNBT tagCompound);
/**
* Initiates construction of the Structure Component picked, at the current Location of StructGen
*/
public void buildComponent(StructurePiece componentIn, List<StructurePiece> listIn, Random rand) {
}
public abstract boolean func_225577_a_(IWorld p_225577_1_, ChunkGenerator<?> p_225577_2_, Random p_225577_3_, MutableBoundingBox p_225577_4_, ChunkPos p_225577_5_);
public MutableBoundingBox getBoundingBox() {
return this.boundingBox;
}
/**
* Returns the component type ID of this component.
*/
public int getComponentType() {
return this.componentType;
}
public boolean func_214810_a(ChunkPos p_214810_1_, int p_214810_2_) {
int i = p_214810_1_.x << 4;
int j = p_214810_1_.z << 4;
return this.boundingBox.intersectsWith(i - p_214810_2_, j - p_214810_2_, i + 15 + p_214810_2_, j + 15 + p_214810_2_);
}
/**
* Discover if bounding box can fit within the current bounding box object.
*/
public static StructurePiece findIntersecting(List<StructurePiece> listIn, MutableBoundingBox boundingboxIn) {
for(StructurePiece structurepiece : listIn) {
if (structurepiece.getBoundingBox() != null && structurepiece.getBoundingBox().intersectsWith(boundingboxIn)) {
return structurepiece;
}
}
return null;
}
/**
* checks the entire StructureBoundingBox for Liquids
*/
protected boolean isLiquidInStructureBoundingBox(IBlockReader worldIn, MutableBoundingBox boundingboxIn) {
int i = Math.max(this.boundingBox.minX - 1, boundingboxIn.minX);
int j = Math.max(this.boundingBox.minY - 1, boundingboxIn.minY);
int k = Math.max(this.boundingBox.minZ - 1, boundingboxIn.minZ);
int l = Math.min(this.boundingBox.maxX + 1, boundingboxIn.maxX);
int i1 = Math.min(this.boundingBox.maxY + 1, boundingboxIn.maxY);
int j1 = Math.min(this.boundingBox.maxZ + 1, boundingboxIn.maxZ);
BlockPos.Mutable blockpos$mutable = new BlockPos.Mutable();
for(int k1 = i; k1 <= l; ++k1) {
for(int l1 = k; l1 <= j1; ++l1) {
if (worldIn.getBlockState(blockpos$mutable.setPos(k1, j, l1)).getMaterial().isLiquid()) {
return true;
}
if (worldIn.getBlockState(blockpos$mutable.setPos(k1, i1, l1)).getMaterial().isLiquid()) {
return true;
}
}
}
for(int i2 = i; i2 <= l; ++i2) {
for(int k2 = j; k2 <= i1; ++k2) {
if (worldIn.getBlockState(blockpos$mutable.setPos(i2, k2, k)).getMaterial().isLiquid()) {
return true;
}
if (worldIn.getBlockState(blockpos$mutable.setPos(i2, k2, j1)).getMaterial().isLiquid()) {
return true;
}
}
}
for(int j2 = k; j2 <= j1; ++j2) {
for(int l2 = j; l2 <= i1; ++l2) {
if (worldIn.getBlockState(blockpos$mutable.setPos(i, l2, j2)).getMaterial().isLiquid()) {
return true;
}
if (worldIn.getBlockState(blockpos$mutable.setPos(l, l2, j2)).getMaterial().isLiquid()) {
return true;
}
}
}
return false;
}
protected int getXWithOffset(int x, int z) {
Direction direction = this.getCoordBaseMode();
if (direction == null) {
return x;
} else {
switch(direction) {
case NORTH:
case SOUTH:
return this.boundingBox.minX + x;
case WEST:
return this.boundingBox.maxX - z;
case EAST:
return this.boundingBox.minX + z;
default:
return x;
}
}
}
protected int getYWithOffset(int y) {
return this.getCoordBaseMode() == null ? y : y + this.boundingBox.minY;
}
protected int getZWithOffset(int x, int z) {
Direction direction = this.getCoordBaseMode();
if (direction == null) {
return z;
} else {
switch(direction) {
case NORTH:
return this.boundingBox.maxZ - z;
case SOUTH:
return this.boundingBox.minZ + z;
case WEST:
case EAST:
return this.boundingBox.minZ + x;
default:
return z;
}
}
}
protected void setBlockState(IWorld worldIn, BlockState blockstateIn, int x, int y, int z, MutableBoundingBox boundingboxIn) {
BlockPos blockpos = new BlockPos(this.getXWithOffset(x, z), this.getYWithOffset(y), this.getZWithOffset(x, z));
if (boundingboxIn.isVecInside(blockpos)) {
if (this.mirror != Mirror.NONE) {
blockstateIn = blockstateIn.mirror(this.mirror);
}
if (this.rotation != Rotation.NONE) {
blockstateIn = blockstateIn.rotate(this.rotation);
}
worldIn.setBlockState(blockpos, blockstateIn, 2);
IFluidState ifluidstate = worldIn.getFluidState(blockpos);
if (!ifluidstate.isEmpty()) {
worldIn.getPendingFluidTicks().scheduleTick(blockpos, ifluidstate.getFluid(), 0);
}
if (BLOCKS_NEEDING_POSTPROCESSING.contains(blockstateIn.getBlock())) {
worldIn.getChunk(blockpos).markBlockForPostprocessing(blockpos);
}
}
}
protected BlockState getBlockStateFromPos(IBlockReader worldIn, int x, int y, int z, MutableBoundingBox boundingboxIn) {
int i = this.getXWithOffset(x, z);
int j = this.getYWithOffset(y);
int k = this.getZWithOffset(x, z);
BlockPos blockpos = new BlockPos(i, j, k);
return !boundingboxIn.isVecInside(blockpos) ? Blocks.AIR.getDefaultState() : worldIn.getBlockState(blockpos);
}
protected boolean getSkyBrightness(IWorldReader worldIn, int x, int y, int z, MutableBoundingBox boundingboxIn) {
int i = this.getXWithOffset(x, z);
int j = this.getYWithOffset(y + 1);
int k = this.getZWithOffset(x, z);
BlockPos blockpos = new BlockPos(i, j, k);
if (!boundingboxIn.isVecInside(blockpos)) {
return false;
} else {
return j < worldIn.getHeight(Heightmap.Type.OCEAN_FLOOR_WG, i, k);
}
}
/**
* arguments: (World worldObj, StructureBoundingBox structBB, int minX, int minY, int minZ, int maxX, int maxY, int
* maxZ)
*/
protected void fillWithAir(IWorld worldIn, MutableBoundingBox structurebb, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
for(int i = minY; i <= maxY; ++i) {
for(int j = minX; j <= maxX; ++j) {
for(int k = minZ; k <= maxZ; ++k) {
this.setBlockState(worldIn, Blocks.AIR.getDefaultState(), j, i, k, structurebb);
}
}
}
}
/**
* Fill the given area with the selected blocks
*/
protected void fillWithBlocks(IWorld worldIn, MutableBoundingBox boundingboxIn, int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, BlockState boundaryBlockState, BlockState insideBlockState, boolean existingOnly) {
for(int i = yMin; i <= yMax; ++i) {
for(int j = xMin; j <= xMax; ++j) {
for(int k = zMin; k <= zMax; ++k) {
if (!existingOnly || !this.getBlockStateFromPos(worldIn, j, i, k, boundingboxIn).isAir()) {
if (i != yMin && i != yMax && j != xMin && j != xMax && k != zMin && k != zMax) {
this.setBlockState(worldIn, insideBlockState, j, i, k, boundingboxIn);
} else {
this.setBlockState(worldIn, boundaryBlockState, j, i, k, boundingboxIn);
}
}
}
}
}
}
/**
* arguments: World worldObj, StructureBoundingBox structBB, int minX, int minY, int minZ, int maxX, int maxY, int
* maxZ, boolean alwaysreplace, Random rand, StructurePieceBlockSelector blockselector
*/
protected void fillWithRandomizedBlocks(IWorld worldIn, MutableBoundingBox boundingboxIn, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, boolean alwaysReplace, Random rand, StructurePiece.BlockSelector blockselector) {
for(int i = minY; i <= maxY; ++i) {
for(int j = minX; j <= maxX; ++j) {
for(int k = minZ; k <= maxZ; ++k) {
if (!alwaysReplace || !this.getBlockStateFromPos(worldIn, j, i, k, boundingboxIn).isAir()) {
blockselector.selectBlocks(rand, j, i, k, i == minY || i == maxY || j == minX || j == maxX || k == minZ || k == maxZ);
this.setBlockState(worldIn, blockselector.getBlockState(), j, i, k, boundingboxIn);
}
}
}
}
}
protected void generateMaybeBox(IWorld worldIn, MutableBoundingBox sbb, Random rand, float chance, int x1, int y1, int z1, int x2, int y2, int z2, BlockState edgeState, BlockState state, boolean requireNonAir, boolean requiredSkylight) {
for(int i = y1; i <= y2; ++i) {
for(int j = x1; j <= x2; ++j) {
for(int k = z1; k <= z2; ++k) {
if (!(rand.nextFloat() > chance) && (!requireNonAir || !this.getBlockStateFromPos(worldIn, j, i, k, sbb).isAir()) && (!requiredSkylight || this.getSkyBrightness(worldIn, j, i, k, sbb))) {
if (i != y1 && i != y2 && j != x1 && j != x2 && k != z1 && k != z2) {
this.setBlockState(worldIn, state, j, i, k, sbb);
} else {
this.setBlockState(worldIn, edgeState, j, i, k, sbb);
}
}
}
}
}
}
protected void randomlyPlaceBlock(IWorld worldIn, MutableBoundingBox boundingboxIn, Random rand, float chance, int x, int y, int z, BlockState blockstateIn) {
if (rand.nextFloat() < chance) {
this.setBlockState(worldIn, blockstateIn, x, y, z, boundingboxIn);
}
}
protected void randomlyRareFillWithBlocks(IWorld worldIn, MutableBoundingBox boundingboxIn, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, BlockState blockstateIn, boolean excludeAir) {
float f = (float)(maxX - minX + 1);
float f1 = (float)(maxY - minY + 1);
float f2 = (float)(maxZ - minZ + 1);
float f3 = (float)minX + f / 2.0F;
float f4 = (float)minZ + f2 / 2.0F;
for(int i = minY; i <= maxY; ++i) {
float f5 = (float)(i - minY) / f1;
for(int j = minX; j <= maxX; ++j) {
float f6 = ((float)j - f3) / (f * 0.5F);
for(int k = minZ; k <= maxZ; ++k) {
float f7 = ((float)k - f4) / (f2 * 0.5F);
if (!excludeAir || !this.getBlockStateFromPos(worldIn, j, i, k, boundingboxIn).isAir()) {
float f8 = f6 * f6 + f5 * f5 + f7 * f7;
if (f8 <= 1.05F) {
this.setBlockState(worldIn, blockstateIn, j, i, k, boundingboxIn);
}
}
}
}
}
}
/**
* Replaces air and liquid from given position downwards. Stops when hitting anything else than air or liquid
*/
protected void replaceAirAndLiquidDownwards(IWorld worldIn, BlockState blockstateIn, int x, int y, int z, MutableBoundingBox boundingboxIn) {
int i = this.getXWithOffset(x, z);
int j = this.getYWithOffset(y);
int k = this.getZWithOffset(x, z);
if (boundingboxIn.isVecInside(new BlockPos(i, j, k))) {
while((worldIn.isAirBlock(new BlockPos(i, j, k)) || worldIn.getBlockState(new BlockPos(i, j, k)).getMaterial().isLiquid()) && j > 1) {
worldIn.setBlockState(new BlockPos(i, j, k), blockstateIn, 2);
--j;
}
}
}
/**
* Adds chest to the structure and sets its contents
*/
protected boolean generateChest(IWorld worldIn, MutableBoundingBox structurebb, Random randomIn, int x, int y, int z, ResourceLocation loot) {
BlockPos blockpos = new BlockPos(this.getXWithOffset(x, z), this.getYWithOffset(y), this.getZWithOffset(x, z));
return this.generateChest(worldIn, structurebb, randomIn, blockpos, loot, (BlockState)null);
}
public static BlockState correctFacing(IBlockReader worldIn, BlockPos posIn, BlockState blockStateIn) {
Direction direction = null;
for(Direction direction1 : Direction.Plane.HORIZONTAL) {
BlockPos blockpos = posIn.offset(direction1);
BlockState blockstate = worldIn.getBlockState(blockpos);
if (blockstate.getBlock() == Blocks.CHEST) {
return blockStateIn;
}
if (blockstate.isOpaqueCube(worldIn, blockpos)) {
if (direction != null) {
direction = null;
break;
}
direction = direction1;
}
}
if (direction != null) {
return blockStateIn.with(HorizontalBlock.HORIZONTAL_FACING, direction.getOpposite());
} else {
Direction direction2 = blockStateIn.get(HorizontalBlock.HORIZONTAL_FACING);
BlockPos blockpos1 = posIn.offset(direction2);
if (worldIn.getBlockState(blockpos1).isOpaqueCube(worldIn, blockpos1)) {
direction2 = direction2.getOpposite();
blockpos1 = posIn.offset(direction2);
}
if (worldIn.getBlockState(blockpos1).isOpaqueCube(worldIn, blockpos1)) {
direction2 = direction2.rotateY();
blockpos1 = posIn.offset(direction2);
}
if (worldIn.getBlockState(blockpos1).isOpaqueCube(worldIn, blockpos1)) {
direction2 = direction2.getOpposite();
posIn.offset(direction2);
}
return blockStateIn.with(HorizontalBlock.HORIZONTAL_FACING, direction2);
}
}
protected boolean generateChest(IWorld worldIn, MutableBoundingBox boundsIn, Random rand, BlockPos posIn, ResourceLocation resourceLocationIn, @Nullable BlockState p_191080_6_) {
if (boundsIn.isVecInside(posIn) && worldIn.getBlockState(posIn).getBlock() != Blocks.CHEST) {
if (p_191080_6_ == null) {
p_191080_6_ = correctFacing(worldIn, posIn, Blocks.CHEST.getDefaultState());
}
worldIn.setBlockState(posIn, p_191080_6_, 2);
TileEntity tileentity = worldIn.getTileEntity(posIn);
if (tileentity instanceof ChestTileEntity) {
((ChestTileEntity)tileentity).setLootTable(resourceLocationIn, rand.nextLong());
}
return true;
} else {
return false;
}
}
protected boolean createDispenser(IWorld worldIn, MutableBoundingBox sbb, Random rand, int x, int y, int z, Direction facing, ResourceLocation lootTableIn) {
BlockPos blockpos = new BlockPos(this.getXWithOffset(x, z), this.getYWithOffset(y), this.getZWithOffset(x, z));
if (sbb.isVecInside(blockpos) && worldIn.getBlockState(blockpos).getBlock() != Blocks.DISPENSER) {
this.setBlockState(worldIn, Blocks.DISPENSER.getDefaultState().with(DispenserBlock.FACING, facing), x, y, z, sbb);
TileEntity tileentity = worldIn.getTileEntity(blockpos);
if (tileentity instanceof DispenserTileEntity) {
((DispenserTileEntity)tileentity).setLootTable(lootTableIn, rand.nextLong());
}
return true;
} else {
return false;
}
}
public void offset(int x, int y, int z) {
this.boundingBox.offset(x, y, z);
}
@Nullable
public Direction getCoordBaseMode() {
return this.coordBaseMode;
}
public void setCoordBaseMode(@Nullable Direction facing) {
this.coordBaseMode = facing;
if (facing == null) {
this.rotation = Rotation.NONE;
this.mirror = Mirror.NONE;
} else {
switch(facing) {
case SOUTH:
this.mirror = Mirror.LEFT_RIGHT;
this.rotation = Rotation.NONE;
break;
case WEST:
this.mirror = Mirror.LEFT_RIGHT;
this.rotation = Rotation.CLOCKWISE_90;
break;
case EAST:
this.mirror = Mirror.NONE;
this.rotation = Rotation.CLOCKWISE_90;
break;
default:
this.mirror = Mirror.NONE;
this.rotation = Rotation.NONE;
}
}
}
public Rotation getRotation() {
return this.rotation;
}
public IStructurePieceType getStructurePieceType() {
return this.structurePieceType;
}
public abstract static class BlockSelector {
protected BlockState blockstate = Blocks.AIR.getDefaultState();
/**
* picks Block Ids and Metadata (Silverfish)
*/
public abstract void selectBlocks(Random rand, int x, int y, int z, boolean wall);
public BlockState getBlockState() {
return this.blockstate;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment