diff --git a/src/main/java/ru/betterend/blocks/complex/MetalMaterial.java b/src/main/java/ru/betterend/blocks/complex/MetalMaterial.java index bb7f6041..7356e108 100644 --- a/src/main/java/ru/betterend/blocks/complex/MetalMaterial.java +++ b/src/main/java/ru/betterend/blocks/complex/MetalMaterial.java @@ -202,5 +202,7 @@ public class MetalMaterial { TagHelper.addTag(BlockTags.BEACON_BASE_BLOCKS, block); TagHelper.addTag(EndTags.IRON_INGOTS, ingot); TagHelper.addTag(ItemTags.BEACON_PAYMENT_ITEMS, ingot); + + TagHelper.addTag(EndTags.DRAGON_IMMUNE, ore, bars); } } \ No newline at end of file diff --git a/src/main/java/ru/betterend/blocks/complex/StoneMaterial.java b/src/main/java/ru/betterend/blocks/complex/StoneMaterial.java index 08fde481..782ff4b0 100644 --- a/src/main/java/ru/betterend/blocks/complex/StoneMaterial.java +++ b/src/main/java/ru/betterend/blocks/complex/StoneMaterial.java @@ -98,5 +98,7 @@ public class StoneMaterial { TagHelper.addTag(BlockTags.SLABS, slab, brick_slab); TagHelper.addTags(pressure_plate, BlockTags.PRESSURE_PLATES, BlockTags.STONE_PRESSURE_PLATES); TagHelper.addTag(EndTags.END_STONES, stone); + + TagHelper.addTag(EndTags.DRAGON_IMMUNE, stone, stairs, slab, wall); } } \ No newline at end of file diff --git a/src/main/java/ru/betterend/mixin/common/EndSpikeFeatureMixin.java b/src/main/java/ru/betterend/mixin/common/EndSpikeFeatureMixin.java index 220a93c3..28be0c91 100644 --- a/src/main/java/ru/betterend/mixin/common/EndSpikeFeatureMixin.java +++ b/src/main/java/ru/betterend/mixin/common/EndSpikeFeatureMixin.java @@ -13,6 +13,8 @@ import net.minecraft.block.Blocks; import net.minecraft.block.PaneBlock; import net.minecraft.entity.EntityType; import net.minecraft.entity.decoration.EndCrystalEntity; +import net.minecraft.structure.Structure; +import net.minecraft.structure.StructurePlacementData; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos.Mutable; import net.minecraft.util.math.MathHelper; @@ -22,7 +24,9 @@ import net.minecraft.world.StructureWorldAccess; import net.minecraft.world.gen.chunk.ChunkGenerator; import net.minecraft.world.gen.feature.EndSpikeFeature; import net.minecraft.world.gen.feature.EndSpikeFeatureConfig; +import ru.betterend.BetterEnd; import ru.betterend.util.BlocksHelper; +import ru.betterend.util.StructureHelper; import ru.betterend.world.generator.GeneratorOptions; @Mixin(EndSpikeFeature.class) @@ -39,50 +43,92 @@ public class EndSpikeFeatureMixin { int x = spike.getCenterX(); int z = spike.getCenterZ(); int radius = spike.getRadius(); - int minY = world.getChunk(spike.getCenterX() >> 4, spike.getCenterZ() >> 4).sampleHeightmap(Type.WORLD_SURFACE, spike.getCenterX() & 15, spike.getCenterZ() & 15) - 15; - int maxY = minY + spike.getHeight() - 50; + int minY = world.getChunk(x >> 4, z >> 4).sampleHeightmap(Type.WORLD_SURFACE, x & 15, z); + int maxY = minY + spike.getHeight() - 30; - int r2 = radius * radius + 1; - Mutable mut = new Mutable(); - for (int px = -radius; px <= radius; px++) { - mut.setX(x + px); - int x2 = px * px; - for (int pz = -radius; pz <= radius; pz++) { - mut.setZ(z + pz); - int z2 = pz * pz; - if (x2 + z2 <= r2) { - for (int py = minY; py < maxY; py++) { - mut.setY(py); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, Blocks.OBSIDIAN); + if (GeneratorOptions.replacePillars() && be_radiusInRange(radius)) { + radius--; + Structure base = StructureHelper.readStructure(BetterEnd.makeID("pillars/pillar_base_" + radius)); + Structure top = StructureHelper.readStructure(BetterEnd.makeID("pillars/pillar_top_" + radius + (spike.isGuarded() ? "_cage" : ""))); + BlockPos side = base.getSize(); + BlockPos pos1 = new BlockPos(x - (side.getX() >> 1), minY - 3, z - (side.getZ() >> 1)); + minY = pos1.getY() + side.getY(); + side = top.getSize(); + BlockPos pos2 = new BlockPos(x - (side.getX() >> 1), maxY, z - (side.getZ() >> 1)); + maxY = pos2.getY(); + + StructurePlacementData data = new StructurePlacementData(); + base.place(world, pos1, data, random); + top.place(world, pos2, data, random); + + int r2 = radius * radius + 1; + Mutable mut = new Mutable(); + for (int px = -radius; px <= radius; px++) { + mut.setX(x + px); + int x2 = px * px; + for (int pz = -radius; pz <= radius; pz++) { + mut.setZ(z + pz); + int z2 = pz * pz; + if (x2 + z2 <= r2) { + for (int py = minY; py < maxY; py++) { + mut.setY(py); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + if ((px == radius || px == -radius || pz == radius || pz == -radius) && random.nextInt(24) == 0) { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.CRYING_OBSIDIAN); + } + else { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.OBSIDIAN); + } + } } } } } } - mut.setX(x); - mut.setZ(z); - mut.setY(maxY); - BlocksHelper.setWithoutUpdate(world, mut, Blocks.BEDROCK); - - EndCrystalEntity crystal = EntityType.END_CRYSTAL.create(world.toServerWorld()); - crystal.setBeamTarget(config.getPos()); - crystal.setInvulnerable(config.isCrystalInvulnerable()); - crystal.refreshPositionAndAngles(x + 0.5D, maxY + 1, z + 0.5D, random.nextFloat() * 360.0F, 0.0F); - world.spawnEntity(crystal); - - if (spike.isGuarded()) { - for (int px = -2; px <= 2; ++px) { - boolean bl = MathHelper.abs(px) == 2; - for (int pz = -2; pz <= 2; ++pz) { - boolean bl2 = MathHelper.abs(pz) == 2; - for (int py = 0; py <= 3; ++py) { - boolean bl3 = py == 3; - if (bl || bl2 || bl3) { - boolean bl4 = px == -2 || px == 2 || bl3; - boolean bl5 = pz == -2 || pz == 2 || bl3; - BlockState blockState = (BlockState) ((BlockState) ((BlockState) ((BlockState) Blocks.IRON_BARS.getDefaultState().with(PaneBlock.NORTH, bl4 && pz != -2)).with(PaneBlock.SOUTH, bl4 && pz != 2)).with(PaneBlock.WEST, bl5 && px != -2)).with(PaneBlock.EAST, bl5 && px != 2); - BlocksHelper.setWithoutUpdate(world, mut.set(spike.getCenterX() + px, maxY + py, spike.getCenterZ() + pz), blockState); + else { + minY -= 15; + int r2 = radius * radius + 1; + Mutable mut = new Mutable(); + for (int px = -radius; px <= radius; px++) { + mut.setX(x + px); + int x2 = px * px; + for (int pz = -radius; pz <= radius; pz++) { + mut.setZ(z + pz); + int z2 = pz * pz; + if (x2 + z2 <= r2) { + for (int py = minY; py < maxY; py++) { + mut.setY(py); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.OBSIDIAN); + } + } + } + } + } + mut.setX(x); + mut.setZ(z); + mut.setY(maxY); + BlocksHelper.setWithoutUpdate(world, mut, Blocks.BEDROCK); + + EndCrystalEntity crystal = EntityType.END_CRYSTAL.create(world.toServerWorld()); + crystal.setBeamTarget(config.getPos()); + crystal.setInvulnerable(config.isCrystalInvulnerable()); + crystal.refreshPositionAndAngles(x + 0.5D, maxY + 1, z + 0.5D, random.nextFloat() * 360.0F, 0.0F); + world.spawnEntity(crystal); + + if (spike.isGuarded()) { + for (int px = -2; px <= 2; ++px) { + boolean bl = MathHelper.abs(px) == 2; + for (int pz = -2; pz <= 2; ++pz) { + boolean bl2 = MathHelper.abs(pz) == 2; + for (int py = 0; py <= 3; ++py) { + boolean bl3 = py == 3; + if (bl || bl2 || bl3) { + boolean bl4 = px == -2 || px == 2 || bl3; + boolean bl5 = pz == -2 || pz == 2 || bl3; + BlockState blockState = (BlockState) ((BlockState) ((BlockState) ((BlockState) Blocks.IRON_BARS.getDefaultState().with(PaneBlock.NORTH, bl4 && pz != -2)).with(PaneBlock.SOUTH, bl4 && pz != 2)).with(PaneBlock.WEST, bl5 && px != -2)).with(PaneBlock.EAST, bl5 && px != 2); + BlocksHelper.setWithoutUpdate(world, mut.set(spike.getCenterX() + px, maxY + py, spike.getCenterZ() + pz), blockState); + } } } } @@ -91,4 +137,8 @@ public class EndSpikeFeatureMixin { info.cancel(); } + + private boolean be_radiusInRange(int radius) { + return radius > 1 && radius < 6; + } } diff --git a/src/main/java/ru/betterend/registry/EndTags.java b/src/main/java/ru/betterend/registry/EndTags.java index f2d5f2e6..c315e530 100644 --- a/src/main/java/ru/betterend/registry/EndTags.java +++ b/src/main/java/ru/betterend/registry/EndTags.java @@ -39,6 +39,7 @@ public class EndTags { public static final Tag.Identified PEDESTALS = makeBlockTag("pedestal"); public static final Tag.Identified BLOCK_CHEST = makeCommonBlockTag("chest"); public static final Tag.Identified END_STONES = makeCommonBlockTag("end_stones"); + public static final Tag.Identified DRAGON_IMMUNE = getMCBlockTag("dragon_immune"); // Item Tags public static final Tag.Identified ITEM_CHEST = makeCommonItemTag("chest"); @@ -70,6 +71,12 @@ public class EndTags { return tag == null ? (Identified) TagRegistry.item(id) : (Identified) tag; } + public static Tag.Identified getMCBlockTag(String name) { + Identifier id = new Identifier(name); + Tag tag = BlockTags.getTagGroup().getTag(id); + return tag == null ? (Identified) TagRegistry.block(id) : (Identified) tag; + } + public static void register() { addSurfaceBlock(Blocks.END_STONE); addSurfaceBlock(EndBlocks.THALLASIUM.ore); @@ -117,6 +124,8 @@ public class EndTags { TagHelper.addTag(BlockTags.BEACON_BASE_BLOCKS, EndBlocks.AETERNIUM_BLOCK); TagHelper.addTag(ItemTags.BEACON_PAYMENT_ITEMS, EndItems.AETERNIUM_INGOT); + + TagHelper.addTag(EndTags.DRAGON_IMMUNE, EndBlocks.ENDER_ORE); } public static void addSurfaceBlock(Block block) { diff --git a/src/main/java/ru/betterend/world/generator/GeneratorOptions.java b/src/main/java/ru/betterend/world/generator/GeneratorOptions.java index baee736f..e166410a 100644 --- a/src/main/java/ru/betterend/world/generator/GeneratorOptions.java +++ b/src/main/java/ru/betterend/world/generator/GeneratorOptions.java @@ -25,6 +25,7 @@ public class GeneratorOptions { private static BlockPos spawn; private static BlockPos portal = BlockPos.ORIGIN; private static boolean replacePortal; + private static boolean replacePillars; public static void init() { biomeSizeLand = Configs.GENERATOR_CONFIG.getInt("biomeMap", "biomeSizeLand", 256); @@ -50,6 +51,7 @@ public class GeneratorOptions { Configs.GENERATOR_CONFIG.getInt("spawn.point", "z", 0) ); replacePortal = Configs.GENERATOR_CONFIG.getBooleanRoot("customEndPortal", true); + replacePillars = Configs.GENERATOR_CONFIG.getBooleanRoot("customObsidianSpikes", true); } public static int getBiomeSizeLand() { @@ -123,4 +125,8 @@ public class GeneratorOptions { public static boolean replacePortal() { return replacePortal; } + + public static boolean replacePillars() { + return replacePillars; + } } diff --git a/src/main/resources/data/betterend/structures/pillars/pillar_base_1.nbt b/src/main/resources/data/betterend/structures/pillars/pillar_base_1.nbt new file mode 100644 index 00000000..a1a3869d Binary files /dev/null and b/src/main/resources/data/betterend/structures/pillars/pillar_base_1.nbt differ diff --git a/src/main/resources/data/betterend/structures/pillars/pillar_base_2.nbt b/src/main/resources/data/betterend/structures/pillars/pillar_base_2.nbt new file mode 100644 index 00000000..7f8da56f Binary files /dev/null and b/src/main/resources/data/betterend/structures/pillars/pillar_base_2.nbt differ diff --git a/src/main/resources/data/betterend/structures/pillars/pillar_base_3.nbt b/src/main/resources/data/betterend/structures/pillars/pillar_base_3.nbt new file mode 100644 index 00000000..9d428124 Binary files /dev/null and b/src/main/resources/data/betterend/structures/pillars/pillar_base_3.nbt differ diff --git a/src/main/resources/data/betterend/structures/pillars/pillar_base_4.nbt b/src/main/resources/data/betterend/structures/pillars/pillar_base_4.nbt new file mode 100644 index 00000000..9a1091fb Binary files /dev/null and b/src/main/resources/data/betterend/structures/pillars/pillar_base_4.nbt differ diff --git a/src/main/resources/data/betterend/structures/pillars/pillar_top_1.nbt b/src/main/resources/data/betterend/structures/pillars/pillar_top_1.nbt new file mode 100644 index 00000000..05805e9c Binary files /dev/null and b/src/main/resources/data/betterend/structures/pillars/pillar_top_1.nbt differ diff --git a/src/main/resources/data/betterend/structures/pillars/pillar_top_1_cage.nbt b/src/main/resources/data/betterend/structures/pillars/pillar_top_1_cage.nbt new file mode 100644 index 00000000..eb5a52de Binary files /dev/null and b/src/main/resources/data/betterend/structures/pillars/pillar_top_1_cage.nbt differ diff --git a/src/main/resources/data/betterend/structures/pillars/pillar_top_2.nbt b/src/main/resources/data/betterend/structures/pillars/pillar_top_2.nbt new file mode 100644 index 00000000..2a168470 Binary files /dev/null and b/src/main/resources/data/betterend/structures/pillars/pillar_top_2.nbt differ diff --git a/src/main/resources/data/betterend/structures/pillars/pillar_top_2_cage.nbt b/src/main/resources/data/betterend/structures/pillars/pillar_top_2_cage.nbt new file mode 100644 index 00000000..97d401e6 Binary files /dev/null and b/src/main/resources/data/betterend/structures/pillars/pillar_top_2_cage.nbt differ diff --git a/src/main/resources/data/betterend/structures/pillars/pillar_top_3.nbt b/src/main/resources/data/betterend/structures/pillars/pillar_top_3.nbt new file mode 100644 index 00000000..81ffb032 Binary files /dev/null and b/src/main/resources/data/betterend/structures/pillars/pillar_top_3.nbt differ diff --git a/src/main/resources/data/betterend/structures/pillars/pillar_top_3_cage.nbt b/src/main/resources/data/betterend/structures/pillars/pillar_top_3_cage.nbt new file mode 100644 index 00000000..aca9c04f Binary files /dev/null and b/src/main/resources/data/betterend/structures/pillars/pillar_top_3_cage.nbt differ diff --git a/src/main/resources/data/betterend/structures/pillars/pillar_top_4.nbt b/src/main/resources/data/betterend/structures/pillars/pillar_top_4.nbt new file mode 100644 index 00000000..8a6c0a05 Binary files /dev/null and b/src/main/resources/data/betterend/structures/pillars/pillar_top_4.nbt differ diff --git a/src/main/resources/data/betterend/structures/pillars/pillar_top_4_cage.nbt b/src/main/resources/data/betterend/structures/pillars/pillar_top_4_cage.nbt new file mode 100644 index 00000000..fffce784 Binary files /dev/null and b/src/main/resources/data/betterend/structures/pillars/pillar_top_4_cage.nbt differ