Closed Scout24HD closed 3 years ago
You repeat most of the tutorial again to make the second structure. If this tutorial were to have a second structure, I would make the new structure class that points to the new pool file. Register it in STStructures. Then register the configuredstructure form in STConfiguredStructures. Then add it to the biomes I want.
You repeat most of the tutorial again to make the second structure. If this tutorial were to have a second structure, I would make the new structure class that points to the new pool file. Register it in STStructures. Then register the configuredstructure form in STConfiguredStructures. Then add it to the biomes I want.
i have do that already but now gives a "Exception generating new chunk" error have you any workspace to give an example?
this is the code: (i hope you can help me :))
public void setup2(final FMLCommonSetupEvent event)
{
event.enqueueWork(() -> {
STStructures.setupStructures();
STConfiguredStructures.registerConfiguredStructures();
//Meteor
//STStructures.setupStructures();
//STConfiguredStructures.registerConfiguredStructures();
});
}
public void biomeModification(final BiomeLoadingEvent event) {
RegistryKey.getOrCreateKey(Registry.BIOME_KEY, event.getName());
if (event.getName().equals(new ResourceLocation("boss_tools:moon_biom"))) {
event.getGeneration().getStructures().add(() -> STConfiguredStructures.CONFIGURED_RUN_DOWN_HOUSE);
}
if (event.getName().equals(new ResourceLocation("boss_tools:moon_biom"))) {
event.getGeneration().getStructures().add(() -> STConfiguredStructures.METEOR_CONFIGURED_RUN_DOWN_HOUSE);
// event.getGeneration().getStructures().add(() -> STConfiguredStructures.CONFIGURED_RUN_DOWN_HOUSE)
}
}
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_CODEC.getKey((Codec<? extends ChunkGenerator>) GETCODEC_METHOD.invoke(serverWorld.getChunkProvider().generator));
if (cgRL != null && cgRL.getNamespace().equals("terraforged")) return;
} catch (Exception e) {
// StructureTutorialMain.LOGGER.error("Was unable to check if " + serverWorld.dimension().location() + " is using Terraforged's ChunkGenerator.");
}
if(serverWorld.getChunkProvider().getChunkGenerator() instanceof FlatChunkGenerator &&
serverWorld.getDimensionType().equals(World.OVERWORLD)){
return;
}
Map<Structure<?>, StructureSeparationSettings> tempMap = new HashMap<>(serverWorld.getChunkProvider().generator.func_235957_b_().func_236195_a_());
tempMap.putIfAbsent(STStructures.RUN_DOWN_HOUSE.get(), DimensionStructuresSettings.field_236191_b_.get(STStructures.RUN_DOWN_HOUSE.get()));
// serverWorld.getChunkProvider().generator.func_235957_b_().func_236195_a_() = tempMap;
//meteor
// tempMap.putIfAbsent(STStructures.METEOR.get(), DimensionStructuresSettings.field_236191_b_.get(STStructures.METEOR.get()));
serverWorld.getChunkProvider().generator.func_235957_b_().field_236193_d_ = tempMap;
Map<Structure<?>, StructureSeparationSettings> tempMap1 = new HashMap<>(serverWorld.getChunkProvider().generator.func_235957_b_().func_236195_a_());
//tempMap.putIfAbsent(STStructures.RUN_DOWN_HOUSE.get(), DimensionStructuresSettings.field_236191_b_.get(STStructures.RUN_DOWN_HOUSE.get()));
// serverWorld.getChunkProvider().generator.func_235957_b_().func_236195_a_() = tempMap;
//meteor
tempMap1.putIfAbsent(STStructures.METEOR.get(), DimensionStructuresSettings.field_236191_b_.get(STStructures.METEOR.get()));
serverWorld.getChunkProvider().generator.func_235957_b_().field_236193_d_ = tempMap1;
ST CLASS:
public class STStructures {
/**
* We are using the Deferred Registry system to register our structure as this is the preferred way on Forge.
* This will handle registering the base structure for us at the correct time so we don't have to handle it ourselves.
* <p>
* HOWEVER, do note that Deferred Registries only work for anything that is a Forge Registry. This means that
* configured structures and configured features need to be registered directly to WorldGenRegistries as there
* is no Deferred Registry system for them.
*/
public static final DeferredRegister<Structure<?>> DEFERRED_REGISTRY_STRUCTURE = DeferredRegister.create(ForgeRegistries.STRUCTURE_FEATURES, "boss_tools");
//MEteor
public static final DeferredRegister<Structure<?>> METEOR_DEFERRED_REGISTRY_STRUCTURE = DeferredRegister.create(ForgeRegistries.STRUCTURE_FEATURES, "boss_tools");
/**
* Registers the structure itself and sets what its path is. In this case, the
* structure will have the resourcelocation of structure_tutorial:run_down_house.
* <p>
* It is always a good idea to register your Structures so that other mods and datapacks can
* use them too directly from the registries. It great for mod/datapacks compatibility.
* <p>
* IMPORTANT: Once you have set the name for your structure below and distributed your mod,
* changing the structure's registry name or removing the structure may cause log spam.
* This log spam won't break your worlds as forge already fixed the Mojang bug of removed structures wrecking worlds.
* https://github.com/MinecraftForge/MinecraftForge/commit/56e538e8a9f1b8e6ff847b9d2385484c48849b8d
* <p>
* However, users might not know that and think you are to blame for issues that doesn't exist.
* So it is best to keep your structure names the same as long as you can instead of changing them frequently.
*/
public static final RegistryObject<Structure<NoFeatureConfig>> RUN_DOWN_HOUSE = DEFERRED_REGISTRY_STRUCTURE.register("alien_structure", () -> (new AlienVillageStructure(NoFeatureConfig.field_236558_a_)));
//meteor
public static final RegistryObject<Structure<NoFeatureConfig>> METEOR = METEOR_DEFERRED_REGISTRY_STRUCTURE.register("meteor_structure", () -> (new MeteorStructure(NoFeatureConfig.field_236558_a_)));
/**
* This is where we set the rarity of your structures and determine if land conforms to it.
* See the comments in below for more details.
*/
public static void setupStructures() {
setupMapSpacingAndLand(
RUN_DOWN_HOUSE.get(), /* The instance of the structure */
new StructureSeparationSettings(24 /* average distance apart in chunks between spawn attempts */,
9 /* minimum distance apart in chunks between spawn attempts */,
1234567890 /* this modifies the seed of the structure so no two structures always spawn over each-other. Make this large and unique. */),
true);
// Add more structures here and so on
//meteor
setupMapSpacingAndLand(
METEOR.get(), /* The instance of the structure */
new StructureSeparationSettings(44 /* average distance apart in chunks between spawn attempts */,
9 /* minimum distance apart in chunks between spawn attempts */,
1234567890 /* this modifies the seed of the structure so no two structures always spawn over each-other. Make this large and unique. */),
true);
}
/**
* Adds the provided structure to the registry, and adds the separation settings.
* The rarity of the structure is determined based on the values passed into
* this method in the structureSeparationSettings argument.
* This method is called by setupStructures above.
*/
public static <F extends Structure<?>> void setupMapSpacingAndLand(
F structure,
StructureSeparationSettings structureSeparationSettings,
boolean transformSurroundingLand) {
/*
* We need to add our structures into the map in Structure class
* alongside vanilla structures or else it will cause errors.
*
* If the registration is setup properly for the structure,
* getRegistryName() should never return null.
*/
Structure.NAME_STRUCTURE_BIMAP.put(structure.getRegistryName().toString(), structure);
/*
* Whether surrounding land will be modified automatically to conform to the bottom of the structure.
* Basically, it adds land at the base of the structure like it does for Villages and Outposts.
* Doesn't work well on structure that have pieces stacked vertically or change in heights.
*
* Note: The air space this method will create will be filled with water if the structure is below sealevel.
* This means this is best for structure above sealevel so keep that in mind.
*
* NOISE_AFFECTING_FEATURES requires AccessTransformer (See resources/META-INF/accesstransformer.cfg)
*/
if (transformSurroundingLand) {
Structure.field_236384_t_ =
ImmutableList.<Structure<?>>builder()
.addAll(Structure.field_236384_t_)
.add(structure)
.build();
/*
* This is the map that holds the default spacing of all structures.
* Always add your structure to here so that other mods can utilize it if needed.
*
* However, while it does propagate the spacing to some correct dimensions from this map,
* it seems it doesn't always work for code made dimensions as they read from this list beforehand.
*
* Instead, we will use the WorldEvent.Load event in StructureTutorialMain to add the structure
* spacing from this list into that dimension or to do dimension blacklisting properly.
* We also use our entry in DimensionStructuresSettings.DEFAULTS in WorldEvent.Load as well.
*
* DEFAULTS requires AccessTransformer (See resources/META-INF/accesstransformer.cfg)
*/
DimensionStructuresSettings.field_236191_b_ =
ImmutableMap.<Structure<?>, StructureSeparationSettings>builder()
.putAll(DimensionStructuresSettings.field_236191_b_)
.put(structure, structureSeparationSettings)
.build();
/*
* There are very few mods that relies on seeing your structure in the noise settings registry before the world is made.
*
* You may see some mods add their spacings to DimensionSettings.BUILTIN_OVERWORLD instead of the NOISE_GENERATOR_SETTINGS loop below but
* that field only applies for the default overworld and won't add to other worldtypes or dimensions (like amplified or Nether).
* So yeah, don't do DimensionSettings.BUILTIN_OVERWORLD. Use the NOISE_GENERATOR_SETTINGS loop below instead if you must.
*/
WorldGenRegistries.NOISE_SETTINGS.getEntries().forEach(settings -> {
Map<Structure<?>, StructureSeparationSettings> structureMap = settings.getValue().getStructures().func_236195_a_();
/*
* Pre-caution in case a mod makes the structure map immutable like datapacks do.
* I take no chances myself. You never know what another mods does...
*
* structureConfig requires AccessTransformer (See resources/META-INF/accesstransformer.cfg)
*/
if (structureMap instanceof ImmutableMap) {
Map<Structure<?>, StructureSeparationSettings> tempMap = new HashMap<>(structureMap);
tempMap.put(structure, structureSeparationSettings);
// settings.getValue().getStructures().func_236195_a_() = tempMap;
} else {
structureMap.put(structure, structureSeparationSettings);
}
});
}
}
}
STConfiguredST...Class
public class STConfiguredStructures {
public static StructureFeature<?, ?> CONFIGURED_RUN_DOWN_HOUSE = STStructures.RUN_DOWN_HOUSE.get().withConfiguration(IFeatureConfig.NO_FEATURE_CONFIG);
public static StructureFeature<?, ?> METEOR_CONFIGURED_RUN_DOWN_HOUSE = STStructures.METEOR.get().withConfiguration(IFeatureConfig.NO_FEATURE_CONFIG);
public static void registerConfiguredStructures() {
Registry<StructureFeature<?, ?>> registry = WorldGenRegistries.CONFIGURED_STRUCTURE_FEATURE;
Registry.register(registry, new ResourceLocation("boss_tools", "configured_run_down_house"), CONFIGURED_RUN_DOWN_HOUSE);
Registry.register(registry, new ResourceLocation("boss_tools", "meteor_configured_run_down_house"), METEOR_CONFIGURED_RUN_DOWN_HOUSE);
// FlatGenerationSettings.field_236932_a_.put(STStructures.RUN_DOWN_HOUSE, CONFIGURED_RUN_DOWN_HOUSE);
FlatGenerationSettings.STRUCTURES.put(STStructures.RUN_DOWN_HOUSE.get(), CONFIGURED_RUN_DOWN_HOUSE);
FlatGenerationSettings.STRUCTURES.put(STStructures.METEOR.get(), METEOR_CONFIGURED_RUN_DOWN_HOUSE);
}
}
ok i have found the error (was a stupid error xD)
Ah nice! You figured it out before i was able to get back on lol.
hi i have a question, how can i add a second structure?