package com.thebrokenrail.energonrelics.block.structure; import com.thebrokenrail.energonrelics.EnergonRelics; import com.thebrokenrail.energonrelics.block.entity.structure.StructureGeneratorBlockEntity; import com.thebrokenrail.energonrelics.api.block.SimpleBlockWithEntity; import com.thebrokenrail.energonrelics.structure.researchcomplex.ResearchComplexStartPart; import com.thebrokenrail.energonrelics.structure.researchcomplex.ResearchComplexState; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.fabricmc.fabric.api.structure.v1.FabricStructureBuilder; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.server.world.ServerWorld; import net.minecraft.state.StateManager; import net.minecraft.state.property.DirectionProperty; import net.minecraft.state.property.Properties; import net.minecraft.structure.StructurePieceType; import net.minecraft.util.BlockMirror; import net.minecraft.util.BlockRotation; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.registry.Registry; import net.minecraft.world.StructureWorldAccess; import net.minecraft.world.World; import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.GenerationStep; import net.minecraft.world.gen.chunk.StructureConfig; import net.minecraft.world.gen.feature.ConfiguredStructureFeature; import net.minecraft.world.gen.feature.DefaultFeatureConfig; import net.minecraft.world.gen.feature.FeatureConfig; import net.minecraft.world.gen.feature.StructureFeature; import java.util.HashMap; import java.util.Map; import java.util.Random; import java.util.function.Function; @SuppressWarnings("deprecation") public class StructureGeneratorBlock extends SimpleBlockWithEntity { public static final DirectionProperty HORIZONTAL_FACING = Properties.HORIZONTAL_FACING; private static final Map blocks = new HashMap<>(); private final StructureGeneratorBlockEntity.StructurePartFactory structureFactory; private final StructureConfig structureConfig; private final StructureFeature feature = new StructureGeneratorFeature(this); final StructurePieceType piece = (structureManager, tag) -> new StructureGeneratorPiece(this, tag); private StructureGeneratorBlock(StructureGeneratorBlockEntity.StructurePartFactory structureFactory, StructureConfig structureConfig) { super(FabricBlockSettings.copy(Blocks.BEDROCK)); setDefaultState(getDefaultState().with(HORIZONTAL_FACING, Direction.NORTH)); this.structureFactory = structureFactory; this.structureConfig = structureConfig; } @Override public BlockState rotate(BlockState state, BlockRotation rotation) { return state.with(HORIZONTAL_FACING, rotation.rotate(state.get(HORIZONTAL_FACING))); } @Override public BlockState mirror(BlockState state, BlockMirror mirror) { return state.rotate(mirror.getRotation(state.get(HORIZONTAL_FACING))); } @Override protected boolean addToItemGroup() { return false; } @Override protected boolean isEpic() { return true; } @Override protected void appendProperties(StateManager.Builder builder) { super.appendProperties(builder); builder.add(HORIZONTAL_FACING); } @Override protected Function, BlockEntity> getFactory() { return type -> new StructureGeneratorBlockEntity(type, structureFactory); } @Override public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { super.scheduledTick(state, world, pos, random); BlockEntity entity = world.getBlockEntity(pos); if (entity instanceof StructureGeneratorBlockEntity) { ((StructureGeneratorBlockEntity) entity).generate(); } } @Override public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState oldState, boolean notify) { super.onBlockAdded(state, world, pos, oldState, notify); if (world instanceof ServerWorld) { schedule((ServerWorld) world, pos); } } public void schedule(StructureWorldAccess world, BlockPos pos) { world.getBlockTickScheduler().schedule(pos, this, 0); } @Override public void register(Identifier id) { super.register(new Identifier(id.getNamespace(), id.getPath() + "_generator")); } @SuppressWarnings("SameParameterValue") private static void create(String name, StructureGeneratorBlockEntity.StructurePartFactory factory, StructureConfig config) { StructureGeneratorBlock block = new StructureGeneratorBlock(factory, config); blocks.put(name, block); Registry.register(Registry.STRUCTURE_PIECE, new Identifier(EnergonRelics.NAMESPACE, name + "_piece"), block.piece); FabricStructureBuilder.create(new Identifier(EnergonRelics.NAMESPACE, name), block.feature).step(GenerationStep.Feature.UNDERGROUND_STRUCTURES).defaultConfig(block.structureConfig).superflatFeature(block.feature.configure(FeatureConfig.DEFAULT)).register(); } public static void registerBlocks() { for (Map.Entry entry : blocks.entrySet()) { entry.getValue().register(entry.getKey()); } } public static void addToBiome(Biome biome) { registerStructures(); for (Map.Entry entry : blocks.entrySet()) { ConfiguredStructureFeature feature = entry.getValue().feature.configure(DefaultFeatureConfig.INSTANCE); biome.getGenerationSettings().getStructureFeatures().add(() -> feature); } } public static void registerStructures() { if (blocks.size() == 0) { create("research_complex", (world, random, transformations) -> new ResearchComplexStartPart(new ResearchComplexState(world, random), transformations), new StructureConfig(32, 8, 14357618)); } } }