Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[1.15.2] Ore generation with DeferredRegistry


GenElectrovise
 Share

Recommended Posts

HI! It's what the title says. I am looking to generate standard Block s with registry names amethyst_ore_overworld amethyst_ore_end , and amethyst_ore_nether in their respective dimensions, however I don't know the correct type of DeferredRegister to use. I think it is one of:

FEATURE, DECORATORS, CHUNK_GENERATOR, or possibly WORLD_CARVER , though of those I suspect, from looking at the Feature class of MC, it should be FEATURE ,  although I don't know how I would implement that. Right now I mostly get a lot of compiler errors saying that Feature has an invalid type argument, but again, I don't know what I'm aiming for as I don't know how many additional classes I may need for it. In 1.7.10, I used a full devoted class ; in 1.12.2 the generator was made in one line ;  in 1.15.2 I have seen people do it without DeferredRegistry , but not with it.

 

Thanks!

How to ask a good coding question: https://stackoverflow.com/help/how-to-ask

Give any applicable of: logs, code, desired effects, and actual effects. Be thorough or we can't help you, and don't post code without putting it in a code block (the <> button on the post - select "C-type Language"): syntax highlighting makes everything easier, and it keeps the post tidy.

 

My own mod, Magiks Most Evile! GitHub (https://github.com/GenElectrovise/MagiksMostEvile) Wiki (https://magiksmostevile.fandom.com/wiki/Magiks_Most_Evile_Wiki)

Edit your own signature at https://www.minecraftforge.net/forum/settings/signature/

Link to comment
Share on other sites

Ore generators are FEATURES. You can look at the vanilla code for how it creates its own oregen.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Ok I've been trying and have been left going round in circles. Might need a bit of a pointer as to where to go from here :)

The problem I'm having right now is a compiler error on line 

new EvileOreFeature(EvileOreFeatureConfig::deserialize));

In EvileRegistry, which says:

The type of deserialize(Dynamic<?>) from the type EvileOreFeatureConfig is EvileOreFeatureConfig, this is incompatible with the descriptor's return type: OreFeatureConfig

And all I seem to be able to do is shift the issue elsewhere, eg to the constructor of EvileOreFeature by changing EvileOreFeature's parameters to fit, which then throws a similar error

 

I was about to go down the route of making a whole new Features class for myself, but I thought that ore generation should probably be simpler than that, so I thought I'd ask for some help instead :)

 

Here are my classes:
 

Spoiler

Relevant bits of my EvileRegistry


private static final DeferredRegister<Feature<?>> ORE_GEN = new DeferredRegister<>(ForgeRegistries.FEATURES,
			Main.MODID);

public static final RegistryObject<EvileOreFeature> AMETHYST_ORE_OVERWORLD_GEN = ORE_GEN
			.register("amethyst_ore_overworld_gen", () -> new EvileOreFeature(EvileOreFeatureConfig::deserialize));

 

Spoiler

EvileOreFeature (Copied from OreFeature, but done so I can edit more easily)


package genelectrovise.magiksmostevile.common.world.gen;

import java.util.BitSet;
import java.util.Random;
import java.util.function.Function;

import com.mojang.datafixers.Dynamic;

import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.IWorld;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.GenerationSettings;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.OreFeatureConfig;

/**
 * Copied from OreFeature.class
 * @author adam_
 *
 */
public class EvileOreFeature extends Feature<OreFeatureConfig> {
	public EvileOreFeature(Function<Dynamic<?>, ? extends OreFeatureConfig> p_i51472_1_) {
		super(p_i51472_1_);
	}

	public boolean place(IWorld worldIn, ChunkGenerator<? extends GenerationSettings> generator, Random rand,
			BlockPos pos, OreFeatureConfig config) {
		float f = rand.nextFloat() * (float) Math.PI;
		float f1 = (float) config.size / 8.0F;
		int i = MathHelper.ceil(((float) config.size / 16.0F * 2.0F + 1.0F) / 2.0F);
		double d0 = (double) ((float) pos.getX() + MathHelper.sin(f) * f1);
		double d1 = (double) ((float) pos.getX() - MathHelper.sin(f) * f1);
		double d2 = (double) ((float) pos.getZ() + MathHelper.cos(f) * f1);
		double d3 = (double) ((float) pos.getZ() - MathHelper.cos(f) * f1);
		int j = 2;
		double d4 = (double) (pos.getY() + rand.nextInt(3) - 2);
		double d5 = (double) (pos.getY() + rand.nextInt(3) - 2);
		int k = pos.getX() - MathHelper.ceil(f1) - i;
		int l = pos.getY() - 2 - i;
		int i1 = pos.getZ() - MathHelper.ceil(f1) - i;
		int j1 = 2 * (MathHelper.ceil(f1) + i);
		int k1 = 2 * (2 + i);

		for (int l1 = k; l1 <= k + j1; ++l1) {
			for (int i2 = i1; i2 <= i1 + j1; ++i2) {
				if (l <= worldIn.getHeight(Heightmap.Type.OCEAN_FLOOR_WG, l1, i2)) {
					return this.func_207803_a(worldIn, rand, config, d0, d1, d2, d3, d4, d5, k, l, i1, j1, k1);
				}
			}
		}

		return false;
	}

	protected boolean func_207803_a(IWorld worldIn, Random random, OreFeatureConfig config, double p_207803_4_,
			double p_207803_6_, double p_207803_8_, double p_207803_10_, double p_207803_12_, double p_207803_14_,
			int p_207803_16_, int p_207803_17_, int p_207803_18_, int p_207803_19_, int p_207803_20_) {
		int i = 0;
		BitSet bitset = new BitSet(p_207803_19_ * p_207803_20_ * p_207803_19_);
		BlockPos.Mutable blockpos$mutable = new BlockPos.Mutable();
		double[] adouble = new double[config.size * 4];

		for (int j = 0; j < config.size; ++j) {
			float f = (float) j / (float) config.size;
			double d0 = MathHelper.lerp((double) f, p_207803_4_, p_207803_6_);
			double d2 = MathHelper.lerp((double) f, p_207803_12_, p_207803_14_);
			double d4 = MathHelper.lerp((double) f, p_207803_8_, p_207803_10_);
			double d6 = random.nextDouble() * (double) config.size / 16.0D;
			double d7 = ((double) (MathHelper.sin((float) Math.PI * f) + 1.0F) * d6 + 1.0D) / 2.0D;
			adouble[j * 4 + 0] = d0;
			adouble[j * 4 + 1] = d2;
			adouble[j * 4 + 2] = d4;
			adouble[j * 4 + 3] = d7;
		}

		for (int l2 = 0; l2 < config.size - 1; ++l2) {
			if (!(adouble[l2 * 4 + 3] <= 0.0D)) {
				for (int j3 = l2 + 1; j3 < config.size; ++j3) {
					if (!(adouble[j3 * 4 + 3] <= 0.0D)) {
						double d12 = adouble[l2 * 4 + 0] - adouble[j3 * 4 + 0];
						double d13 = adouble[l2 * 4 + 1] - adouble[j3 * 4 + 1];
						double d14 = adouble[l2 * 4 + 2] - adouble[j3 * 4 + 2];
						double d15 = adouble[l2 * 4 + 3] - adouble[j3 * 4 + 3];
						if (d15 * d15 > d12 * d12 + d13 * d13 + d14 * d14) {
							if (d15 > 0.0D) {
								adouble[j3 * 4 + 3] = -1.0D;
							} else {
								adouble[l2 * 4 + 3] = -1.0D;
							}
						}
					}
				}
			}
		}

		for (int i3 = 0; i3 < config.size; ++i3) {
			double d11 = adouble[i3 * 4 + 3];
			if (!(d11 < 0.0D)) {
				double d1 = adouble[i3 * 4 + 0];
				double d3 = adouble[i3 * 4 + 1];
				double d5 = adouble[i3 * 4 + 2];
				int k = Math.max(MathHelper.floor(d1 - d11), p_207803_16_);
				int k3 = Math.max(MathHelper.floor(d3 - d11), p_207803_17_);
				int l = Math.max(MathHelper.floor(d5 - d11), p_207803_18_);
				int i1 = Math.max(MathHelper.floor(d1 + d11), k);
				int j1 = Math.max(MathHelper.floor(d3 + d11), k3);
				int k1 = Math.max(MathHelper.floor(d5 + d11), l);

				for (int l1 = k; l1 <= i1; ++l1) {
					double d8 = ((double) l1 + 0.5D - d1) / d11;
					if (d8 * d8 < 1.0D) {
						for (int i2 = k3; i2 <= j1; ++i2) {
							double d9 = ((double) i2 + 0.5D - d3) / d11;
							if (d8 * d8 + d9 * d9 < 1.0D) {
								for (int j2 = l; j2 <= k1; ++j2) {
									double d10 = ((double) j2 + 0.5D - d5) / d11;
									if (d8 * d8 + d9 * d9 + d10 * d10 < 1.0D) {
										int k2 = l1 - p_207803_16_ + (i2 - p_207803_17_) * p_207803_19_
												+ (j2 - p_207803_18_) * p_207803_19_ * p_207803_20_;
										if (!bitset.get(k2)) {
											bitset.set(k2);
											blockpos$mutable.setPos(l1, i2, j2);
											if (config.target.func_214738_b()
													.test(worldIn.getBlockState(blockpos$mutable))) {
												worldIn.setBlockState(blockpos$mutable, config.state, 2);
												++i;
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}

		return i > 0;
	}

}

 

Spoiler

EvileOreFeatureConfig (Again mostly copied, but for similar reasons)


package genelectrovise.magiksmostevile.common.world.gen;

import java.util.Arrays;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import com.google.common.collect.ImmutableMap;
import com.mojang.datafixers.Dynamic;
import com.mojang.datafixers.types.DynamicOps;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.pattern.BlockMatcher;

public class EvileOreFeatureConfig {

	public final EvileOreFeatureConfig.EvileOreFillerBlockType target;
	public final int size;
	public final BlockState state;

	public EvileOreFeatureConfig(EvileOreFeatureConfig.EvileOreFillerBlockType target, BlockState state, int size) {
		this.size = size;
		this.state = state;
		this.target = target;
	}

	public <T> Dynamic<T> serialize(DynamicOps<T> ops) {
		return new Dynamic<>(ops,
				ops.createMap(ImmutableMap.of(ops.createString("size"), ops.createInt(this.size),
						ops.createString("target"), ops.createString(this.target.func_214737_a()),
						ops.createString("state"), BlockState.serialize(ops, this.state).getValue())));
	}

	public static EvileOreFeatureConfig deserialize(Dynamic<?> p_214641_0_) {
		int i = p_214641_0_.get("size").asInt(0);
		EvileOreFeatureConfig.EvileOreFillerBlockType orefeatureconfig$fillerblocktype = EvileOreFeatureConfig.EvileOreFillerBlockType
				.func_214736_a(p_214641_0_.get("target").asString(""));
		BlockState blockstate = p_214641_0_.get("state").map(BlockState::deserialize)
				.orElse(Blocks.AIR.getDefaultState());
		return new EvileOreFeatureConfig(orefeatureconfig$fillerblocktype, blockstate, i);
	}

	public static enum EvileOreFillerBlockType implements net.minecraftforge.common.IExtensibleEnum {
		NATURAL_STONE("natural_stone", (p_214739_0_) -> {
			if (p_214739_0_ == null) {
				return false;
			} else {
				Block block = p_214739_0_.getBlock();
				return block == Blocks.STONE || block == Blocks.GRANITE || block == Blocks.DIORITE
						|| block == Blocks.ANDESITE;
			}
		}), NETHERRACK("netherrack", new BlockMatcher(Blocks.NETHERRACK));

		private static final Map<String, EvileOreFeatureConfig.EvileOreFillerBlockType> field_214741_c = Arrays
				.stream(values()).collect(Collectors.toMap(EvileOreFeatureConfig.EvileOreFillerBlockType::func_214737_a,
						(p_214740_0_) -> {
							return p_214740_0_;
						}));
		private final String field_214742_d;
		private final Predicate<BlockState> field_214743_e;

		private EvileOreFillerBlockType(String p_i50618_3_, Predicate<BlockState> p_i50618_4_) {
			this.field_214742_d = p_i50618_3_;
			this.field_214743_e = p_i50618_4_;
		}

		public String func_214737_a() {
			return this.field_214742_d;
		}

		public static EvileOreFeatureConfig.EvileOreFillerBlockType func_214736_a(String p_214736_0_) {
			return field_214741_c.get(p_214736_0_);
		}

		public Predicate<BlockState> func_214738_b() {
			return this.field_214743_e;
		}

		public static EvileOreFillerBlockType create(String enumName, String p_i50618_3_,
				Predicate<BlockState> p_i50618_4_) {
			throw new IllegalStateException("Enum not extended");
		}

		@Override
		@Deprecated
		public void init() {
			field_214741_c.put(func_214737_a(), this);
		}

	}
}

 

 

How to ask a good coding question: https://stackoverflow.com/help/how-to-ask

Give any applicable of: logs, code, desired effects, and actual effects. Be thorough or we can't help you, and don't post code without putting it in a code block (the <> button on the post - select "C-type Language"): syntax highlighting makes everything easier, and it keeps the post tidy.

 

My own mod, Magiks Most Evile! GitHub (https://github.com/GenElectrovise/MagiksMostEvile) Wiki (https://magiksmostevile.fandom.com/wiki/Magiks_Most_Evile_Wiki)

Edit your own signature at https://www.minecraftforge.net/forum/settings/signature/

Link to comment
Share on other sites

1 hour ago, GenElectrovise said:

Feature<OreFeatureConfig>

 

1 hour ago, GenElectrovise said:

EvileOreFeatureConfig {

Hmm....

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Sorry it took sooooooo long for me to respond -- another project had to take over for a bit.

 

I have resolved the compiler errors I previously was asking about -- by deleting my copied classes, then readding them and simply extending the appropriate MC classes with a view to overriding their methods in the future.

 

However I don't believe it is being registered properly.

There are no errors, however my generator does not appear in the [ne.mi.re.ForgeRegistry/REGISTRYDUMP]: Registry Name: minecraft:feature  , so I assume that that means it isn't being registered (all of my other items and blocks appear in their respective registry dumps).

Any ideas how I can get the game to acknowledge my Feature's existance?

 

It is now being registered after I realised I hadn't been registering its registry. Oops!

Still no ore spawning though.

 

I haven't come across any place to put in AMETHYST_ORE as a parameter yet, so I'm not making anything happen, even if it is now being registered properly. Is there some documentation on use of DeferredRegistry? Because noone seems to have posted anything about it anywhere, and of course MC doesn't use it as it's part of Forge, so there's no help coming from there.

 

Ps I now have a github repo

Edited by GenElectrovise
More information

How to ask a good coding question: https://stackoverflow.com/help/how-to-ask

Give any applicable of: logs, code, desired effects, and actual effects. Be thorough or we can't help you, and don't post code without putting it in a code block (the <> button on the post - select "C-type Language"): syntax highlighting makes everything easier, and it keeps the post tidy.

 

My own mod, Magiks Most Evile! GitHub (https://github.com/GenElectrovise/MagiksMostEvile) Wiki (https://magiksmostevile.fandom.com/wiki/Magiks_Most_Evile_Wiki)

Edit your own signature at https://www.minecraftforge.net/forum/settings/signature/

Link to comment
Share on other sites

6 hours ago, GenElectrovise said:

Is there some documentation on use of DeferredRegistry?

The class is called DeferredRegister and the documentation is on the javadoc on the top of it. 

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Link to comment
Share on other sites

22 hours ago, Cadiboo said:

The class is called DeferredRegister and the documentation is on the javadoc on the top of it. 

I am aware of this and have been very successfully using this for Items and Blocks. My question is how to generate ores in the world, registering the Feature / Generator using DeferredRegister.

 

Following the advice of my own signature, I have found another thread asking about general ore generation in 1.15 and have combined that information with MC source to create this bodged, yet functional method which is called on the FMLLoadCompleteEvent being fired:

Spoiler

 


public static void addOverworldOres() {
		for (Biome biome : ForgeRegistries.BIOMES) {
			biome.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES,
					Feature.ORE
							.func_225566_b_(new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE,
									EvileRegistry.AMETHYST_ORE_OVERWORLD.get().getDefaultState(), 7))
							.func_227228_a_(
									Placement.COUNT_DEPTH_AVERAGE.func_227446_a_(new DepthAverageConfig(1, 100, 25))));

		}
	}

 

I would much rather use DeferredRegistry, however no-one appears to know how to do that. Or else I haven't been able to work it out from their hints.

I believe that you would do something like this to register it?

Spoiler

private static final DeferredRegister<Feature<?>> FEATURES = new DeferredRegister<>(ForgeRegistries.FEATURES,
			Main.MODID);

public static final RegistryObject<EvileOreFeature> AMETHYST_ORE_OVERWORLD_GEN = FEATURES
			.register("amethyst_ore_overworld_gen", () -> new EvileOreFeature(EvileOreFeatureConfig::deserialize));

 

 

If by some miracle that is correct, I seem to be getting an endless number of compiler errors in my EvileOreFeature and EvileOreFeatureConfig classes. How does one make a new FillerBlockType? Eg for generating ores in the end dimensions?

I have been trying to use the create(String enumName, String p_i50618_3_, Predicate<BlockState> p_i50618_4_) method, however I can't work out what to pass into the last parameter. So far I have this:

Spoiler

 


public static final FillerBlockType FILLER_BLOCK_END_STONE = FillerBlockType.create("filler_block_end_stone", Blocks.END_STONE, new Predicate<BlockState>(Blocks.END_STONE.getDefaultState()));

... which throws 2 compiler errors, saying: 

 

"The method create(String, String, Predicate<BlockState>) in the type OreFeatureConfig.FillerBlockType is not applicable for the arguments (String, Block, Predicate<BlockState>)"

Which seems pretty self explanatory, as a Block is certainly not a String -- I just don't know what to put there.

 

AND 

 

"Cannot instantiate the type Predicate<BlockState>

Which I am less sure of.

 

Oh and I don't even think it will work as all the method does is:

Spoiler

throw new IllegalStateException("Enum not extended");

 

...sooooooo yeah. Any tips?

 

In a nutshell:

How to create new FillerBlockType for ore gen in other dimensions

How to do this with DeferredRegistry

 

I can't think of anything else to say, so I'll just make sure my GitHub repo is updated and await someone's reponse.

Many thanks, 

GenElectrovise

Edited by GenElectrovise
Heeding my own signature

How to ask a good coding question: https://stackoverflow.com/help/how-to-ask

Give any applicable of: logs, code, desired effects, and actual effects. Be thorough or we can't help you, and don't post code without putting it in a code block (the <> button on the post - select "C-type Language"): syntax highlighting makes everything easier, and it keeps the post tidy.

 

My own mod, Magiks Most Evile! GitHub (https://github.com/GenElectrovise/MagiksMostEvile) Wiki (https://magiksmostevile.fandom.com/wiki/Magiks_Most_Evile_Wiki)

Edit your own signature at https://www.minecraftforge.net/forum/settings/signature/

Link to comment
Share on other sites

On 2/11/2020 at 7:13 AM, GenElectrovise said:

Oh and I don't even think it will work as all the method does is:

   Reveal hidden contents


throw new IllegalStateException("Enum not extended");

 

...sooooooo yeah. Any tips?

Read the documentation on IExtensibleEnum.

I’ll take a look into world gen myself and report back (never done anything except super basic ore gen back in 1.12.2)

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Link to comment
Share on other sites

On 2/13/2020 at 2:32 AM, Cadiboo said:

Read the documentation on IExtensibleEnum.

I’ll take a look into world gen myself and report back (never done anything except super basic ore gen back in 1.12.2)

Can do! Thanks!

How to ask a good coding question: https://stackoverflow.com/help/how-to-ask

Give any applicable of: logs, code, desired effects, and actual effects. Be thorough or we can't help you, and don't post code without putting it in a code block (the <> button on the post - select "C-type Language"): syntax highlighting makes everything easier, and it keeps the post tidy.

 

My own mod, Magiks Most Evile! GitHub (https://github.com/GenElectrovise/MagiksMostEvile) Wiki (https://magiksmostevile.fandom.com/wiki/Magiks_Most_Evile_Wiki)

Edit your own signature at https://www.minecraftforge.net/forum/settings/signature/

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.

Guest
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.

 Share



×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.