Jump to content

My structure is not generating


Armanse

Recommended Posts

Hi, i've been working recently on a structure called the tree monument. I finished my code but the structure doesn't spawn in to the overworld what did i do wrong ?

Here is the code: MAIN.class

import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.armanse.barkutil.init.BlockInit;
import com.armanse.barkutil.init.FeatureInit;
import com.armanse.barkutil.init.ItemInit;
import com.armanse.barkutil.world.gen.STConfiguredStructures;
import com.mojang.serialization.Codec;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.FlatChunkGenerator;
import net.minecraft.world.gen.feature.structure.Structure;
import net.minecraft.world.gen.settings.DimensionStructuresSettings;
import net.minecraft.world.gen.settings.StructureSeparationSettings;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.event.world.BiomeLoadingEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Mod("bark_mod")
public class Bark_UtilityMain
{
    public static final Logger LOGGER = LogManager.getLogger();
    public static final String MOD_ID = "bark_mod";

    public Bark_UtilityMain() {
    	
    	IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();
        
        BlockInit.BLOCKS.register(bus);
        ItemInit.ITEMS.register(bus);
        FeatureInit.STRUCTURE.register(bus);
        bus.addListener(this::setup);
        IEventBus forgeBus = MinecraftForge.EVENT_BUS;
        forgeBus.addListener(EventPriority.NORMAL, this::addDimensionalSpacing);

        
        forgeBus.addListener(EventPriority.HIGH, this::biomeModification);
        MinecraftForge.EVENT_BUS.register(this);
    }

    public void setup(final FMLCommonSetupEvent event)
    {
        event.enqueueWork(() -> {
            FeatureInit.setupStructures();
            STConfiguredStructures.registerConfiguredStructures();
        });
    }


   
    public void biomeModification(final BiomeLoadingEvent event) {
        
        event.getGeneration().getStructures().add(() -> STConfiguredStructures.CONFIGURED_TREEMONUMENT);
    }

    
    private static Method GETCODEC_METHOD;
    public void addDimensionalSpacing(final WorldEvent.Load event) {
        if(event.getWorld() instanceof ServerWorld){
            ServerWorld serverWorld = (ServerWorld)event.getWorld();

            try {
                if(GETCODEC_METHOD == null) GETCODEC_METHOD = ObfuscationReflectionHelper.findMethod(ChunkGenerator.class, "func_230347_a_");
                ResourceLocation cgRL = Registry.CHUNK_GENERATOR.getKey((Codec<? extends ChunkGenerator>) GETCODEC_METHOD.invoke(serverWorld.getChunkSource().generator));
                if(cgRL != null && cgRL.getNamespace().equals("terraforged")) return;
            }
            catch(Exception e){
                Bark_UtilityMain.LOGGER.error("Was unable to check if " + serverWorld.dimension().location() + " is using Terraforged's ChunkGenerator.");
            }

           
            if(serverWorld.getChunkSource().getGenerator() instanceof FlatChunkGenerator &&
                serverWorld.dimension().equals(World.OVERWORLD)){
                return;
            }

            Map<Structure<?>, StructureSeparationSettings> tempMap = new HashMap<>(serverWorld.getChunkSource().generator.getSettings().structureConfig());
            tempMap.putIfAbsent(FeatureInit.TREEMONUMENT.get(), DimensionStructuresSettings.DEFAULTS.get(FeatureInit.TREEMONUMENT.get()));
            serverWorld.getChunkSource().generator.getSettings().structureConfig = tempMap;
        }
   }

}

FeatureInit.class:

import java.util.HashMap;
import java.util.Map;
import com.armanse.barkutil.Bark_UtilityMain;
import com.armanse.barkutil.world.features.TreeMonument;
import com.google.common.collect.ImmutableMap;

import net.minecraft.util.registry.WorldGenRegistries;
import net.minecraft.world.gen.feature.NoFeatureConfig;
import net.minecraft.world.gen.feature.structure.Structure;
import net.minecraft.world.gen.settings.DimensionStructuresSettings;
import net.minecraft.world.gen.settings.StructureSeparationSettings;
import net.minecraftforge.fml.RegistryObject;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;

public class FeatureInit {
	
	public static final DeferredRegister<Structure<?>> STRUCTURE = DeferredRegister.create(ForgeRegistries.STRUCTURE_FEATURES, Bark_UtilityMain.MOD_ID);
	
	public static final RegistryObject<Structure<NoFeatureConfig>> TREEMONUMENT = STRUCTURE.register("treemonument", () -> new TreeMonument(NoFeatureConfig.CODEC));
	
	 public static void setupStructures() {
	        setupMapSpacingAndLand(
	                TREEMONUMENT.get(), 
	                new StructureSeparationSettings(10,
	                        5,
	                        1234567890),
	                true);
	    }

	    public static <F extends Structure<?>> void setupMapSpacingAndLand(
	            F structure,
	            StructureSeparationSettings structureSeparationSettings,
	            boolean transformSurroundingLand)
	    {
	        Structure.STRUCTURES_REGISTRY.put(structure.getRegistryName().toString(), structure);
	        
	       DimensionStructuresSettings.DEFAULTS.putAll(DimensionStructuresSettings.DEFAULTS);
	       DimensionStructuresSettings.DEFAULTS.put(structure, structureSeparationSettings);
	       DimensionStructuresSettings.DEFAULTS.builder().build();
	        
	        
	        WorldGenRegistries.NOISE_GENERATOR_SETTINGS.entrySet().forEach(settings -> {
	            Map<Structure<?>, StructureSeparationSettings> structureMap = settings.getValue().structureSettings().structureConfig();

	            if(structureMap instanceof ImmutableMap){
	                Map<Structure<?>, StructureSeparationSettings> tempMap = new HashMap<>(structureMap);
	                tempMap.put(structure, structureSeparationSettings);
	                settings.getValue().structureSettings().structureConfig = tempMap;
	            }
	            else{
	                structureMap.put(structure, structureSeparationSettings);
	            }
	        });
	    }
}

Tree Monument.class:

import java.util.List;
import com.armanse.barkutil.Bark_UtilityMain;
import com.google.common.collect.ImmutableList;
import com.mojang.serialization.Codec;
import net.minecraft.block.BlockState;
import net.minecraft.entity.EntityType;
import net.minecraft.util.SharedSeedRandom;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.registry.DynamicRegistries;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.MobSpawnInfo;
import net.minecraft.world.biome.MobSpawnInfo.Spawners;
import net.minecraft.world.biome.provider.BiomeProvider;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.GenerationStage;
import net.minecraft.world.gen.GenerationStage.Decoration;
import net.minecraft.world.gen.feature.NoFeatureConfig;
import net.minecraft.world.gen.feature.structure.Structure;
import net.minecraft.world.gen.feature.structure.StructureStart;
import net.minecraft.world.gen.feature.template.TemplateManager;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MutableBoundingBox;
import net.minecraft.util.math.vector.Vector3i;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.gen.feature.jigsaw.JigsawManager;
import net.minecraft.world.gen.feature.structure.*;
import org.apache.logging.log4j.Level;
public class TreeMonument extends Structure<NoFeatureConfig> {

	public TreeMonument(Codec<NoFeatureConfig> config) {
		super(config);
		// TODO Auto-generated constructor stub
	}

	@Override
	public IStartFactory<NoFeatureConfig> getStartFactory() {
		// TODO Auto-generated method stub
		return TreeMonument.Start::new;
	}
	
	
	@Override
	public String getFeatureName() {
		// TODO Auto-generated method stub
		return Bark_UtilityMain.MOD_ID + ":TreeMonument";
	}

	@Override
	public Decoration step() {
		// TODO Auto-generated method stub
		return GenerationStage.Decoration.SURFACE_STRUCTURES;
	}
	
	private static final List<MobSpawnInfo.Spawners> STRUCTURE_MONSTERS = ImmutableList.of(
	           new MobSpawnInfo.Spawners(EntityType.SILVERFISH, 100, 1, 5),
	           new MobSpawnInfo.Spawners(EntityType.ENDERMITE, 100, 1, 5));
	@Override
	 public List<MobSpawnInfo.Spawners> getDefaultSpawnList() {
		 return STRUCTURE_MONSTERS;
	 }
	 
	@Override
	public List<Spawners> getDefaultCreatureSpawnList() {
		// TODO Auto-generated method stub
		return super.getDefaultCreatureSpawnList();
	}
	
	@Override
	protected boolean isFeatureChunk(ChunkGenerator chunkGenerator, BiomeProvider biomeprovider, long p_230363_3_,
			SharedSeedRandom p_230363_5_, int chunkX, int chunkZ, Biome biome, ChunkPos pos,
			NoFeatureConfig p_230363_10_) {
	
		 BlockPos centerOfChunk = new BlockPos((chunkX << 4)+7, 0, (chunkZ<<4)+7);

	     int landHeight = chunkGenerator.getFirstOccupiedHeight(centerOfChunk.getX(), centerOfChunk.getZ(), Heightmap.Type.WORLD_SURFACE_WG);
	     IBlockReader columnOfBlocks = chunkGenerator.getBaseColumn(centerOfChunk.getX(), centerOfChunk.getZ());
	     BlockState topBlock = columnOfBlocks.getBlockState(centerOfChunk.above(landHeight));
	     return topBlock.getFluidState().isEmpty();
	}
	
	public static class Start extends StructureStart<NoFeatureConfig>  {
        public Start(Structure<NoFeatureConfig> structureIn, int chunkX, int chunkZ, MutableBoundingBox mutableBoundingBox, int referenceIn, long seedIn) {
            super(structureIn, chunkX, chunkZ, mutableBoundingBox, referenceIn, seedIn);
        }

        @Override
        public void generatePieces(DynamicRegistries dynamicRegistryManager, ChunkGenerator chunkGenerator, TemplateManager templateManagerIn, int chunkX, int chunkZ, Biome biomeIn, NoFeatureConfig config) {

            int x = (chunkX << 4) +7;
            int z = (chunkZ << 4) +7;

           
            BlockPos centerPos = new BlockPos(x, 0, z);

            JigsawManager.addPieces(
                    dynamicRegistryManager,
                    new VillageConfig(() -> dynamicRegistryManager.registryOrThrow(Registry.TEMPLATE_POOL_REGISTRY)
                            .get(new ResourceLocation(Bark_UtilityMain.MOD_ID, "treemonument/start_pool")),10),
                    AbstractVillagePiece::new,
                    chunkGenerator,
                    templateManagerIn,
                    centerPos, 
                    this.pieces, 
                    this.random,
                    false, 
                    true);  

            this.pieces.forEach(piece -> piece.move(0, 1, 0));
            this.pieces.forEach(piece -> piece.getBoundingBox().y0 -= 1);

          
            Vector3i structureCenter = this.pieces.get(0).getBoundingBox().getCenter();
            int xOffset = centerPos.getX() - structureCenter.getX();
            int zOffset = centerPos.getZ() - structureCenter.getZ();
            for(StructurePiece structurePiece : this.pieces){
                structurePiece.move(xOffset, 0, zOffset);
            }

            this.calculateBoundingBox();

            Bark_UtilityMain.LOGGER.log(Level.DEBUG, "Tree at " +
                            this.pieces.get(0).getBoundingBox().x0 + " " +
                            this.pieces.get(0).getBoundingBox().y0 + " " +
                            this.pieces.get(0).getBoundingBox().z0);
        }


    }
}

STConfiguredStructures.class :

import com.armanse.barkutil.Bark_UtilityMain;
import com.armanse.barkutil.init.FeatureInit;

import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.WorldGenRegistries;
import net.minecraft.world.gen.FlatGenerationSettings;
import net.minecraft.world.gen.feature.IFeatureConfig;
import net.minecraft.world.gen.feature.StructureFeature;

public class STConfiguredStructures {
	
    public static StructureFeature<?, ?> CONFIGURED_TREEMONUMENT = FeatureInit.TREEMONUMENT.get().configured(IFeatureConfig.NONE);

    
    public static void registerConfiguredStructures() {
        Registry<StructureFeature<?, ?>> registry = WorldGenRegistries.CONFIGURED_STRUCTURE_FEATURE;
        Registry.register(registry, new ResourceLocation(Bark_UtilityMain.MOD_ID, "configured_treemonument"), CONFIGURED_TREEMONUMENT);

        FlatGenerationSettings.STRUCTURE_FEATURES.put(FeatureInit.TREEMONUMENT.get(), CONFIGURED_TREEMONUMENT);
    }
}

I followed that example code for those who are wondering : https://github.com/TelepathicGrunt/StructureTutorialMod . Thank you

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.