Jump to content

[1.7.10]Custom Dimension that generates like the overworld


Elrol_Arrowsend

Recommended Posts

I am trying to make a mirror dimension that looks exactly like the overworld, using the same seed and the same world generator, so that when a players uses a mirror it teleports them to the same coordinates in the mirror dimension and it looks the same. If anyone can point me to the file in minecraft that generates the biomes/blocks/anything else and/or can help in any way, I would be grateful.

 

Thanks in advance

Link to comment
Share on other sites

Do you mean looks exactly the same with how it was generated? Or player built stuff must be mirrored too?

First one is very easy - follow any dimension creation tutorial, to the point where you created world provider. Done. In short: do not override any world gen methods in your world provider.

Second one - a bit harder, but possible.

Link to comment
Share on other sites

basically I want it to generate the world the exact same way, the blocks that it will generate however will not be stone, or dirt, but be Mirror stone and mirror dirt, every block in the dimension will be a mirror version of the original, and I will have a mirror item and where ever you are in the world is where it will put you in the mirror dimension

Link to comment
Share on other sites

basically I want it to generate the world the exact same way, the blocks that it will generate however will not be stone, or dirt, but be Mirror stone and mirror dirt, every block in the dimension will be a mirror version of the original, and I will have a mirror item and where ever you are in the world is where it will put you in the mirror dimension

Then create new

IChunkProvider

and copy everything from

ChunkProviderGenerate

. Go to

provideChunk

method and before

=new Chunk

line loop through blocks in

Block[] ablock

and replace ones that you want to mirror with mirrored version. Also, don't forget to change metadata if needed (

byte[] abyte

is metadata).

Link to comment
Share on other sites

I understood the majority of what you said, here is the bit of code I think you are referring to. Where in it can I use my blocks to generate instead of minecraft's blocks

 

 

 

this.rand.setSeed((long)p_73154_1_ * 341873128712L + (long)p_73154_2_ * 132897987541L);

        Block[] ablock = new Block[65536];

        byte[] abyte = new byte[65536];

        this.func_147424_a(p_73154_1_, p_73154_2_, ablock);

        this.biomesForGeneration = this.worldObj.getWorldChunkManager().loadBlockGeneratorData(this.biomesForGeneration, p_73154_1_ * 16, p_73154_2_ * 16, 16, 16);

        this.replaceBlocksForBiome(p_73154_1_, p_73154_2_, ablock, abyte, this.biomesForGeneration);

        this.caveGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);

        this.ravineGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);

 

        if (this.mapFeaturesEnabled)

        {

            this.mineshaftGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);

            this.villageGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);

            this.strongholdGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);

            this.scatteredFeatureGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);

        }

 

        Chunk chunk = new Chunk(this.worldObj, ablock, abyte, p_73154_1_, p_73154_2_);

        byte[] abyte1 = chunk.getBiomeArray();

 

        for (int k = 0; k < abyte1.length; ++k)

        {

            abyte1[k] = (byte)this.biomesForGeneration[k].biomeID;

        }

 

Link to comment
Share on other sites

I understood the majority of what you said, here is the bit of code I think you are referring to. Where in it can I use my blocks to generate instead of minecraft's blocks

 

 

 

this.rand.setSeed((long)p_73154_1_ * 341873128712L + (long)p_73154_2_ * 132897987541L);

        Block[] ablock = new Block[65536];

        byte[] abyte = new byte[65536];

        this.func_147424_a(p_73154_1_, p_73154_2_, ablock);

        this.biomesForGeneration = this.worldObj.getWorldChunkManager().loadBlockGeneratorData(this.biomesForGeneration, p_73154_1_ * 16, p_73154_2_ * 16, 16, 16);

        this.replaceBlocksForBiome(p_73154_1_, p_73154_2_, ablock, abyte, this.biomesForGeneration);

        this.caveGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);

        this.ravineGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);

 

        if (this.mapFeaturesEnabled)

        {

            this.mineshaftGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);

            this.villageGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);

            this.strongholdGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);

            this.scatteredFeatureGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);

        }

 

        Chunk chunk = new Chunk(this.worldObj, ablock, abyte, p_73154_1_, p_73154_2_);

        byte[] abyte1 = chunk.getBiomeArray();

 

        for (int k = 0; k < abyte1.length; ++k)

        {

            abyte1[k] = (byte)this.biomesForGeneration[k].biomeID;

        }

 

Yes, this is correct part of the code. As you can see, there's

Block[]

there, which as you may guess holds blocks for new chunk. Iterate through it and when you encounter block hat can be mirrored, replace it with mirrored version. You have to do this before

Chunk chunk = new Chunk

and after last block generation code (in this case -

this.scatteredFeatureGenerator.func_151539_a

).

Link to comment
Share on other sites

Should I add my blocks like :

 

Block[] ablock = new Block[65536]{ModBlocks.darkStone, ModBlocks.darkGrass, ModBlocks.darkDirt, etc}

 

or is there another way. and do the darker versions need to be in order so that they generate correctly (if I have dark cobble first would it replace the stone with dark cobble when it generates?)

Link to comment
Share on other sites

Should I add my blocks like :

 

Block[] ablock = new Block[65536]{ModBlocks.darkStone, ModBlocks.darkGrass, ModBlocks.darkDirt, etc}

 

or is there another way. and do the darker versions need to be in order so that they generate correctly (if I have dark cobble first would it replace the stone with dark cobble when it generates?)

No. You leave everything as it is and before

Chunk chunk = new Chunk(this.worldObj, ablock, abyte, p_73154_1_, p_73154_2_);

line, you add new code that iterates thorugh

blocks

and "mirrors" them. Pseudo example:

for(int i = 0; i < blocks.length; i++){
if(blocks[i].canBeMirrored){
	blocks[i] = blocks[i].mirror();
}
}

Link to comment
Share on other sites

This what I came up with, I think it will work for me

 

 

private static Block[] OriginalBlocks = new Block[]{Blocks.stone, Blocks.dirt, Blocks.grass};
[/Code]

[code]
public Chunk provideChunk(int p_73154_1_, int p_73154_2_)
    {
        this.rand.setSeed((long)p_73154_1_ * 341873128712L + (long)p_73154_2_ * 132897987541L);
        Block[] ablock = new Block[65536];
        
        for(int i = 0; i < ablock.length; i++){
        	if(this.canBeMirrored(ablock[i])){
        		ablock[i] = this.mirror(ablock[i]);
        	}
        }
        
        byte[] abyte = new byte[65536];
        this.func_147424_a(p_73154_1_, p_73154_2_, ablock);
        this.biomesForGeneration = this.worldObj.getWorldChunkManager().loadBlockGeneratorData(this.biomesForGeneration, p_73154_1_ * 16, p_73154_2_ * 16, 16, 16);
        this.replaceBlocksForBiome(p_73154_1_, p_73154_2_, ablock, abyte, this.biomesForGeneration);
        this.caveGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);
        this.ravineGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);

        if (this.mapFeaturesEnabled)
        {
            this.mineshaftGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);
            this.villageGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);
            this.strongholdGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);
            this.scatteredFeatureGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);
        }

        Chunk chunk = new Chunk(this.worldObj, ablock, abyte, p_73154_1_, p_73154_2_);
        byte[] abyte1 = chunk.getBiomeArray();

        for (int k = 0; k < abyte1.length; ++k)
        {
            abyte1[k] = (byte)this.biomesForGeneration[k].biomeID;
        }

        chunk.generateSkylightMap();
        return chunk;
    }
[/Code]

[Code]
    public static boolean canBeMirrored(Block block){
	for(int i=0; i > OriginalBlocks.length; i++){
		if(block == OriginalBlocks[i]){
			return true;
		}
	}
	return false;

}
[/Code]

[Code]
    public static Block mirror(Block original){
    	Block Mirror = null;
    	if(original == Blocks.stone){
    		Mirror = ModBlocks.darkStone;
    	}else if(original == Blocks.dirt){
                Mirror = ModBlocks.darkDirt;
        }else if(original == Blocks.grass){
                Mirror = ModBlocks.darkGrass;
        }
    	return Mirror;
    }

 

 

Link to comment
Share on other sites

This what I came up with, I think it will work for me

 

 

private static Block[] OriginalBlocks = new Block[]{Blocks.stone, Blocks.dirt, Blocks.grass};
[/Code]

[code]
public Chunk provideChunk(int p_73154_1_, int p_73154_2_)
    {
        this.rand.setSeed((long)p_73154_1_ * 341873128712L + (long)p_73154_2_ * 132897987541L);
        Block[] ablock = new Block[65536];
        
        for(int i = 0; i < ablock.length; i++){
        	if(this.canBeMirrored(ablock[i])){
        		ablock[i] = this.mirror(ablock[i]);
        	}
        }
        
        byte[] abyte = new byte[65536];
        this.func_147424_a(p_73154_1_, p_73154_2_, ablock);
        this.biomesForGeneration = this.worldObj.getWorldChunkManager().loadBlockGeneratorData(this.biomesForGeneration, p_73154_1_ * 16, p_73154_2_ * 16, 16, 16);
        this.replaceBlocksForBiome(p_73154_1_, p_73154_2_, ablock, abyte, this.biomesForGeneration);
        this.caveGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);
        this.ravineGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);

        if (this.mapFeaturesEnabled)
        {
            this.mineshaftGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);
            this.villageGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);
            this.strongholdGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);
            this.scatteredFeatureGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);
        }

        Chunk chunk = new Chunk(this.worldObj, ablock, abyte, p_73154_1_, p_73154_2_);
        byte[] abyte1 = chunk.getBiomeArray();

        for (int k = 0; k < abyte1.length; ++k)
        {
            abyte1[k] = (byte)this.biomesForGeneration[k].biomeID;
        }

        chunk.generateSkylightMap();
        return chunk;
    }
[/Code]

[Code]
    public static boolean canBeMirrored(Block block){
	for(int i=0; i > OriginalBlocks.length; i++){
		if(block == OriginalBlocks[i]){
			return true;
		}
	}
	return false;

}
[/Code]

[Code]
    public static Block mirror(Block original){
    	Block Mirror = null;
    	if(original == Blocks.stone){
    		Mirror = ModBlocks.darkStone;
    	}else if(original == Blocks.dirt){
                Mirror = ModBlocks.darkDirt;
        }else if(original == Blocks.grass){
                Mirror = ModBlocks.darkGrass;
        }
    	return Mirror;
    }

 

 

Was typing reply to your previous comment and you posted this one... Ok, let's take a look...

No, it will not work, but you are very close. Because stone, dirt, grass... are generated in

func_147424_a

, which is called after you iterate through blocks which are empty at this moment. Move your iteration (for loops) to following location:

-In

provideChunk

method. [X]

-After all blocks are generated (last generation code line:

this.scatteredFeatureGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);

) [0]

-Before new chunk is created (

Chunk chunk = new Chunk(this.worldObj, ablock, abyte, p_73154_1_, p_73154_2_);

). [X]

 

[X] means that code is convenient for this condition.

[0] means it's not.

 

I really don't like to give answers directly, so please, try to understand...

Link to comment
Share on other sites

I understand that, one last thing and I think I will be well on my way to getting everything added. How would I go about adding a check for the different woods for example, since the wood is dependent on the metadata, I guess I am asking how I would get a specific block with metadata into a Block[]

 

I do thank you very much for all the assistance with my issue. Once I have my code working I will defiantly +1 you

Link to comment
Share on other sites

I also came up with what I hope is a better way to test/mirror the blocks. I made another block list containing my mirror versions, and I changed the .mirror to look like this:

 


public static boolean canBeMirrored(Block block){
for(int i=0; i > OriginalBlocks.length; i++){
if(block == OriginalBlocks[i]){
return true;
}
}
return false;

}
   
    public static Block mirror(Block original){
    for(int i=0; i > OriginalBlocks.length; i++){
if(original == OriginalBlocks[i]){
return MirrorBlocks[i];
}
}
return original;
    }
[/Code]

Link to comment
Share on other sites

First of all, there are 2 arrays in

provideChunk

:

Block[]

and

byte

. First one holds blocks and second one holds metadata.

Second, do you know what

java.util.Map<K, V>

is? If not, you must. Go and read now. RIGHT NOW!

Link to comment
Share on other sites

I cant seem to find java.util.Map<K, V>

however, I was wondering if there was a way to put the byte, into an int and have that set the metadata for a block so that I can run it in my code.

 

is it possible to cast a byte to an int, and is there a thing like

Block.setMetadata((int)byte)[/Code]

 

the help I have gotten so excited from the help you have given me. It has really helped me out.

Link to comment
Share on other sites

I cant seem to find java.util.Map<K, V>

however, I was wondering if there was a way to put the byte, into an int and have that set the metadata for a block so that I can run it in my code.

 

is it possible to cast a byte to an int, and is there a thing like

Block.setMetadata((int)byte)[/Code]

 
the help I have gotten so excited from the help you have given me. It has really helped me out.

Ok, let me explain you what [code]java.util.Map

is first: http://lmgtfy.com/?q=java.util.Map

Now, that you know what

Map

is, rewrite your helper code using maps instead of arrays. You will see, it will get a lot cleaner.

Also, yes you can cast byte to int and backwards, but why?

Link to comment
Share on other sites

I was testing something out, but when I just copy the entire file, change the bare minimum so that the code works, it generated the right world seed but the chunk seed is set with a random, and I cant find how to get a seed for the chunks. I can use this to get the chunk for the cords in the overworld:


MinecraftServer server = MinecraftServer.getServer();
server.worldServerForDimension(0).getChunkFromChunkCoords(x, z);

[/Code]

 

that will give me the same chunk that is in the overworld at the same position as the chunk it is trying to generate in the Mirror dimension. I don't know where to go from there to get the chunk seed

 

Link to comment
Share on other sites

I managed to get stuff like stone and dirt and grass to generate, but I have 2 errors. 1) no ores or biome decorations at all and 2) the world is not generating the same as the overworld. here is my code:

 


public Chunk provideChunk(int p_73154_1_, int p_73154_2_)
    {
        this.rand.setSeed((long)p_73154_1_ * 341873128712L + (long)p_73154_2_ * 132897987541L);
        Block[] ablock = new Block[65536];
        byte[] abyte = new byte[65536];
       
        this.func_147424_a(p_73154_1_, p_73154_2_, ablock);
        this.biomesForGeneration = this.worldObj.getWorldChunkManager().loadBlockGeneratorData(this.biomesForGeneration, p_73154_1_ * 16, p_73154_2_ * 16, 16, 16);
        this.replaceBlocksForBiome(p_73154_1_, p_73154_2_, ablock, abyte, this.biomesForGeneration);
        this.caveGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);
        this.ravineGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);

        if (this.mapFeaturesEnabled)
        {
            this.mineshaftGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);
            this.villageGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);
            this.strongholdGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);
            this.scatteredFeatureGenerator.func_151539_a(this, this.worldObj, p_73154_1_, p_73154_2_, ablock);
        }

        for(int i = 0; i < ablock.length; i++){
        if(ablock[i] != null){
        Block original = ablock[i];
        Block temp = Mirror(ablock[i]);
        ablock[i] = temp;
        if(original != temp){
        //System.out.println("Replaced " + original.getLocalizedName() + " with " + ablock[i].getLocalizedName());
        }else{
        //System.out.println("No Mirror Item Found For " + temp.getLocalizedName() + temp.getLocalizedName());
        }
        }
        }
       
        Chunk chunk = new Chunk(this.worldObj, ablock, abyte, p_73154_1_, p_73154_2_);
        byte[] abyte1 = chunk.getBiomeArray();

        for (int k = 0; k < abyte1.length; ++k)
        {
            abyte1[k] = (byte)this.biomesForGeneration[k].biomeID;
        }

        chunk.generateSkylightMap();
        return chunk;
    }
[/Code]

Link to comment
Share on other sites

First of all, blocks are not generated in

new Chunk

, but in

generateTerrain

(may be called

func_147424_a

for you).

There is asks WorldChunkManager for biomes, which asks GenLayers. There, in GenLayers, there's random determined per chunk. Try to find place where you can change it, or simply copy all GenLayer classes and changing random seed to what you want.

Ores aren't generated, because in

populateChunk

, you are calling event with world dimension id != 0, while ores generate in dimId == 0.

 

Last thing, just found that mod: Witchery, it has dream dimensions that generate exactly like overworld. I suggest looking at it's source code.

Link to comment
Share on other sites

  • 6 years later...
On 10/27/2015 at 8:51 AM, Elix_x said:

Do you mean looks exactly the same with how it was generated? Or player built stuff must be mirrored too?

First one is very easy - follow any dimension creation tutorial, to the point where you created world provider. Done. In short: do not override any world gen methods in your world provider.

Second one - a bit harder, but possible.

do you know how to do the second option? or are there any tutorials on how to do it?

Link to comment
Share on other sites

Please don't necro ancient threads, especially ones that concern versions that have long since been unsupported.

This is my Forum Signature, I am currently attempting to transform it into a small guide for fixing easier issues using spoiler blocks to keep things tidy.

 

As the most common issue I feel I should put this outside the main bulk:

The only official source for Forge is https://files.minecraftforge.net, and the only site I trust for getting mods is CurseForge.

If you use any site other than these, please take a look at the StopModReposts project and install their browser extension, I would also advise running a virus scan.

 

For players asking for assistance with Forge please expand the spoiler below and read the appropriate section(s) in its/their entirety.

Spoiler

Logs (Most issues require logs to diagnose):

Spoiler

Please post logs using one of the following sites (Thank you Lumber Wizard for the list):

https://gist.github.com/100MB Requires member (Free)

https://pastebin.com/: 512KB as guest, 10MB as Pro ($$$)

https://hastebin.com/: 400KB

Do NOT use sites like Mediafire, Dropbox, OneDrive, Google Drive, or a site that has a countdown before offering downloads.

 

What to provide:

...for Crashes and Runtime issues:

Minecraft 1.14.4 and newer:

Post debug.log

Older versions:

Please update...

 

...for Installer Issues:

Post your installer log, found in the same place you ran the installer

This log will be called either installer.log or named the same as the installer but with .log on the end

Note for Windows users:

Windows hides file extensions by default so the installer may appear without the .jar extension then when the .log is added the log will appear with the .jar extension

 

Where to get it:

Mojang Launcher: When using the Mojang launcher debug.log is found in .minecraft\logs.

 

Curse/Overwolf: If you are using the Curse Launcher, their configurations break Forge's log settings, fortunately there is an easier workaround than I originally thought, this works even with Curse's installation of the Minecraft launcher as long as it is not launched THROUGH Twitch:

Spoiler
  1. Make sure you have the correct version of Forge installed (some packs are heavily dependent on one specific build of Forge)
  2. Make a launcher profile targeting this version of Forge.
  3. Set the launcher profile's GameDir property to the pack's instance folder (not the instances folder, the folder that has the pack's name on it).
  4. Now launch the pack through that profile and follow the "Mojang Launcher" instructions above.

Video:

Spoiler

 

 

 

or alternately, 

 

Fallback ("No logs are generated"):

If you don't see logs generated in the usual place, provide the launcher_log.txt from .minecraft

 

Server Not Starting:

Spoiler

If your server does not start or a command window appears and immediately goes away, run the jar manually and provide the output.

 

Reporting Illegal/Inappropriate Adfocus Ads:

Spoiler

Get a screenshot of the URL bar or copy/paste the whole URL into a thread on the General Discussion board with a description of the Ad.

Lex will need the Ad ID contained in that URL to report it to Adfocus' support team.

 

Posting your mod as a GitHub Repo:

Spoiler

When you have an issue with your mod the most helpful thing you can do when asking for help is to provide your code to those helping you. The most convenient way to do this is via GitHub or another source control hub.

When setting up a GitHub Repo it might seem easy to just upload everything, however this method has the potential for mistakes that could lead to trouble later on, it is recommended to use a Git client or to get comfortable with the Git command line. The following instructions will use the Git Command Line and as such they assume you already have it installed and that you have created a repository.

 

  1. Open a command prompt (CMD, Powershell, Terminal, etc).
  2. Navigate to the folder you extracted Forge’s MDK to (the one that had all the licenses in).
  3. Run the following commands:
    1. git init
    2. git remote add origin [Your Repository's URL]
      • In the case of GitHub it should look like: https://GitHub.com/[Your Username]/[Repo Name].git
    3. git fetch
    4. git checkout --track origin/master
    5. git stage *
    6. git commit -m "[Your commit message]"
    7. git push
  4. Navigate to GitHub and you should now see most of the files.
    • note that it is intentional that some are not synced with GitHub and this is done with the (hidden) .gitignore file that Forge’s MDK has provided (hence the strictness on which folder git init is run from)
  5. Now you can share your GitHub link with those who you are asking for help.

[Workaround line, please ignore]

 

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.


×
×
  • Create New...

Important Information

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