Minecraft 1.12.2模组开发(四十九) 维度空间

1.18.2维度空间教程

1.16.5维度空间教程

我们今天在1.12.2的模组中实现一个自定义维度的生成:

1.在Java包的init包中新建一个InitDimension类注册我们所有的维度:

InitDimension.java

package com.joy187.rejoymod.init;

import com.joy187.rejoymod.world.dimension.re8dim.re8WorldProvider;
import net.minecraft.world.DimensionType;
import net.minecraftforge.common.DimensionManager;

public class InitDimension {
    //public static final DimensionType DIM_TWO = DimensionType.register("dim_two", "_testdim", ModConfig.DEBUG_CONF.DIM_ONE_ID, DimensionOne.class, false);
    public static final DimensionType RE8_DIMENSION = DimensionType.register("re8_dimension", "_dim", 118, re8WorldProvider.class, false);

    public static void registerDimensions()
    {
        //这个118是我们的维度编号,和上面保持一致,你的维度编号要与众不同
        DimensionManager.registerDimension(118, RE8_DIMENSION);
    }
}
在RegistryHandler中的preInitRegistries函数中对我们的维度进行注册:
	public static void preInitRegistries(FMLPreInitializationEvent event)
	{

		//ModFluid.registerFluids();
		InitBiome.registerBiomes();
		
		//添加这个
		InitDimension.registerDimensions();

		ModEntityInit.registerEntities();


	}

2.在world包中新建dimension包 -> dimension包中新建一个我们的维度包re8dim -> 包中新建re8WorldProvider

re8WorldProvider.java

package com.joy187.rejoymod.world.dimension.re8dim;

import com.joy187.rejoymod.init.InitBiome;
import com.joy187.rejoymod.init.InitDimension;
import com.joy187.rejoymod.world.dimension.hexcube.ChunkGeneratorHexCube16;
import net.minecraft.world.DimensionType;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.biome.BiomeProvider;
import net.minecraft.world.biome.BiomeProviderSingle;
import net.minecraft.world.gen.IChunkGenerator;

public class re8WorldProvider extends WorldProvider {
    public re8WorldProvider()
    {
        //里面是我们维度的生物群系
        this.biomeProvider= new BiomeProviderSingle(Biome.PLAINS);
    }

    public DimensionType getDimensionType(){
        return InitDimension.RE8_DIMENSION;
    }


    @Override
    public IChunkGenerator createChunkGenerator() {
        return new re8ChunkGenerator(world, world.getSeed(), true);
    }

    public boolean canRespawnHere()
    {
        return false;
    }

    public boolean isSurfaceWorld()
    {
        return false;
    }


}
包中新建re8ChunkGenerator类来进行我们维度的区块生成工作,这个类的可操作度很高,你可以随意创作:

re8ChunkGenerator.java

package com.joy187.rejoymod.world.dimension.re8dim;

import com.joy187.rejoymod.blocks.ModBlocks;
import com.joy187.rejoymod.world.dimension.hexcube.HexCubeHelper;
import com.joy187.rejoymod.world.dimension.hexcube.structure.*;
import net.minecraft.block.BlockColored;
import net.minecraft.block.BlockFalling;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.init.Biomes;
import net.minecraft.init.Blocks;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.WorldProviderSurface;
import net.minecraft.world.WorldType;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.IChunkGenerator;
import net.minecraft.world.gen.MapGenBase;
import net.minecraft.world.gen.NoiseGeneratorOctaves;
import net.minecraft.world.gen.NoiseGeneratorPerlin;
import net.minecraftforge.fml.common.IWorldGenerator;

import javax.annotation.Nullable;
import java.util.List;
import java.util.Random;

import static com.joy187.rejoymod.util.CommonDef.CHUNK_SIZE;

public class re8ChunkGenerator implements IChunkGenerator {
    private final World world;
    private final boolean generateStructures;
    private final Random rand;
    private WorldType worldType;
    private final double[] field_147434_q;
    private final float[] parabolicField;
    private double[] stoneNoise = new double[256];
    private double[] densities;
    private Biome[] biomesForGeneration;
    re8MapGen omotholGenerator = new re8MapGen();
    double[] noiseData1, noiseData2, noiseData3, noiseData4, noiseData5;

    //    private MapGenBase caveGenerator = new MapGenCavesAC();
//    private MapGenBase dreadlandsCaveGenerator = new MapGenCavesDreadlands();
    private NoiseGeneratorOctaves noiseGen1;
    private NoiseGeneratorOctaves noiseGen2;
    private NoiseGeneratorOctaves noiseGen3;
    private NoiseGeneratorOctaves noiseGen4;
    public NoiseGeneratorOctaves noiseGen5;
    public NoiseGeneratorOctaves noiseGen6;
    //private StructureShoggothPit shoggothLair = new StructureShoggothPit();
//    public re8ChunkGenerator(World world, boolean generate, long seed) {
//        this.world = world;
//        this.generateStructures = generate;
//        this.rand = new Random(seed);
//        world.setSeaLevel(63);
//    }
    //区块生成函数
    public re8ChunkGenerator(World par1World, long par2, boolean par4)
    {
        world = par1World;
        generateStructures = par4;
        worldType = par1World.getWorldInfo().getTerrainType();
        rand = new Random(par2);
        //世界生成的噪声函数,模拟地形生成用的
        noiseGen1 = new NoiseGeneratorOctaves(rand, 16);
        noiseGen2 = new NoiseGeneratorOctaves(rand, 16);
        noiseGen3 = new NoiseGeneratorOctaves(rand, 8);
        noiseGen4 = new NoiseGeneratorOctaves(rand, 4);
        noiseGen5 = new NoiseGeneratorOctaves(rand, 10);
        noiseGen6 = new NoiseGeneratorOctaves(rand, 16);
        field_147434_q = new double[825];
        parabolicField = new float[25];

        for (int j = -2; j <= 2; ++j)
            for (int k = -2; k <= 2; ++k)
            {
                float f = 10.0F / MathHelper.sqrt(j * j + k * k + 0.2F);
                parabolicField[j + 2 + (k + 2) * 5] = f;
            }
    }


    public void buildChunk(int x, int z, ChunkPrimer primer) {

//        if (chunkUsed(x, z)) {
//            for (int y = 0; y < heightLimit; y+=CHUNK_SIZE) {
//                genCubeHalf(primer, x, y, z);
//            }
//        }
//
//        if (this.generateStructures)
//        {
//
//        }

        GenerateFloor(primer);
    }

    private void GenerateFloor(ChunkPrimer primer) {
        for (int dx = 0; dx < CHUNK_SIZE; dx++)
        {
            //for (int dy = 0; dy < CommonDef.CHUNK_SIZE; dy++)
            {
                for (int dz = 0; dz < CHUNK_SIZE; dz++)
                {
                    //BlockPos curPos = new BlockPos(x+dx, y+dy, z+dz);
                    primer.setBlockState(dx, 0, dz,
                            Blocks.BEDROCK.getDefaultState());
//                    primer.setBlockState(dx, heightLimit, dz,
//                            Blocks.BEDROCK.getDefaultState());

                }
            }
        }
    }
//    @Override
//    public void generate(Random random, int chunkX, int chunkZ, World world, IChunkGenerator
//            chunkGenerator, IChunkProvider chunkProvider) {
//        if(world.provider instanceof WorldProviderSurface)
//            generateSurface(world, random, chunkX*16, chunkZ*16);
//    }
    //在每个区块中填充你的自定义方块
    public void setBlocksInChunk(int x, int z, ChunkPrimer primer)
    {
        int i = 2;
        int j = i + 1;
        int k = 33;
        int l = i + 1;
        densities = initializeNoiseField(densities, x * i, 0, z * i, j, k, l);

        for (int i1 = 0; i1 < i; ++i1)
            for (int j1 = 0; j1 < i; ++j1)
                for (int k1 = 0; k1 < 32; ++k1)
                {
                    double d0 = 0.25D;
                    double d1 = densities[((i1 + 0) * l + j1 + 0) * k + k1 + 0];
                    double d2 = densities[((i1 + 0) * l + j1 + 1) * k + k1 + 0];
                    double d3 = densities[((i1 + 1) * l + j1 + 0) * k + k1 + 0];
                    double d4 = densities[((i1 + 1) * l + j1 + 1) * k + k1 + 0];
                    double d5 = (densities[((i1 + 0) * l + j1 + 0) * k + k1 + 1] - d1) * d0;
                    double d6 = (densities[((i1 + 0) * l + j1 + 1) * k + k1 + 1] - d2) * d0;
                    double d7 = (densities[((i1 + 1) * l + j1 + 0) * k + k1 + 1] - d3) * d0;
                    double d8 = (densities[((i1 + 1) * l + j1 + 1) * k + k1 + 1] - d4) * d0;

                    for (int l1 = 0; l1 < 4; ++l1)
                    {
                        double d9 = 0.125D;
                        double d10 = d1;
                        double d11 = d2;
                        double d12 = (d3 - d1) * d9;
                        double d13 = (d4 - d2) * d9;

                        for (int i2 = 0; i2 < 8; ++i2)
                        {
                            double d14 = 0.125D;
                            double d15 = d10;
                            double d16 = (d11 - d10) * d14;

                            for (int j2 = 0; j2 < 8; ++j2)
                            {
                                IBlockState iblockstate = null;

                                //可以换成你自己的方块
                                if (d15 > 0.0D)
                                    iblockstate = ModBlocks.WASTELAND_BLOCK.getDefaultState();

                                int k2 = i2 + i1 * 8;
                                int l2 = l1 + k1 * 4;
                                int i3 = j2 + j1 * 8;
                                primer.setBlockState(k2, l2, i3, iblockstate);
                                d15 += d16;
                            }

                            d10 += d12;
                            d11 += d13;
                        }

                        d1 += d5;
                        d2 += d6;
                        d3 += d7;
                        d4 += d8;
                    }
                }
    }

    public void replaceBlocksForBiome(ChunkPrimer primer)
    {

        for (int i = 0; i < 16; ++i)
            for (int j = 0; j < 16; ++j)
            {
                int k = 1;
                int l = -1;
                //可以换成你模组里的方块
                IBlockState iblockstate = ModBlocks.WASTELAND_ROCK_BLOCK.getDefaultState();
                IBlockState iblockstate1 = ModBlocks.WASTELAND_ROCK_BLOCK.getDefaultState();

                for (int i1 = 127; i1 >= 0; --i1)
                {
                    IBlockState iblockstate2 = primer.getBlockState(i, i1, j);

                    if (iblockstate2.getMaterial() == Material.AIR)
                        l = -1;
                    else if (iblockstate2.getBlock() == Blocks.STONE)
                        if (l == -1)
                        {
                            if (k <= 0)
                            {
                                iblockstate = Blocks.AIR.getDefaultState();
                                iblockstate1 = ModBlocks.WASTELAND_ROCK_BLOCK.getDefaultState();
                            }

                            l = k;

                            if (i1 >= 0)
                                primer.setBlockState(i, i1, j, iblockstate);
                            else
                                primer.setBlockState(i, i1, j, iblockstate1);
                        }
                        else if (l > 0)
                        {
                            --l;
                            primer.setBlockState(i, i1, j, iblockstate1);
                        }
                }
            }
    }

    @Override
    public Chunk generateChunk(int x, int z)
    {
        rand.setSeed(x * 341873128712L + z * 132897987541L);
        ChunkPrimer primer = new ChunkPrimer();
        biomesForGeneration = world.getBiomeProvider().getBiomes(biomesForGeneration, x * 16, z * 16, 16, 16);
        setBlocksInChunk(x, z, primer);
        replaceBlocksForBiome(primer);

        omotholGenerator.generate(world, x, z, primer);

        Chunk chunk = new Chunk(world, primer, x, z);
        byte[] abyte = chunk.getBiomeArray();

        for (int k = 0; k < abyte.length; ++k)
            abyte[k] = (byte)Biome.getIdForBiome(biomesForGeneration[k]);

        chunk.generateSkylightMap();
        return chunk;
    }

    private double[] initializeNoiseField(double[] par1ArrayOfDouble, int x, int y, int z, int xSize, int ySize, int zSize)
    {
        if(par1ArrayOfDouble == null)
            par1ArrayOfDouble = new double[xSize * ySize * zSize];
        double d = 684.41200000000003D;
        double d1 = 684.41200000000003D;
        noiseData4 = noiseGen4.generateNoiseOctaves(noiseData4, x, z, xSize, zSize, 1.121D, 1.121D, 0.5D);
        noiseData5 = noiseGen5.generateNoiseOctaves(noiseData5, x, z, xSize, zSize, 200D, 200D, 0.5D);
        d *= 2D;
        noiseData1 = noiseGen3.generateNoiseOctaves(noiseData1, x, y, z, xSize, ySize, zSize, d / 80D, d1 / 160D, d / 80D);
        noiseData2 = noiseGen1.generateNoiseOctaves(noiseData2, x, y, z, xSize, ySize, zSize, d, d1, d);
        noiseData3 = noiseGen2.generateNoiseOctaves(noiseData3, x, y, z, xSize, ySize, zSize, d, d1, d);
        int k1 = 0;
        int l1 = 0;
        for(int j2 = 0; j2 < xSize; j2++)
            for(int l2 = 0; l2 < zSize; l2++)
            {
                double d3;
                d3 = 0.5D;
                double d4 = 1.0D - d3;
                d4 *= d4;
                d4 *= d4;
                d4 = 1.0D - d4;
                double d5 = (noiseData4[l1] + 256D) / 512D;
                d5 *= d4;
                if(d5 > 1.0D)
                    d5 = 1.0D;
                double d6 = noiseData5[l1] / 8000D;
                if(d6 < 0.0D)
                    d6 = -d6 * 0.29999999999999999D;
                d6 = d6 * 3D - 2D;
                if(d6 > 1.0D)
                    d6 = 1.0D;
                d6 /= 8D;
                d6 = 0.0D;
                if(d5 < 0.0D)
                    d5 = 0.0D;
                d5 += 0.5D;
                d6 = d6 * ySize / 16D;
                l1++;
                double d7 = ySize / 2D;
                for(int j3 = 0; j3 < ySize; j3++)
                {
                    double d8 = 0.0D;
                    double d9 = (j3 - d7) * 8D / d5;
                    if(d9 < 0.0D)
                        d9 *= -1D;
                    double d10 = noiseData2[k1] / 512D;
                    double d11 = noiseData3[k1] / 512D;
                    double d12 = (noiseData1[k1] / 10D + 1.0D) / 2D;
                    if(d12 < 0.0D)
                        d8 = d10;
                    else
                    if(d12 > 1.0D)
                        d8 = d11;
                    else
                        d8 = d10 + (d11 - d10) * d12;
                    d8 -= 8D;
                    int k3 = 32;
                    if(j3 > ySize - k3)
                    {
                        double d13 = (j3 - (ySize - k3)) / (k3 - 1.0F);
                        d8 = d8 * (1.0D - d13) + -30D * d13;
                    }
                    k3 = 8;
                    if(j3 < k3)
                    {
                        double d14 = (k3 - j3) / (k3 - 1.0F);
                        d8 = d8 * (1.0D - d14) + -30D * d14;
                    }
                    par1ArrayOfDouble[k1] = d8;
                    k1++;
                }

            }

        return par1ArrayOfDouble;
    }

    public void generateSurface(World world, Random random, int chunkX, int chunkZ) {


    }
    
    @Override
    public void populate(int x, int z)
    {
        BlockFalling.fallInstantly = true;

        int k = x * 16;
        int l = z * 16;
        Biome Biome = world.getBiome(new BlockPos(k + 16, 0, l + 16));

        ChunkPos chunkcoordintpair = new ChunkPos(x, z);

        //omotholGenerator.generateStructure(world, rand, chunkcoordintpair);

        for(int i = 0; i < 1; i++) {
            int Xcoord2 = k + rand.nextInt(16) + 8;
            int Zcoord2 = l + rand.nextInt(2) + 28;
            BlockPos pos1 = world.getHeight(new BlockPos(Xcoord2, 0, Zcoord2));
            if(world.getBlockState(pos1).getMaterial() == Material.PLANTS) pos1 = pos1.down();

           // if(rand.nextInt(100) == 0 && !world.isAirBlock(pos1.north(13)) && !world.isAirBlock(pos1.north(20)) && !world.isAirBlock(pos1.north(27)))
                //shoggothLair.generate(world, rand, pos1);
        }

        if((x > -2 || x < 2) && (z > 6 || z < -1)) {

            BlockPos pos2 = world.getHeight(new BlockPos(k, 0, l));

            //adding RNG to the coords to give a more accurate picture of the actual position
//            if(!cityGen.tooClose(pos2.add(rand.nextInt(8) + 8, 0, rand.nextInt(8) + 8)))
//                cityGen.generate(world, rand, pos2);

            int randX = k + rand.nextInt(2) + 1;
            int randZ = l + rand.nextInt(2) + 1;

            pos2 = world.getHeight(new BlockPos(randX, 0, randZ));

//            if(rand.nextBoolean() && !templeGen.tooClose(pos2) && !cityGen.tooClose(pos2))
//                templeGen.generate(world, rand, pos2);


            randX = k + rand.nextInt(8) + 8;
            randZ = l + rand.nextInt(8) + 8;

            pos2 = world.getHeight(new BlockPos(randX, 0, randZ));

//            if(rand.nextBoolean() && !towerGen.tooClose(pos2) && !cityGen.tooClose(pos2))
//                towerGen.generate(world, rand, pos2);

            randX = k + rand.nextInt(7) + 7;
            randZ = l + rand.nextInt(7) + 7;

            pos2 = world.getHeight(new BlockPos(randX, 0, randZ));

//            if(rand.nextBoolean() && !storageGen.tooClose(pos2) && !cityGen.tooClose(pos2))
//                storageGen.generate(world, rand, pos2);
        }

        Biome.decorate(world, world.rand, new BlockPos(k, 0, l));

        BlockFalling.fallInstantly = false;
    }

    @Override
    public List getPossibleCreatures(EnumCreatureType par1EnumCreatureType, BlockPos pos)
    {
        Biome Biome = world.getBiome(pos);
        return Biome == null ? null : Biome.getSpawnableList(par1EnumCreatureType);
    }

    @Override
    public BlockPos getNearestStructurePos(World par1World, String par2String, BlockPos pos, boolean bool)
    {
        return null;
    }

    @Override
    public void recreateStructures(Chunk chunk, int x, int z) {

        //omotholGenerator.generate(world, x, z, null);

    }

    @Override
    public boolean generateStructures(Chunk chunkIn, int x, int z) {

        return false;
    }

    @Override
    public boolean isInsideStructure(World p_193414_1_, String p_193414_2_, BlockPos p_193414_3_) {

        return false;
    }

}
包中新建re8MapGen类来进行我们维度的地图生成工作

re8MapGen.java

package com.joy187.rejoymod.world.dimension.re8dim;

import java.util.*;
import java.util.Map.Entry;

import com.joy187.rejoymod.init.InitBiome;

import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.structure.MapGenStructure;
import net.minecraft.world.gen.structure.StructureComponent;
import net.minecraft.world.gen.structure.StructureStart;
import net.minecraft.world.gen.structure.StructureStrongholdPieces;

public class re8MapGen extends MapGenStructure
{
    public static List<Biome> villageSpawnBiomes = Arrays.<Biome>asList(new Biome[] {InitBiome.RE8BIOME,InitBiome.RE8DESERTBIOME});
    /** World terrain type, 0 for normal, 1 for flat map */
    private int terrainType;
    private int field_82665_g;
    private int field_82666_h;

    public re8MapGen()
    {
        field_82665_g = 32;
        field_82666_h = 8;
    }

    public re8MapGen(Map<String, String> p_i2093_1_)
    {
        this();

        for (Entry<String, String> entry : p_i2093_1_.entrySet())
            if (entry.getKey().equals("size"))
                terrainType = MathHelper.getInt(entry.getValue(), terrainType, 0);
            else if (entry.getKey().equals("distance"))
                field_82665_g = MathHelper.getInt(entry.getValue(), field_82665_g, field_82666_h + 1);
    }

    @Override
    public String getStructureName()
    {
        return "re8_structure";
    }

    @Override
    protected boolean canSpawnStructureAtCoords(int chunkX, int chunkZ)
    {
        if(chunkX == 0 && chunkZ == 0) return true;

        return false;
    }

    @Override
    protected StructureStart getStructureStart(int chunkX, int chunkZ)
    {
        return new re8MapGen.Start(world, rand, chunkX, chunkZ, terrainType);
    }

    public static class Start extends StructureStart
    {
        /** well ... thats what it does */
        private boolean hasMoreThanTwoComponents;

        public Start()
        {
        }


        public Start(World worldIn, Random random, int chunkX, int chunkZ,int p_i2092_5_)
        {
            super(chunkX, chunkZ);
            StructureStrongholdPieces.prepareStructurePieces();
            StructureStrongholdPieces.Stairs2 structurestrongholdpieces$stairs2 = new StructureStrongholdPieces.Stairs2(0, random, (chunkX << 4) + 2, (chunkZ << 4) + 2);
            this.components.add(structurestrongholdpieces$stairs2);
            structurestrongholdpieces$stairs2.buildComponent(structurestrongholdpieces$stairs2, this.components, random);
            List<StructureComponent> list = structurestrongholdpieces$stairs2.pendingChildren;

            while (!list.isEmpty())
            {
                int i = random.nextInt(list.size());
                StructureComponent structurecomponent = list.remove(i);
                structurecomponent.buildComponent(structurestrongholdpieces$stairs2, this.components, random);
            }

            this.updateBoundingBox();
            this.markAvailableHeight(worldIn, random, 10);
        }
        /**
         * currently only defined for Villages, returns true if Village has more than 2 non-road components
         */
        @Override
        public boolean isSizeableStructure()
        {
            return hasMoreThanTwoComponents;
        }

        @Override
        public void writeToNBT(NBTTagCompound tagCompound)
        {
            super.writeToNBT(tagCompound);
            tagCompound.setBoolean("Valid", hasMoreThanTwoComponents);
        }

        @Override
        public void readFromNBT(NBTTagCompound tagCompound)
        {
            super.readFromNBT(tagCompound);
            hasMoreThanTwoComponents = tagCompound.getBoolean("Valid");
        }
    }

    @Override
    public BlockPos getNearestStructurePos(World worldIn, BlockPos pos, boolean findUnexplored) {

        return null;
    }
}

cr3.png

3.保存所有文件 -> 运行游戏测试:

按’t’进入控制台输入指令进入我们的维度,维度编号是第一步中你的维度编号
/tpdim 118

dim.png

我们成功进入了自己的维度!

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jay_fearless

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值