Ajouter une nouvelle dimension



  • Sommaire

    Introduction

    Dans ce nouveau tutoriel nous allons voir comment créer une nouvelle dimension. Dans une dimension il y a plusieurs composants, les biomes, le portail, la génération, les structures et plein d'autre éléments du décor. Dans ce tutoriel nous allons voir comment créer une dimension et aussi comment ajouter les éléments qui la composent.

    Pré-requis

    Ce tutoriel est relativement dur à comprendre, donc vous aurez, avant tout, besoin de bonnes connaissances en java.

    Code

    Ce tutoriel est très long, toutes les classes un peu longues seront mises dans un onglet spoiler.

    La classe du Chunk Provider :

    Cette classe est très importante dans votre dimension : beaucoup de choses y seront enregistrées, comme les lacs, les structures et les Noises.
    Commencez en créant une nouvelle classe. Je vous conseille de la nommer comme ça : "ChunkProvider + le nom de la dimension, ou du mod", ou bien "nom du mod ou de la dimension + ChunkProvider", vous allez avoir beaucoup de classes il est donc important de pouvoir vite se retrouver dans ce gros paquet.
    Une fois cette classe créée, ajoutez l'implémentation suivante :

    implements IChunkProvider
    

    Nous allons ajouter les méthodes prochainement.
    Ensuite, ajoutez tous les fields :

        private Random rand;
        private NoiseGeneratorOctaves noiseGen1;//les noises
        private NoiseGeneratorOctaves noiseGen2;
        private NoiseGeneratorOctaves noiseGen3;
        private NoiseGeneratorPerlin noiseGen4;
        public NoiseGeneratorOctaves noiseGen5;
        public NoiseGeneratorOctaves noiseGen6;
        public NoiseGeneratorOctaves mobSpawnerNoise;
        private World worldObj;
        private WorldType worldType;
        private final double[] noiseArray;
        private final float[] parabolicField;
        private final boolean mapFeaturesEnabled;
    
        private MapGenBase caveGenerator = new MapGenCaves();//la génération des caves, remplacer par votre ravin si vous utiliser une autre stone
        private MapGenMineshaft mineshaftGenerator = new MapGenMineshaft();//la génération des mineshaft, ""        ""                     ""
        private MapGenScatteredFeature scatteredFeatureGenerator = new MapGenScatteredFeature();
        private MapGenBase ravineGenerator = new MapGenRavine();//la structure du ravin,          ""             ""                     ""
    
        private double[] stoneNoise = new double[256];
        private BiomeGenBase[] biomesForGeneration;
        double[] noiseData1; //les noises data
        double[] noiseData2;
        double[] noiseData3;
        double[] noiseData4;
    

    Pour le moment ils ne sont pas initialisés, mais nous allons le faire (vous pouvez voir que nous générons des structures, donc remplacer les structures existantes par les vôtres, ou ajoutez-les), mais avant d'ajouter :

        {
            caveGenerator = TerrainGen.getModdedMapGen(caveGenerator, CAVE);
            mineshaftGenerator = (MapGenMineshaft) TerrainGen.getModdedMapGen(mineshaftGenerator, MINESHAFT);
            scatteredFeatureGenerator = (MapGenScatteredFeature) TerrainGen.getModdedMapGen(scatteredFeatureGenerator, SCATTERED_FEATURE);
            ravineGenerator = TerrainGen.getModdedMapGen(ravineGenerator, RAVINE);
        }
    

    N'oubliez pas de tout importer ! Si jamais sur les : "CAVE, MINESHAFT ..." il vous reste des erreurs, il faut tout importer, donc dans les imports ajoutez :

    import static net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.*;
    

    Ceci nous permet (plus tard) de générer les structures.
    Ensuite, nous allons initialiser les fields. Ajoutez cette fonction :

        public TutoChunkProvider(World world, long seed, boolean features)
        {
                this.worldObj = world;
                this.mapFeaturesEnabled = features;
                this.worldType = world.getWorldInfo().getTerrainType();
                this.rand = new Random(seed);
                this.noiseGen1 = new NoiseGeneratorOctaves(this.rand, 16);
                this.noiseGen2 = new NoiseGeneratorOctaves(this.rand, 16);
                this.noiseGen3 = new NoiseGeneratorOctaves(this.rand, 8);
                this.noiseGen4 = new NoiseGeneratorPerlin(this.rand, 4);
                this.noiseGen5 = new NoiseGeneratorOctaves(this.rand, 10);
                this.noiseGen6 = new NoiseGeneratorOctaves(this.rand, 16);
                this.mobSpawnerNoise = new NoiseGeneratorOctaves(this.rand, 8);
                this.noiseArray = new double[825];
                this.parabolicField = new float[25];
    
                for (int j = -2; j <= 2; ++j)
                {
                    for (int k = -2; k <= 2; ++k)
                    {
                        float f = 10.0F / MathHelper.sqrt_float((float)(j * j + k * k) + 0.2F);
                        this.parabolicField[j + 2 + (k + 2) * 5] = f;
                    }
                }
    
                NoiseGenerator[] noiseGens = {noiseGen1, noiseGen2, noiseGen3, noiseGen4, noiseGen5, noiseGen6, mobSpawnerNoise};
                noiseGens = TerrainGen.getModdedNoiseGenerators(world, this.rand, noiseGens);
                this.noiseGen1 = (NoiseGeneratorOctaves)noiseGens[0];
                this.noiseGen2 = (NoiseGeneratorOctaves)noiseGens[1];
                this.noiseGen3 = (NoiseGeneratorOctaves)noiseGens[2];
                this.noiseGen4 = (NoiseGeneratorPerlin)noiseGens[3];
                this.noiseGen5 = (NoiseGeneratorOctaves)noiseGens[4];
                this.noiseGen6 = (NoiseGeneratorOctaves)noiseGens[5];
                this.mobSpawnerNoise = (NoiseGeneratorOctaves)noiseGens[6];
        }
    

    Je ne vois pas quoi expliquer mis à part que nous initialisons les fields plus haut.
    Normalement, il doit vous rester qu'une seule erreur vous demandant d'ajouter des fonctions, mais comme dit plus haut ne le faites pas.
    Ensuite, nous allons ajouter une autre fonction, elle définira en quels blocs seront générés les lacs et le blocs dans le sol.

        public void func_147424_a(int Xchunks, int Zchunks, Block[] topBlock)
        {
            byte b0 = 63;
            this.biomesForGeneration = this.worldObj.getWorldChunkManager().getBiomesForGeneration(this.biomesForGeneration, Xchunks * 4 - 2, Zchunks * 4 - 2, 10, 10);
            this.func_147423_a(Xchunks * 4, 0, Zchunks * 4);
    
            final Random rand = new Random();
    
            for (int k = 0; k < 4; ++k)
            {
                int l = k * 5;
                int i1 = (k + 1) * 5;
    
                for (int j1 = 0; j1 < 4; ++j1)
                {
                    int k1 = (l + j1) * 33;
                    int l1 = (l + j1 + 1) * 33;
                    int i2 = (i1 + j1) * 33;
                    int j2 = (i1 + j1 + 1) * 33;
    
                    for (int k2 = 0; k2 < 32; ++k2)
                    {
                        double d0 = 0.105D;
                        double d1 = this.noiseArray[k1 + k2];
                        double d2 = this.noiseArray[l1 + k2];
                        double d3 = this.noiseArray[i2 + k2];
                        double d4 = this.noiseArray[j2 + k2];
                        double d5 = (this.noiseArray[k1 + k2 + 1] - d1) * d0;
                        double d6 = (this.noiseArray[l1 + k2 + 1] - d2) * d0;
                        double d7 = (this.noiseArray[i2 + k2 + 1] - d3) * d0;
                        double d8 = (this.noiseArray[j2 + k2 + 1] - d4) * d0;
    
                        for (int l2 = 0; l2 < 8; ++l2)
                        {
                            double d9 = 0.25D;
                            double d10 = d1;
                            double d11 = d2;
                            double d12 = (d3 - d1) * d9;
                            double d13 = (d4 - d2) * d9;
    
                            for (int i3 = 0; i3 < 4; ++i3)
                            {
                                int j3 = i3 + k * 4 << 12 | 0 + j1 * 4 << 8 | k2 * 8 + l2;
                                short short1 = 256;
                                j3 -= short1;
                                double d14 = 0.25D;
                                double d16 = (d11 - d10) * d14;
                                double d15 = d10 - d16;
    
                                for (int k3 = 0; k3 < 4; ++k3)
                                {
                                    if ((d15 += d16) > 0.0D)
                                    {
                                        topBlock[j3 += short1] = Blocks.stone;
                                    }
                                    else if (k2 * 8 + l2 < b0)
                                    {
                                        topBlock[j3 += short1] = Blocks.water;
                                    }
                                    else
                                    {
                                        topBlock[j3 += short1] = null;
                                    }
                                }
    
                                d10 += d12;
                                d11 += d13;
                            }
    
                            d1 += d5;
                            d2 += d6;
                            d3 += d7;
                            d4 += d8;
                        }
                    }
                }
            }
        }
    

    Cette fonction nous permet de générer le sol, vous devriez avoir une erreur, car il vous manque une fonction qui sera ajoutée plus tard.
    Pour la prochaine fonction nous donnons un biome, un biome qui devra être même partout dans toutes vos autres classes, vous pourrez bien entendu le changer par la suite.

    Ajoutez :

        public void replaceBlocksForBiome(int coordX, int coordZ, Block[] block, byte[] arrayOfByte, BiomeGenBase[] biomeList)
        {
            ChunkProviderEvent.ReplaceBiomeBlocks event = new ChunkProviderEvent.ReplaceBiomeBlocks(this, coordX, coordZ, block, biomeList);
            MinecraftForge.EVENT_BUS.post(event);
            if (event.getResult() == Result.DENY) return;
    
            double d0 = 0.03125D;
            this.stoneNoise = this.noiseGen4.func_151599_a(this.stoneNoise, (double)(coordX * 16), (double)(coordZ * 16), 16, 16, d0 * 2.0D, d0 * 2.0D, 1.0D);
    
            for (int k = 0; k < 16; ++k)
            {
                for (int l = 0; l < 16; ++l)
                {
                    BiomeGenPlains /*TODO ce biome est a remplacer par le votre*/ biomegenbase = (BiomeGenPlains /*TODO ce biome est a remplacer par le votre*/)biomeList[l + k * 16];
                    biomegenbase.genTerrainBlocks(this.worldObj, this.rand, block, arrayOfByte, coordX * 16 + k, coordZ * 16 + l, this.stoneNoise[l + k * 16]);
                }
            }
        }
    

    Cette fonction permet de changer les blocs par les blocs du biome.
    Après cette fonction ajoutez cette autre fonction :

        public Chunk loadChunk(int par1, int par2)
        {
            return this.provideChunk(par1, par2);
        }
    

    Cette fonction permet de charger ou générer des chunks spécifiques.

    Ajoutez ensuite la fonction :

        public Chunk provideChunk(int par1, int par2)
        {
            this.rand.setSeed((long)par1 * 341873128712L + (long)par2 * 132897987541L);
            Block[] ablock = new Block[65536];
            byte[] abyte = new byte[65536];
            this.func_147424_a(par1, par2, ablock);
            this.biomesForGeneration = this.worldObj.getWorldChunkManager().loadBlockGeneratorData(this.biomesForGeneration, par1 * 16, par2 * 16, 16, 16);
            this.replaceBlocksForBiome(par1, par2, ablock, abyte, this.biomesForGeneration);
            this.caveGenerator.func_151539_a(this, this.worldObj, par1, par2, ablock);
            this.ravineGenerator.func_151539_a(this, this.worldObj, par1, par2, ablock);
    
            if (this.mapFeaturesEnabled)
            {
                this.mineshaftGenerator.func_151539_a(this, this.worldObj, par1, par2, ablock);
                this.scatteredFeatureGenerator.func_151539_a(this, this.worldObj, par1, par2, ablock);
            }
    
            Chunk chunk = new Chunk(this.worldObj, ablock, abyte, par1, par2);
            byte[] abyte1 = chunk.getBiomeArray();
    
            for (int k = 0; k < abyte1.length; ++k)
            {
                abyte1[k] = (byte)this.biomesForGeneration[k].biomeID;
            }
    
            chunk.generateSkylightMap();
            return chunk;
        }
    
    • Nous définissons qu'il récupère le seed (pas totalement sûr).
    • Génération des blocs par rapport au seed.
    • Ceci retourne à la fonction créer au début.
    • On initialise le field biomeForGeneration.
    • On dit qu'il peut générer certaines structures.
    • Dans la condition on met toutes les structures qui se génèrent quand la génération des structures est active.
    • Génère la lumière du ciel, gardez-le même si vous ne voulez pas de lumière, tout se fera dans une autre classe.

    Après cette longue fonction ajoutez une fonction (encore plus longue :P) :

        private void func_147423_a(int x, int y, int z)
        {
            double d0 = 684.412D;
            double d1 = 684.412D;
            double d2 = 512.0D;
            double d3 = 512.0D;
            this.noiseData4 = this.noiseGen6.generateNoiseOctaves(this.noiseData4, x, z, 5, 5, 200.0D, 200.0D, 0.5D);
            this.noiseData1 = this.noiseGen3.generateNoiseOctaves(this.noiseData1, x, y, z, 5, 33, 5, 8.555150000000001D, 4.277575000000001D, 8.555150000000001D);
            this.noiseData2 = this.noiseGen1.generateNoiseOctaves(this.noiseData2, x, y, z, 5, 33, 5, 684.412D, 684.412D, 684.412D);
            this.noiseData3 = this.noiseGen2.generateNoiseOctaves(this.noiseData3, x, y, z, 5, 33, 5, 684.412D, 684.412D, 684.412D);
            boolean flag1 = false;
            boolean flag = false;
            int l = 0;
            int i1 = 0;
            double d4 = 8.5D;
    
            for (int j1 = 0; j1 < 5; ++j1)
            {
                for (int k1 = 0; k1 < 5; ++k1)
                {
                    float f = 0.0F;
                    float f1 = 0.0F;
                    float f2 = 0.0F;
                    byte b0 = 2;
                    BiomeGenBase biomegenbase = this.biomesForGeneration[j1 + 2 + (k1 + 2) * 10];
    
                    for (int l1 = -b0; l1 <= b0; ++l1)
                    {
                        for (int i2 = -b0; i2 <= b0; ++i2)
                        {
                            BiomeGenBase biomegenbase1 = this.biomesForGeneration[j1 + l1 + 2 + (k1 + i2 + 2) * 10];
                            float f3 = biomegenbase1.rootHeight;
                            float f4 = biomegenbase1.heightVariation;
    
                            float f5 = this.parabolicField[l1 + 2 + (i2 + 2) * 5] / (f3 + 2.0F);
    
                            if (biomegenbase1.rootHeight > biomegenbase.rootHeight)
                            {
                                f5 /= 2.0F;
                            }
    
                            f += f4 * f5;
                            f1 += f3 * f5;
                            f2 += f5;
                        }
                    }
    
                    f /= f2;
                    f1 /= f2;
                    f = f * 0.9F + 0.1F;
                    f1 = (f1 * 4.0F - 1.0F) / 8.0F;
                    double d13 = this.noiseData4[i1] / 8000.0D;
    
                    if (d13 < 0.0D)
                    {
                        d13 = -d13 * 0.3D;
                    }
    
                    d13 = d13 * 3.0D - 2.0D;
    
                    if (d13 < 0.0D)
                    {
                        d13 /= 2.0D;
    
                        if (d13 < -1.0D)
                        {
                            d13 = -1.0D;
                        }
    
                        d13 /= 1.4D;
                        d13 /= 2.0D;
                    }
                    else
                    {
                        if (d13 > 1.0D)
                        {
                            d13 = 1.0D;
                        }
    
                        d13 /= 8.0D;
                    }
    
                    ++i1;
                    double d12 = (double)f1;
                    double d14 = (double)f;
                    d12 += d13 * 0.2D;
                    d12 = d12 * 8.5D / 8.0D;
                    double d5 = 8.5D + d13 * 4.0D;
    
                    for (int j2 = 0; j2 < 33; ++j2)
                    {
                        double d6 = ((double)j2 - d5) * 12.0D * 128.0D / 256.0D / d14;
    
                        if (d6 < 0.0D)
                        {
                            d6 *= 4.0D;
                        }
    
                        double d7 = this.noiseData2[l] / 512.0D;
                        double d8 = this.noiseData3[l] / 512.0D;
                        double d9 = (this.noiseData1[l] / 10.0D + 1.0D) / 2.0D;
                        double d10 = MathHelper.denormalizeClamp(d7, d8, d9) - d6;
    
                        if (j2 > 29)
                        {
                            double d11 = (double)((float)(j2 - 29) / 3.0F);
                            d10 = d10 * (1.0D - d11) + -10.0D * d11;
                        }
    
                        this.noiseArray[l] = d10;
                        ++l;
                    }
                }
            }
        }
    

    Je ne vais pas expliquer la fonction dans chaque détail, mais elle sera utilisée dans la génération du monde.
    Ensuite, ajoutez la petite fonction :

        public boolean chunkExists(int par1, int par2)
        {
            return true;
        }
    

    Cette fonction regarde si les chunks existent ou non.
    Ensuite, nous allons ajouter une fonction vraiment pratique que je vous laisserais modifier à votre guise si vous en trouvez une utilité :

        public void populate(IChunkProvider chunkProvider, int x, int z)
        {
            BlockFalling.fallInstantly = true;
            int x1 = x * 16;
            int z1 = z * 16;
            BiomeGenBase biomegenbase = this.worldObj.getBiomeGenForCoords(x1 + 16, z1 + 16);
            this.rand.setSeed(this.worldObj.getSeed());
            long i1 = this.rand.nextLong() / 2L * 2L + 1L;
            long j1 = this.rand.nextLong() / 2L * 2L + 1L;
            this.rand.setSeed((long)x * i1 + (long)z * j1 ^ this.worldObj.getSeed());
            boolean flag = false;
    
            MinecraftForge.EVENT_BUS.post(new PopulateChunkEvent.Pre(chunkProvider, worldObj, rand, x, z, flag));
    
            // si l'option de génération des structures est activer alors nous générons le mineshaft et l'autre structure
    
            if (this.mapFeaturesEnabled)
            {
                this.mineshaftGenerator.generateStructuresInChunk(this.worldObj, this.rand, x, z);
                this.scatteredFeatureGenerator.generateStructuresInChunk(this.worldObj, this.rand, x, z);
            }
    
            int x2;
            int z2;
            int i2;
    
            //si le biome n'est pas un désert, une montagne du désert, et que la rand.nextIn(4) ne fait pas 0 alors nous avons un lac
            if (biomegenbase != BiomeGenBase.desert && biomegenbase != BiomeGenBase.desertHills && !flag && this.rand.nextInt(4) == 0
                && TerrainGen.populate(chunkProvider, worldObj, rand, x, z, flag, LAKE))
            {
                x2 = x1 + this.rand.nextInt(16) + 8;
                z2 = this.rand.nextInt(256);
                i2 = z1 + this.rand.nextInt(16) + 8;
                                    //Le blocs de génération du lac
                (new WorldGenLakes(Blocks.water)).generate(this.worldObj, this.rand, x2, z2, i2);
            }
    
            //la condition est la même que en haut, sans les biomes 
            if (TerrainGen.populate(chunkProvider, worldObj, rand, x, z, flag, LAVA) && !flag && this.rand.nextInt(8) == 0)
            {
                x2 = x1 + this.rand.nextInt(16) + 8;
                //nous définissons les x, y, z
                z2 = this.rand.nextInt(this.rand.nextInt(248) + 8);
                i2 = z1 + this.rand.nextInt(16) + 8;
    
                if (z2 < 63 || this.rand.nextInt(10) == 0)
                {						//changer le par le blocs de votre choix
                    (new WorldGenLakes(Blocks.lava)).generate(this.worldObj, this.rand, x2, z2, i2);
                }
            }
    
            //sa nous permet de générer des donjons, comme plus haut changer la classe par la votre pour générer vos donjons
            boolean doGen = TerrainGen.populate(chunkProvider, worldObj, rand, x, z, flag, DUNGEON);
            for (x2 = 0; doGen && x2 < 8; ++x2)
            {
                z2 = x1 + this.rand.nextInt(16) + 8;
                i2 = this.rand.nextInt(256);
                int j2 = z1 + this.rand.nextInt(16) + 8;
                //changer la classe par votre classe
                (new WorldGenDungeons()).generate(this.worldObj, this.rand, z2, i2, j2);
            }
    
            biomegenbase.decorate(this.worldObj, this.rand, x1, z1);
            //sa ajoute des mobs
            if (TerrainGen.populate(chunkProvider, worldObj, rand, x, z, flag, ANIMALS))
            {
            SpawnerAnimals.performWorldGenSpawning(this.worldObj, biomegenbase, x1 + 8, z1 + 8, 16, 16, this.rand);
            }
            x1 += 8;
            z1 += 8;
    
            //sa remplace la génération de l'eau par de la glasse, et ajoute la tomber de neige
            doGen = TerrainGen.populate(chunkProvider, worldObj, rand, x, z, flag, ICE);
            for (x2 = 0; doGen && x2 < 16; ++x2)
            {
                for (z2 = 0; z2 < 16; ++z2)
                {
                    i2 = this.worldObj.getPrecipitationHeight(x1 + x2, z1 + z2);
    
                    if (this.worldObj.isBlockFreezable(x2 + x1, i2 - 1, z2 + z1))
                    {
                        this.worldObj.setBlock(x2 + x1, i2 - 1, z2 + z1, Blocks.ice, 0, 2);
                    }
    
                    if (this.worldObj.func_147478_e(x2 + x1, i2, z2 + z1, true))
                    {
                        this.worldObj.setBlock(x2 + x1, i2, z2 + z1, Blocks.snow_layer, 0, 2);
                    }
                }
            }
    
            MinecraftForge.EVENT_BUS.post(new PopulateChunkEvent.Post(chunkProvider, worldObj, rand, x, z, flag));
    
            BlockFalling.fallInstantly = false;
        }
    

    Si vous avez des erreurs sur les attributs LAVA, ANIMALS, DUNGEONS, ICE... Importez manuellement :

    import static net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.*;
    

    Même si le code est un peu expliqué je vais mieux vous l'expliquer.

    • Les premiers int (long ...) ne vous en préoccupez pas ce sont des choses comme les positions y ...
    • Ensuite, nous avons la condition que si nous activons les structures, nous générons les structures (qui sont dans cette condition), vous pouvez changer par vos classes.
    • Nous déclarons des ints, qui seront initialisés par la suite, il correspondent aux trois vecteurs x, y et z.
    • Nous avons une condition qui nous permet de vérifier que ça ne soit pas un désert et qu'un int soit égal à une valeur. Si la condition est vérifiée nous générons un lac (vous pouvez changer par votre classe de génération), et nous mettons en quels blocs pour mon cas ça sera en bloc d'eau, mais vous pouvez changer par votre propre bloc.
    • La condition est presque identique à la précédente sauf que nous générons un lac de lave.
    • Nous ajoutons la génération des donjons.
    • Ensuite, nous ajoutons l'apparition de certains mobs.
    • Cela nous permet de changer des blocs en glace (bloc d'eau) et de faire tomber de la neige.
    • N'oubliez pas que vous pouvez changer par vos classes et qu'ils ne sont pas tous essentiel.

    Nous allons ajouter le reste des fonctions de la classe, ajoutez :

        public boolean saveChunks(boolean par1, IProgressUpdate par2IProgressUpdate)
        {
            return true;
        }
    
        public void saveExtraData() {}
    
        public boolean unloadQueuedChunks()
        {
            return false;
        }
    
        public boolean canSave()
        {
            return true;
        }
    
        public String makeString()
        {
            return "RandomLevelSource";
        }
    
        public List getPossibleCreatures(EnumCreatureType par1EnumCreatureType, int par2, int par3, int par4)
        {
            /*TODO*/BiomeGenPlains biomegenbase = (/*TODO*/BiomeGenPlains)this.worldObj.getBiomeGenForCoords(par2, par4);
            return par1EnumCreatureType == EnumCreatureType.monster && this.scatteredFeatureGenerator.func_143030_a(par2, par3, par4) ? this.scatteredFeatureGenerator.getScatteredFeatureSpawnList() : biomegenbase.getSpawnableList(par1EnumCreatureType);
        }
    
        public ChunkPosition func_147416_a(World world, String strg, int x, int y, int z)
        {
            return null;
        }
    
        public int getLoadedChunkCount()
        {
            return 0;
        }
    
        public void recreateStructures(int par1, int par2)
        {
            if (this.mapFeaturesEnabled)
            {
                this.mineshaftGenerator.func_151539_a(this, this.worldObj, par1, par2, (Block[])null);
                this.scatteredFeatureGenerator.func_151539_a(this, this.worldObj, par1, par2, (Block[])null);
            }
        }
    

    N'oubliez pas de tout importer (Ctrl + shift + o) et normalement toutes les erreurs devraient partir.
    Mais à quoi ça correspond ? (la liste est dans l'ordre des fonctions) :

    • Ceci permet de sauvegarder tous les niveaux en une seule fois.
    • Cela permet de sauvegarder ce qui ne concerne pas les chunks.
    • Cette fonction permet de décharger certains chunks.
    • Je pense qu'un minimum d'anglais s'impose si vous ne comprenez pas, ça veut dire : les chunks supportent-ils la sauvegarde ? Dans notre cas nous mettons oui.
    • Cela convertit des données en chose lisible pour le monde (oui, moi aussi je n'aime pas dire chose, truc ...).
    • Voilà la liste des créatures qui peuvent spawn, mais dans la classe cela n'est pas très important, car ça se passe dans une autre classe.
    • Je crois bien que ceci est pour une génération. Nous nous en avons pas elle est donc null.
    • Là nous démontrons le nombre de chunks qui doivent rester chargés.
    • Nous ajoutons la liste habituelle des structures (quand l'option "Générer des structures" est sur "ON").
      Voilà nous en avons enfin fini avec cette très longue classe d'environ 520 lignes, reste plus qu'à faire la suite.

    De plus, si jamais vous voulez des ravins, des grottes... Il vous faut créer vos propres classes si vous utilisez une autre stone et remplacer dans le code (en créant une classe similaire) Blocks.stone par votre bloc.

    La classe GenLayer :

    La classe GenLayer nous permet la génération de nos biomes, nous pouvons y configurer les endroits où seront les biomes dans le monde, dans cette classe nous allons seulement faire la génération de biome.
    Donc comme toujours, créez une classe abstraite et ajoutez l'extension :

    GenLayer
    

    Ensuite, importez la classe (Ctrl + shift + o).
    Ce qui doit vous donner :

    public abstract class TutoGenLayer extends  GenLayer
    {
        public TutoGenLayer(long par1) 
        {
            super(par1);
        }
    }
    

    Ensuite, ajoutez la fonction suivante :

        public static GenLayer[] makeTheWorld(long l)
        {
    
        }
    

    Dans cette fonction nous ajouterons les lignes de code permettant de générer des biomes et le monde en général.
    Maintenant complétez en ajoutant :

            GenLayer biomes = new TutoGenLayerBiome(1L);
    
            biomes = new GenLayerZoom(1000L, biomes);
            biomes = new GenLayerZoom(1001L, biomes);
            biomes = new GenLayerZoom(1002L, biomes);
            biomes = new GenLayerZoom(1003L, biomes);
            biomes = new GenLayerZoom(1004L, biomes);
            biomes = new GenLayerZoom(1005L, biomes);
    
            GenLayer genlayervoronoizoom = new GenLayerVoronoiZoom(10L, biomes);
            biomes.initWorldGenSeed(l);
            genlayervoronoizoom.initWorldGenSeed(l);
    
            return new GenLayer[] {biomes, genlayervoronoizoom};
    
    • Ici, nous donnons les biomes que nous aurons. Cette classe n'est pas encore créée donc vous devriez avoir une erreur.
    • Les GenLayerZoom sont les valeurs de la génération de couche; elle peut concerner d'autre informations que les couches, comme la température etc...
    • Ceci donne encore des informations sur le monde.
    • Nous prenons en compte le seed du monde.
    • Idem :).
    • Nous retournons par un tableau au "biomes", et au "genlayervoronoizoo".
      Nous en avons fini avec cette classe, nous passons donc à une autre classe.

    La classe BiomeGenLayer :

    Dans cette classe nous enregistrerons tous les biomes de notre dimension. Commencez en créant une classe et en lui ajoutant GenLayer comme classe mère.

    Ensuite ajoutez :

        protected BiomeGenBase[] baseBiome = {BiomeGenBase.//Biome};
    
        public TutoBiomeGenLayer(long seed)
        {
            super(seed);
        }
    
        @Override
        public int[] getInts(int coordX, int coordZ, int width, int depth) 
        {
    
        }
    

    Ici, nous ajoutons un tableau. Vous devez mettre toujours le biome que vous avez mis dans vos autres classes, ou que vous mettrez plus tard, mais dans ce tableau tous les biomes devront être mis. Tous les biomes doivent avoir l'extends de votre biome de base (le biome mis dans toutes les autres classes), ou de une de vos classes, mais nous reparlerons de ça plus tard.
    Complétez la fonction getInts en ajoutant :

            int[] dest = IntCache.getIntCache(width * depth);
    
            for(int dz = 0; dz < depth; dz++)
            {
                for(int dx = 0; dx < width; dx++)
                {
                    this.initChunkSeed(dx + coordX, dz + coordZ);
                    dest[(dx + dz * width)] = this.baseBiome[nextInt(this.baseBiome.length)].biomeID;
                }
            }
            return dest;
    

    Cela permettra la génération de vos biomes. Nous en avons fini avec les classes GenLayer.

    La classe Teleporter :

    La classe "Teleporter" sera la classe qui permettra d'envoyer le joueur dans notre dimension.

    Pour commencer ajoutez cette extension :

        Teleporter
    

    puis ceci :

        private final WorldServer worldServerInstance;
        private final Random random;
        private final LongHashMap destinationCoordinateCache = new LongHashMap();
    
        private final List destinationCoordinateKeys = new ArrayList();
    
        public TutoTeleporter(WorldServer worldServer)
        {
    
        }
    
        public void placeInPortal(Entity entity, double x, double y, double z, float rotationYaw)
        {
    
        }
    
        public boolean placeInExistingPortal(Entity entity, double x, double y, double z, float rotationYaw)
        {
    
        }
    
        public boolean makePortal(Entity entity)
        {
    
        }
    

    Les fonctions permettent de :

    • La fonction (constructeur) qui correspond au nom de votre classe permet d'initialiser des fields.
    • "placeInPortal", permet de placer l'entité dans un portail ou de le créer (appelle les deux autres fonctions).
    • "placeInExistingPortal" va mettre l'entité dans un portail déjà existant s'il existe.
    • "makePortal" va permettre de créer notre portail au passage de la dimension, la fonction est appelé uniquement si aucun portail est trouvé.

    Complétez la première fonction (constructeur) avec :

            super(worldServer);
            this.worldServerInstance = worldServer;
            this.random = new Random(worldServer.getSeed());
    

    Ici, nous initialisons des fields.
    Dans la fonction placeInPortal ajoutez la condition :

            if(this.worldServerInstance.provider.dimensionId != 1)
            {
                if(!this.placeInExistingPortal(entity, x, y, z, rotationYaw))
                {
                    this.makePortal(entity);
                    this.placeInExistingPortal(entity, x, y, z, rotationYaw);
                }
            }
    

    Cette fonction vas regarder si la dimension n'est pas la dimension portant l'ID 1 (l'overworld).
    Ensuite, ajoutez :

            else
            {
                int i = MathHelper.floor_double(entity.posX);//position x
                int j = MathHelper.floor_double(entity.posY) - 1;//position y
                int k = MathHelper.floor_double(entity.posZ);//position z
                byte b0 = 1;
                byte b1 = 0;
                for(int l = -2; l <= 2; ++l)
                {
                    for(int i1 = -2; i1 <= 2; ++i1)
                    {
                        for(int j1 = -1; j1 < 3; ++j1)
                        {
                            int k1 = i + i1 * b0 + l * b1;
                            int l1 = j + j1;
                            int i2 = k + i1 * b1 - l * b0;
                            boolean flag = j1 < 0;
    
                            //set la structure
                            this.worldServerInstance.setBlock(k1, l1, i2, flag ? Blocks.stone : Blocks.air);
                        }
                    }
                }
                entity.setLocationAndAngles((double)i, (double)j, (double)k, entity.rotationYaw, 0.0F);
                entity.motionX = entity.motionY = entity.motionZ = 0.0D;
            }
    

    permet de générer comme il faut la structure.
    Ensuite, dans la troisième fonction :

            short short1 = 128;
            double d3 = -1.0D;
            int i = 0;
            int j = 0;
            int k = 0;
            int l = MathHelper.floor_double(entity.posX);// position x
            int i1 = MathHelper.floor_double(entity.posZ);// position z
            long j1 = ChunkCoordIntPair.chunkXZ2Int(l, i1);// convertit en un nombre
                                                            // entier pour le hach
            boolean flag = true;
            double d4;
            int k1;
    
            if(this.destinationCoordinateCache.containsItem(j1))
            {
                PortalPosition portalposition = (PortalPosition)this.destinationCoordinateCache.getValueByKey(j1);
                d3 = 0.0D;
                i = portalposition.posX;// position x
                j = portalposition.posY;// position y
                k = portalposition.posZ;// position z
                portalposition.lastUpdateTime = this.worldServerInstance.getTotalWorldTime();
                flag = false;
            }
    
            else
            {
                for(k1 = l - short1; k1 <= l + short1; ++k1)
                {
                    double d5 = (double)k1 + 0.5D - entity.posX;
                    for(int l1 = i1 - short1; l1 <= i1 + short1; ++l1)
                    {
                        double d6 = (double)l1 + 0.5D - entity.posZ;
                        // renvoie a la hauteur du monde
                        for(int i2 = this.worldServerInstance.getActualHeight() - 1; i2 >= 0; --i2)
                        {
                            if(this.worldServerInstance.getBlock(k1, i2, l1) == TutoDimension.tutoPortail)
                            {
                                while(this.worldServerInstance.getBlock(k1, i2 - 1, l1) == TutoDimension.tutoPortail)
                                {
                                    --i2;
                                }
                                d4 = (double)i2 + 0.5D - entity.posY;
                                double d7 = d5 * d5 + d4 * d4 + d6 * d6;
                                if(d3 < 0.0D || d7 < d3)
                                {
                                    d3 = d7;
                                    i = k1;
                                    j = i2;
                                    k = l1;
                                }
                            }
                        }
                    }
                }
            }
    
            if(d3 >= 0.0D)
            {
                if(flag)
                { // ajoute des valeurs au LongHashMap
                    this.destinationCoordinateCache.add(j1, new TutoPortalPosition(this, i, j, k, this.worldServerInstance.getTotalWorldTime()));
                    this.destinationCoordinateKeys.add(Long.valueOf(j1));
                }
                double d8 = (double)i + 0.5D;
                double d9 = (double)j + 0.5D;
                d4 = (double)k + 0.5D;
                int j2 = -1;
                if(this.worldServerInstance.getBlock(i - 1, j, k) == TutoDimension.tutoPortail)
                {
                    j2 = 2;
                }
                if(this.worldServerInstance.getBlock(i + 1, j, k) == TutoDimension.tutoPortail)
                {
                    j2 = 0;
                }
                if(this.worldServerInstance.getBlock(i, j, k - 1) == TutoDimension.tutoPortail)
                {
                    j2 = 3;
                }
                if(this.worldServerInstance.getBlock(i, j, k + 1) == TutoDimension.tutoPortail)
                {
                    j2 = 1;
                }
                int k2 = entity.getTeleportDirection();
                if(j2 > -1)
                { // la position de l'entité dans le monde après avoir passer le
                    // portail
                    int l2 = Direction.rotateLeft[j2];
                    int i3 = Direction.offsetX[j2];
                    int j3 = Direction.offsetZ[j2];
                    int k3 = Direction.offsetX[l2];
                    int l3 = Direction.offsetZ[l2];
                    boolean flag1 = !this.worldServerInstance.isAirBlock(i + i3 + k3, j, k + j3 + l3) || !this.worldServerInstance.isAirBlock(i + i3 + k3, j + 1, k + j3 + l3);
                    boolean flag2 = !this.worldServerInstance.isAirBlock(i + i3, j, k + j3) || !this.worldServerInstance.isAirBlock(i + i3, j + 1, k + j3);
                    if(flag1 && flag2)
                    {
                        j2 = Direction.rotateOpposite[j2];
                        l2 = Direction.rotateOpposite[l2];
                        i3 = Direction.offsetX[j2];
                        j3 = Direction.offsetZ[j2];
                        k3 = Direction.offsetX[l2];
                        l3 = Direction.offsetZ[l2];
                        k1 = i - k3;
                        d8 -= (double)k3;
                        int i4 = k - l3;
                        d4 -= (double)l3;
                        flag1 = !this.worldServerInstance.isAirBlock(k1 + i3 + k3, j, i4 + j3 + l3) || !this.worldServerInstance.isAirBlock(k1 + i3 + k3, j + 1, i4 + j3 + l3);
                        flag2 = !this.worldServerInstance.isAirBlock(k1 + i3, j, i4 + j3) || !this.worldServerInstance.isAirBlock(k1 + i3, j + 1, i4 + j3);
                    }
                    float f1 = 0.5F;
                    float f2 = 0.5F;
                    if(!flag1 && flag2)
                    {
                        f1 = 1.0F;
                    }
                    else if(flag1 && !flag2)
                    {
                        f1 = 0.0F;
                    }
                    else if(flag1 && flag2)
                    {
                        f2 = 0.0F;
                    }
                    d8 += (double)((float)k3 * f1 + f2 * (float)i3);
                    d4 += (double)((float)l3 * f1 + f2 * (float)j3);
                    float f3 = 0.0F;
                    float f4 = 0.0F;
                    float f5 = 0.0F;
                    float f6 = 0.0F;
                    if(j2 == k2)
                    {
                        f3 = 1.0F;
                        f4 = 1.0F;
                    }
                    else if(j2 == Direction.rotateOpposite[k2])
                    {
                        f3 = -1.0F;
                        f4 = -1.0F;
                    }
                    else if(j2 == Direction.rotateRight[k2])
                    {
                        f5 = 1.0F;
                        f6 = -1.0F;
                    }
                    else
                    {
                        f5 = -1.0F;
                        f6 = 1.0F;
                    }
                    double d10 = entity.motionX;
                    double d11 = entity.motionZ;
                    entity.motionX = d10 * (double)f3 + d11 * (double)f6;
                    entity.motionZ = d10 * (double)f5 + d11 * (double)f4;
                    entity.rotationYaw = rotationYaw - (float)(k2 * 90) + (float)(j2 * 90);
                }
                else
                {
                    entity.motionX = entity.motionY = entity.motionZ = 0.0D;
                }
                entity.setLocationAndAngles(d8, d9, d4, entity.rotationYaw, entity.rotationPitch);
                return true;
            }
            else
            {
                return false;
            }
    

    Il est très dur de vous décrire le code, je pense qu'en regardant vous comprendrez.
    Ensuite, dans la dernière fonction ajoutez :

            byte b0 = 16;
            double d0 = -1.0D;
            int x = MathHelper.floor_double(entity.posX);// position x
            int y = MathHelper.floor_double(entity.posY);// position y
            int z = MathHelper.floor_double(entity.posZ);// position z
            int l = x;
            int i1 = y;
            int j1 = z;
            int k1 = 0;
            int l1 = this.random.nextInt(4);
            int i2;
            double d1;
            int k2;
            double d2;
            int i3;
            int j3;
            int k3;
            int l3;
            int i4;
            int j4;
            int k4;
            int l4;
            int i5;
            double d3;
            double d4;
    
            for(i2 = x - b0; i2 <= x + b0; ++i2)
            {
                d1 = (double)i2 + 0.5D - entity.posX;
    
                for(k2 = z - b0; k2 <= z + b0; ++k2)
                {
                    d2 = (double)k2 + 0.5D - entity.posZ;
                    label274:
    
                    for(i3 = this.worldServerInstance.getActualHeight() - 1; i3 >= 0; --i3)
                    {
                        // si le blocs et un bloc d'air
                        if(this.worldServerInstance.isAirBlock(i2, i3, k2))
                        {
                            while(i3 > 0 && this.worldServerInstance.isAirBlock(i2, i3 - 1, k2))
                            {
                                --i3;
                            }
    
                            for(j3 = l1; j3 < l1 + 4; ++j3)
                            {
                                k3 = j3 % 2;
                                l3 = 1 - k3;
    
                                if(j3 % 4 >= 2)
                                {
                                    k3 = -k3;
                                    l3 = -l3;
                                }
    
                                for(i4 = 0; i4 < 3; ++i4)
                                {
                                    for(j4 = 0; j4 < 4; ++j4)
                                    {
                                        for(k4 = -1; k4 < 4; ++k4)
                                        {
                                            l4 = i2 + (j4 - 1) * k3 + i4 * l3;
                                            i5 = i3 + k4;
                                            int j5 = k2 + (j4 - 1) * l3 - i4 * k3;
    
                                            // si k4 et inférieur a 0 et que le
                                            // blocs n'est pas solide ou si k4 et
                                            // égale ou inférieur a 0 et que le bloc
                                            // est pas d'air nous retournons ou
                                            // label274 plus haut
                                            if(k4 < 0 && !this.worldServerInstance.getBlock(l4, i5, j5).getMaterial().isSolid() || k4 >= 0 && !this.worldServerInstance.isAirBlock(l4, i5, j5))
                                            {
                                                continue label274;
                                            }
                                        }
                                    }
                                }
    
                                d3 = (double)i3 + 0.5D - entity.posY;
                                d4 = d1 * d1 + d3 * d3 + d2 * d2;
    
                                if(d0 < 0.0D || d4 < d0)
                                {
                                    d0 = d4;
                                    l = i2;
                                    i1 = i3;
                                    j1 = k2;
                                    k1 = j3 % 4;
                                }
                            }
                        }
                    }
                }
            }
    
            if(d0 < 0.0D)
            {
                for(i2 = x - b0; i2 <= x + b0; ++i2)
                {
                    d1 = (double)i2 + 0.5D - entity.posX;
    
                    for(k2 = z - b0; k2 <= z + b0; ++k2)
                    {
                        d2 = (double)k2 + 0.5D - entity.posZ;
                        label222:
    
                        for(i3 = this.worldServerInstance.getActualHeight() - 1; i3 >= 0; --i3)
                        {
                            if(this.worldServerInstance.isAirBlock(i2, i3, k2))
                            {
                                while(i3 > 0 && this.worldServerInstance.isAirBlock(i2, i3 - 1, k2))
                                {
                                    --i3;
                                }
    
                                for(j3 = l1; j3 < l1 + 2; ++j3)
                                {
                                    k3 = j3 % 2;
                                    l3 = 1 - k3;
    
                                    for(i4 = 0; i4 < 4; ++i4)
                                    {
                                        for(j4 = -1; j4 < 4; ++j4)
                                        {
                                            k4 = i2 + (i4 - 1) * k3;
                                            l4 = i3 + j4;
                                            i5 = k2 + (i4 - 1) * l3;
                                            // si k4 et inférieur a 0 et que le
                                            // blocs n'est pas solide ou si k4 et
                                            // égale ou inférieur a 0 et que le bloc
                                            // est pas d'air nous retournons ou
                                            // label222 plus haut
                                            if(j4 < 0 && !this.worldServerInstance.getBlock(k4, l4, i5).getMaterial().isSolid() || j4 >= 0 && !this.worldServerInstance.isAirBlock(k4, l4, i5))
                                            {
                                                continue label222;
                                            }
                                        }
                                    }
    
                                    d3 = (double)i3 + 0.5D - entity.posY;
                                    d4 = d1 * d1 + d3 * d3 + d2 * d2;
    
                                    if(d0 < 0.0D || d4 < d0)
                                    {
                                        d0 = d4;
                                        l = i2;
                                        i1 = i3;
                                        j1 = k2;
                                        k1 = j3 % 2;
                                    }
                                }
                            }
                        }
                    }
                }
            }
    
            int k5 = l;
            int j2 = i1;
            k2 = j1;
            int l5 = k1 % 2;
            int l2 = 1 - l5;
    
            if(k1 % 4 >= 2)
            {
                l5 = -l5;
                l2 = -l2;
            }
    
            boolean flag;
    
            if(d0 < 0.0D)
            {
                if(i1 < 70)
                {
                    i1 = 70;
                }
    
                if(i1 > this.worldServerInstance.getActualHeight() - 10)
                {
                    i1 = this.worldServerInstance.getActualHeight() - 10;
                }
    
                j2 = i1;
    
                for(i3 = -1; i3 <= 1; ++i3)
                {
                    for(j3 = 1; j3 < 3; ++j3)
                    {
                        for(k3 = -1; k3 < 3; ++k3)
                        {
                            l3 = k5 + (j3 - 1) * l5 + i3 * l2;
                            i4 = j2 + k3;
                            j4 = k2 + (j3 - 1) * l2 - i3 * l5;
                            flag = k3 < 0;
                            // permet de set des blocs de stone et air au bonne
                            // endroit
                            this.worldServerInstance.setBlock(l3, i4, j4, flag ? Blocks.stone : Blocks.air);
                        }
                    }
                }
            }
    
            for(i3 = 0; i3 < 4; ++i3)
            {
                for(j3 = 0; j3 < 4; ++j3)
                {
                    for(k3 = -1; k3 < 4; ++k3)
                    {
                        l3 = k5 + (j3 - 1) * l5;
                        i4 = j2 + k3;
                        j4 = k2 + (j3 - 1) * l2;
                        flag = j3 == 0 || j3 == 3 || k3 == -1 || k3 == 3;
                        // permet de set des blocs de stone et portail au bonne
                        // endroit
                        this.worldServerInstance.setBlock(l3, i4, j4, (flag ? Blocks.stone : TutoDimension.tutoPortail), 0, 2);
                    }
                }
    
                for(j3 = 0; j3 < 4; ++j3)
                {
                    for(k3 = -1; k3 < 4; ++k3)
                    {
                        l3 = k5 + (j3 - 1) * l5;
                        i4 = j2 + k3;
                        j4 = k2 + (j3 - 1) * l2;
                        this.worldServerInstance.notifyBlocksOfNeighborChange(l3, i4, j4, this.worldServerInstance.getBlock(l3, i4, j4));
                    }
                }
            }
    
            return true;
        }
    

    Cette fonction permet de faire le portail en modifiant les int des l3, i4, j4, nous pouvons changer le portail.
    Après cette fonction nous allons ajouter la classe interne :

    class TutoPortalPosition extends ChunkCoordinates
    {
    
    }
    

    Terminez la fonction avec :

        public long time;
        final TutoTeleporter teleporter;
    
        public TutoPortalPosition(TutoTeleporter teleporter, int x, int y, int z, long creationTime)
        {
    
        }
    
        @Override
        public int compareTo(Object o)
        {
    
        }
    

    Dans la fonction ajoutez :

            super(x, y, z);
            this.teleporter = teleporter;
            this.time = creationTime;
    

    Ceci est le temps où le portail sera vérifié.
    Nous en avons fini avec la classe pleine de calcul qui est le "Teleporter".

    WorldChunkManager

    Commencez à ajouter l’extension :

    extends WorldChunkManager
    

    Dans cette classe ajoutez tout ça, nous compléterons fonction par fonction. Ajoutez :

        /**
            * GenLayer = classe de GenLayer si vous utiliser un GenLayer qui n’hérite
            * pas de la classe GenLayer alors il faut changer par votre classe
            */
        private GenLayer genBiomes;
        private GenLayer biomeIndexLayer;
        /** L'objet du BiomeCache pour le monde */
        private BiomeCache biomeCache;
        /** List des biome ou le joueur peu spawn */
        private List<BiomeGenBase> biomesToSpawnIn;
    
        protected TutoWorldChunkManager()
        {
    
        }
    
        public TutoWorldChunkManager(long par1, WorldType worldType)
        {
    
        }
    
        public TutoWorldChunkManager(World world)
        {
    
        }
    
        /** Permet d'obtenir la list des biomes ou le joueur peut apparaitre */
        public List<BiomeGenBase> getBiomesToSpawnIn()
        {
    
        }
    
        /** Renvoie au BiomeGenBase a la position x, z relative dans le monde */
        public BiomeGenBase getBiomeGenAt(int x, int z)
        {
    
        }
    
        /**
            * Retourne a la list des valeurs pour la pluis... ... pour en fonction de
            * blocs spésifier
            */
        public float[] getRainfall(float[] par1ArrayOfFloat, int par2, int par3, int par4, int par5)
        {
    
        }
    
        /** Retourne a une température donner par raport au y */
        @SideOnly(Side.CLIENT)
        public float getTemperatureAtHeight(float par1, int par2)
        {
    
        }
    
        /** Retourne à un tableau pour les biomes a générer */
        public BiomeGenBase[] getBiomesForGeneration(BiomeGenBase[] par1ArrayOfBiomeGenBase, int par2, int par3, int par4, int par5)
        {
    
        }
    
        /** Retourne au biome et charge les données pour les blocs */
        public BiomeGenBase[] loadBlockGeneratorData(BiomeGenBase[] par1ArrayOfBiomeGenBase, int par2, int par3, int par4, int par5)
        {
    
        }
    
        /**
            * Retourne a une liste de biome pour les blocs spécifiés argument : x, y,
            * largeur, longueur, cache.
            */
        public BiomeGenBase[] getBiomeGenAt(BiomeGenBase[] arrayOfBiomeGenBase, int x, int y, int width, int length, boolean cacheFlag)
        {
    
        }
    
        /** Verifie les données du chunk */
        public boolean areBiomesViable(int x, int y, int z, List par4List)
        {
    
        }
    
        /** Trouve un biome dans un chunk */
        public ChunkPosition findBiomePosition(int x, int y, int z, List list, Random rand)
        {
    
        }
    
        /** Supprime le biome dans les 30s. si il n'est pas vérifier dans la temps */
        public void cleanupCache()
        {
    
        }
    }
    

    Nous ajoutons quelques fonctions et des fields. Tous est décrit donc vous avez seulement à lire.
    Dans la première fonction (constructeur) ajoutez :

            this.biomeCache = new BiomeCache(this);
            // liste des biomes ou nous spawons
            this.biomesToSpawnIn = new ArrayList<BiomeGenBase>();
            // Ce biome n'est pas le biome ou vous spawner forcement, mais dans
            // toute les classes il devra être mis
            this.biomesToSpawnIn.add(BiomeGenBase.forest);
    

    Après dans la seconde fonction ajoutez :

            this();
            /**
                * Appele la fonction makeTheWorld dans la classe TutoGenLayer, la
                * fonction est la fonction de génération de nos biome
                */
            GenLayer[] agenlayer = TutoGenLayer.makeTheWorld(par1);
            this.genBiomes = agenlayer[0];
            this.biomeIndexLayer = agenlayer[1];
    

    Ajoutez dans la troisième fonction :

            this(world.getSeed(), world.provider.terrainType);
    

    Dans la fonction suivante il vous faut ajouter :

            return this.biomesToSpawnIn;
    

    Ce qui permet de retourner à la liste des biomes où le joueur peut spawn.
    Dans la fonction getBiomeGenAt ajoutez :

            BiomeGenBase biome = this.biomeCache.getBiomeGenAt(x, z);
            if(biome == null)
            {
                return BiomeGenBase.forest;
    
            }
            return biome;
    

    La fonction vous est expliquée.
    Ensuite, ajoutez la fonction suivante :

            if(par1ArrayOfFloat == null || par1ArrayOfFloat.length < par4 * par5)
            {
                par1ArrayOfFloat = new float[par4 * par5];
            }
    
            Arrays.fill(par1ArrayOfFloat, 0, par4 * par5, 0.0F);
            return par1ArrayOfFloat;
    

    La fonction est décrite juste au-dessus.
    Dans le getTemperatureAtHeight ajoutez :

                    return par 1
    

    Après ajoutez dans la fonction suivante :

            IntCache.resetIntCache();
    
            if(par1ArrayOfBiomeGenBase == null || par1ArrayOfBiomeGenBase.length < par4 * par5)
            {
                par1ArrayOfBiomeGenBase = new BiomeGenBase[par4 * par5];
            }
    
            int[] aint = this.genBiomes.getInts(par2, par3, par4, par5);
    
            for(int i = 0; i < par4 * par5; ++i)
            {
                if(aint* >= 0)
                {
                    par1ArrayOfBiomeGenBase* = BiomeGenBase.getBiome(aint*);
                }
                else
                {
                    par1ArrayOfBiomeGenBase* = BiomeGenBase.forest;
                }
            }
    
            return par1ArrayOfBiomeGenBase;
    

    La fonction est aussi mise au dessus.
    La fonction loadBlockGeneratorData est à compléter avec :

            return this.getBiomeGenAt(par1ArrayOfBiomeGenBase, par2, par3, par4, par5, true);
    

    Dans la fonction getBiomeGenAt terminez avec :

            IntCache.resetIntCache();
    
            if(arrayOfBiomeGenBase == null || arrayOfBiomeGenBase.length < width * length)
            {
                arrayOfBiomeGenBase = new BiomeGenBase[width * length];
            }
    
            if(cacheFlag && width == 16 && length == 16 && (x & 15) == 0 && (y & 15) == 0)
            {
                BiomeGenBase[] abiomegenbase1 = this.biomeCache.getCachedBiomes(x, y);
                System.arraycopy(abiomegenbase1, 0, arrayOfBiomeGenBase, 0, width * length);
                return arrayOfBiomeGenBase;
            }
            else
            {
                int[] aint = this.biomeIndexLayer.getInts(x, y, width, length);
    
                for(int i1 = 0; i1 < width * length; ++i1)
                {
                    if(aint[i1] >= 0)
                    {
                        arrayOfBiomeGenBase[i1] = BiomeGenBase.getBiome(aint[i1]);
                    }
    
                    else
                    {
                        arrayOfBiomeGenBase[i1] = BiomeGenBase.forest;
                    }
                }
    
                return arrayOfBiomeGenBase;
            }
    

    La fonction est aussi expliquée.
    Après ceci, ajoutez dans la fonction :

            IntCache.resetIntCache();
            int l = x - z >> 2;
            int i1 = y - z >> 2;
            int j1 = x + z >> 2;
            int k1 = y + z >> 2;
            int l1 = j1 - l + 1;
            int i2 = k1 - i1 + 1;
            int[] aint = this.genBiomes.getInts(l, i1, l1, i2);
    
            for(int j2 = 0; j2 < l1 * i2; ++j2)
            {
                BiomeGenBase biomegenbase = BiomeGenBase.getBiome(aint[j2]);
    
                if(!par4List.contains(biomegenbase))
                {
                    return false;
                }
            }
    
            return true;
    

    La fonction est aussi décrite au dessus.
    Dans la dernière fonction qui est aussi décrite ajoutez :

            this.biomeCache.cleanupCache();
    

    Nous en avons fini avec cette classe.

    WorldProvider :

    Pour cette classe ajoutez l’extension suivante :

    extends WorldProvider
    

    Ensuite, ajoutez une fonction :

        public void registerWorldChunkManager()
        {
    
        }
    

    Nous allons un peu la compléter, donc ajoutez :

            this.worldChunkMgr = new TutoWorldChunkManager(worldObj.getSeed(), terrainType);
            this.dimensionId = TutoDimension.tutoDimID;
    
    • Le premier permet de dire quel est notre WorldChunkManager, donc mettez votre WorldChunkManager.
    • La seconde permet de donner l'ID de la dimension, cet ID doit être le même partout, donc je vous conseille de mettre un "int" et de lui donner votre propre valeur, ça permet aussi d'ajouter un fichier de configuration facilement.
      Vous pouvez aussi ajouter :
    this.hasNoSky = false;
    this.isHellWorld = false;
    

    Le premier demande s'il y a pas de ciel et la seconde si nous sommes dans un HellWorld (Enfer).
    Nous allons ensuite ajouter quelques fonctions bien pratique comme :

        public IChunkProvider createChunkGenerator()
        {
            return new TutoChunkProvider(this.worldObj, this.worldObj.getSeed(), false);
        }
    

    Cette fonction permet de dire quel est notre ChunkProvider.
    Il y a aussi cette fonction :

        public String getDimensionName()
        {
            return "tuto";
        }
    

    Le nom de votre dimension.
    Et cette fonction :

    public String getSaveFolder()
    {
        return "tutoDim";
    }
    

    Le dossier où est sauvegardé la dimension.
    Je vais vous donner encore quelques autre fonctions.

    public boolean canRespawnHere()
    {
        return false;
    }
    

    True si le joueur peut réapparaître dedans sinon vous le mettez en false.

    public boolean isSurfaceWorld()
    {
        return true;
    }
    

    Si notre monde est à la surface.

    public boolean getWorldHasVoidParticles()
    {
        return true;
    }
    

    Si nous avons des particules de vide qui son jouées en fonction de la hauteur du Y (quand le joueur tombe dans le vide).

        public int getHeight()
        {
            return 256;
        }
    

    La hauteur du monde.

    public boolean canCoordinateBeSpawn(int par1, int par2)
    {
        return this.worldObj.getTopBlock(par1, par2) == Blocks.grass;
    }
    

    Le bloc sur lequel le joueur peut apparaître (ne vous inquiétez pas si vous ajoutez un désert, il apparaît sur le sable).

        protected void generateLightBrightnessTable()
        {
            float f = 0.2F;
    
            for(int i = 0; i <= 15; ++i)
            {
                    float f1 = 1.0F - (float)i / 15.0F;
                    this.lightBrightnessTable* = (1.0F - f1) / (f1 * 3.0F + 1.0F) * (1.0F - f) + f;
            }
        }
    

    La lumière dans le monde (vous pouvez la modifier).

        public float calculateCelestialAngle(long par1, float par2)
        {
            int j = (int)(par1 % 24000L);
            float f1 = ((float)j + par2) / 24000.0F - 0.25F;
    
            if(f1 < 0.0F)
            {
                        ++f1;
            }
            if(f1 > 1.0F)
            {
                    --f1;
            }
            float f2 = f1;
            f1 = 1.0F - (float)((Math.cos((double)f1 * Math.PI) + 1.0D) / 2.0D);
            f1 = f2 + (f1 - f2) / 3.0F;
            return f1;
        }
    

    Les angles du soleil et de la lune, vous pouvez les modifier.

    public int getMoonPhase(long par1)
    {
        return (int)(par1 / 24000L % 8L + 8L) % 8;
    }
    

    Permet d'obtenir les phases de la lune (vous pouvez les modifier, mais pas trop :P).

    public String getWelcomeMessage()
    {
        if(this instanceof TutoWorldProvider)
        {
            return "Entering the Tuto Dimension";
        }
        return null;
    }
    

    Le message affiché quand le joueur entre dans la dimension.

    public String getDepartMessage()
    {
        if(this instanceof TutoWorldProvider)
        {
            return "Leaving the Tuto Dimension";
        }
        return null;
    }
    

    Le message affiché quand le joueur quitte la dimension.

    public double getMovementFactor()
    {
        if(this instanceof TutoWorldProvider)
        {       //a changé par votre valeur
            return 10.0;
        }
        return 1.0;
    }
    

    Si vous n'ajoutez pas cette fonction rien ne se passera, mais dans notre cas cela correspond au nombre de blocs dans l'overworld par rapport à notre dimension, dans mon cas 10 blocs pour l'overworld fait un bloc dans la dimension (comme le nether, mais avec 8 blocs), si vous n'ajoutez pas cette fonction par défaut nous serons à 1.

        @SideOnly(Side.CLIENT)
        public boolean isSkyColored()
        {
            return true;
        }
    

    Si le ciel a une couleur.

    @Override
    public Vec3 getSkyColor(Entity cameraEntity, float partialTicks)
    {                                 //à modifier pour changer la couleur
        return Vec3.createVectorHelper(2.8, 1.1, 1.7);
    }
    

    La couleur du ciel.
    Voilà nous avons fini notre classe.



  • Le portailBlock :

    Ce bloc vous permettra d’accéder dans votre dimension. Vous pouvez aussi ajouter des fonctions d'autres blocs pour permettre d'avoir un bloc plus complexe; pour le coup dans le tutoriel nous allons seulement créer un bloc simple.
    Comme d’habitude créez votre classe et ajoutez :

    extends Block
    

    Ensuite, importez la classe Block.
    Vous devriez avoir une erreur. Passer la souris dessus et faites "add constructor".
    Vous devriez avoir quelque chose comme ça :

    protected TutoPortail(Material p_i45394_1_)
    {
        super(p_i45394_1_);
    }
    

    Nous allons renommer le paramètre (prenez en l’habitude) en material ce qui donne :

    protected TutoPortail(Material material)
    {
        super(material);
    }
    

    Ensuite, nous allons ajouter :

    super(material.portal);//Le material de notre bloc
    this.setTickRandomly(true);//si le bloc et update de façons random
    this.setStepSound(Block.soundTypeGlass);//le son jouet une fois casser
    this.setLightLevel(0.75F);//le niveau de lumière
    this.setCreativeTab(CreativeTabs.tabBlock);//la creative tabs
    

    Ensuite, nous allons ajouter :

    @Override
    public void setBlockBoundsBasedOnState(IBlockAccess blockaccess, int x, int y, int z)
    {
        float f;
        float f1;
    
        if(!blockaccess.getBlock(x - 1, y, z).equals(this) && !blockaccess.getBlock(x + 1, y, z).equals(this))
        {
            f = 0.125F;
            f1 = 0.5F;
            this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f1, 0.5F + f, 1.0F, 0.5F + f1);
        }
        else
        {
            f = 0.5F;
            f1 = 0.125F;
            this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f1, 0.5F + f, 1.0F, 0.5F + f1);
        }
    }
    

    Avec ceci nous aurons une forme et une hitBox comme le bloc de portail de base.
    Ajoutez cette fonction :

    @Override
    public void setBlockBoundsForItemRender()
    {
        float f1 = 0.125F;
        this.setBlockBounds(0, 0.0F, 0.5F - f1, 1F, 1.0F, 0.5F + f1);
    }
    

    Ce sera le rendu en tant qu'item.
    Ajoutez après cela :

    @Override
    public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z)
    {
        return null;
    }
    

    Cela permet d'enlever la boite de collision (permet d'entrer dans le bloc).
    Après cette fonction nous allons ajouter :

    @Override
    public void onNeighborBlockChange(World world, int x, int y, int z, Block block)
    {
        int y2 = y;
        while(world.getBlock(x, y2, z).equals(this))
        {
            y2–;
        }
        if(!world.getBlock(x, y2, z).equals(Blocks.stone))
        {
            world.setBlockToAir(x, y, z);
        }
        int y3 = y2 + 1;
        boolean portalIsGood = false;
        if(world.getBlock(x, y3, z + 1).equals(this))
        {
            portalIsGood = (world.getBlock(x, y2, z).equals(Blocks.stone) && world.getBlock(x, y2, z + 1).equals(Blocks.stone) && world.getBlock(x, y2 + 1, z + 2).equals(Blocks.stone) && world.getBlock(x, y2 + 2, z + 2).equals(Blocks.stone) && world.getBlock(x, y2 + 3, z + 2).equals(Blocks.stone) && world.getBlock(x, y2 + 1, z - 1).equals(Blocks.stone) && world.getBlock(x, y2 + 2, z - 1).equals(Blocks.stone) && world.getBlock(x, y2 + 3, z - 1).equals(Blocks.stone) && world.getBlock(x, y2 + 4, z - 1).equals(Blocks.stone) && world.getBlock(x, y2 + 4, z).equals(Blocks.stone));
        }
        else if(world.getBlock(x, y3, z - 1).equals(this))
        {
            portalIsGood = (world.getBlock(x, y2, z).equals(Blocks.stone) && world.getBlock(x, y2, z - 1).equals(Blocks.stone) && world.getBlock(x, y2 + 1, z - 2).equals(Blocks.stone) && world.getBlock(x, y2 + 2, z - 2).equals(Blocks.stone) && world.getBlock(x, y2 + 3, z - 2).equals(Blocks.stone) && world.getBlock(x, y2 + 1, z + 1).equals(Blocks.stone) && world.getBlock(x, y2 + 2, z + 1).equals(Blocks.stone) && world.getBlock(x, y2 + 3, z + 1).equals(Blocks.stone) && world.getBlock(x, y2 + 4, z + 1).equals(Blocks.stone) && world.getBlock(x, y2 + 4, z).equals(Blocks.stone));
        }
        else if(world.getBlock(x + 1, y3, z).equals(this))
        {
            portalIsGood = (world.getBlock(x, y2, z).equals(Blocks.stone) && world.getBlock(x + 1, y2, z).equals(Blocks.stone) && world.getBlock(x + 2, y2 + 1, z).equals(Blocks.stone) && world.getBlock(x + 2, y2 + 2, z).equals(Blocks.stone) && world.getBlock(x + 2, y2 + 3, z).equals(Blocks.stone) && world.getBlock(x - 1, y2 + 1, z).equals(Blocks.stone) && world.getBlock(x - 1, y2 + 2, z).equals(Blocks.stone) && world.getBlock(x - 1, y2 + 3, z).equals(Blocks.stone) && world.getBlock(x + 1, y2 + 4, z).equals(Blocks.stone) && world.getBlock(x, y2 + 4, z).equals(Blocks.stone));
        }
        else if(world.getBlock(x - 1, y3, z).equals(this))
        {
            portalIsGood = (world.getBlock(x, y2, z).equals(Blocks.stone) && world.getBlock(x - 1, y2, z).equals(Blocks.stone) && world.getBlock(x - 2, y2 + 1, z).equals(Blocks.stone) && world.getBlock(x - 2, y2 + 2, z).equals(Blocks.stone) && world.getBlock(x - 2, y2 + 3, z).equals(Blocks.stone) && world.getBlock(x + 1, y2 + 1, z).equals(Blocks.stone) && world.getBlock(x + 1, y2 + 2, z).equals(Blocks.stone) && world.getBlock(x + 1, y2 + 3, z).equals(Blocks.stone) && world.getBlock(x + 1, y2 + 4, z).equals(Blocks.stone) && world.getBlock(x, y2 + 4, z).equals(Blocks.stone));
        }
    }
    

    Permet de définir quand le portail sera bien construit (pour pas avoir tous les blocs qui se suppriment), changez le "Blocks.stone" par le bloc de la structure de votre portail. Ensuite, la fonction permet qu'en cassant un bloc tous les blocs autour se détruisent.
    Ajoutez ensuite :

    @Override
    public boolean isOpaqueCube()
    {
        return false;
    }
    
    @Override
    public boolean renderAsNormalBlock()
    {
        return false;
    }
    
    @Override
    public int quantityDropped(Random random)
    {
        return 0;
    }
    
    1. Si le bloc est opaque
    2. S'il a un rendu normal
    3. La drop lâché quand on le casse

    Après nous allons ajouter une des fonctions les plus importantes :

    @Override
    public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity)
    {
    
    }
    

    Maintenant nous allons compléter la fonction, donc ajoutez cette première condition :

    if((entity.ridingEntity == null) && (entity.riddenByEntity == null))
    {
    
    }
    

    La condition sera vérifiée si :

    1. L'entité n'est pas sur une autre.
    2. Une autre entité n'est pas sur elle.

    Ensuite, nous allons ajouter deux autres conditions :

    if(entity.dimension != TutoDimension.tutoDimID)
    {
    
    }
    else
    {
    
    }
    

    La condition est vérifiée si le joueur est dans une autre dimension que la nôtre. Sinon nous appelons le "else".
    La condition doit être complétée avec :

    if(entity instanceof EntityPlayerMP)
    {
        EntityPlayerMP player = (EntityPlayerMP)entity;
        if(player.timeUntilPortal > 0)
        {
            player.timeUntilPortal = 10;
        }
        else
        {
            player.timeUntilPortal = 10;
            player.mcServer.getConfigurationManager().transferPlayerToDimension(player, TutoDimension.tutoDimID, new TutoTeleporter(player.mcServer.worldServerForDimension(TutoDimension.tutoDimID)));
        }
    }
    
    1. On récupère l'instance de la classe EntityPlayerMP
    2. Si le temps dans le portail est supérieur à 0, on le met à 10
    3. Ensuite, on met le timeUnitilPortal à 10
    4. On met le transfert de dimension (avec l'ID de notre dimension)
    5. On ajoute notre TutoTeleporter à notre sauce et on met notre ID de dimension

    Nous complétons le else :

    if(entity instanceof EntityPlayerMP)
    {
        EntityPlayerMP player = (EntityPlayerMP)entity;
        if(player.timeUntilPortal > 0)
        {
            player.timeUntilPortal = 10;
        }
        else
        {
            player.timeUntilPortal = 10;
            player.mcServer.getConfigurationManager().transferPlayerToDimension(player, 0, new TutoTeleporter(player.mcServer.worldServerForDimension(0)));
        }
    }
    
    • Nous avons la même chose sauf que si le joueur est dans notre dimension alors nous l'envoyons dans l'overworld (si vous voulez envoyer le joueur dans une autre dimension, changez le WorldProvider et changez le 0).

    Nous allons ajouter la fonction qui permet d'avoir de la transparence :

    @SideOnly(Side.CLIENT)
    @Override
    public int getRenderBlockPass()
    {
        return 1;
    }
    

    Si vous le mettez à 1 il aura de la transparence, sinon à 0 il sera opaque.
    Ensuite :

    @SideOnly(Side.CLIENT)
    @Override
    public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z)
    {
        return null;
    }
    

    Ce qui permet que le joueur, en le cassant, ne puisse pas l'avoir dans son inventaire.
    Nous allons ajouter la dernière fonction :

    @Override
    public void breakBlock(World world, int x, int y, int z, Block block, int metadata)
    {
        super.breakBlock(world, x, y, z, block, metadata);
        if(world.getBlock(x, y + 1, z).equals(this))
        {
            world.setBlockToAir(x, y + 1, z);
        }
        if(world.getBlock(x, y - 1, z).equals(this))
        {
            world.setBlockToAir(x, y - 1, z);
        }
        if(world.getBlock(x + 1, y, z).equals(this))
        {
            world.setBlockToAir(x + 1, y, z);
        }
        if(world.getBlock(x - 1, y, z).equals(this))
        {
            world.setBlockToAir(x - 1, y, z);
        }
        if(world.getBlock(x, y, z + 1).equals(this))
        {
            world.setBlockToAir(x, y, z + 1);
        }
        if(world.getBlock(x, y, z - 1).equals(this))
        {
            world.setBlockToAir(x, y, z - 1);
        }
    }
    

    Qui permet de set des blocs d'air une fois cassé. Cette classe est finie.

    L'activateur :

    L'activateur est une item plutôt important, car en effet il va vous permettre de activer votre portail (structure), donc sans ce dernier votre mod sera un peu moyen.
    Pour la classe vous aurez besoin de ajouter l’extension "Item".
    Ensuite vous devez ajouter le constructeur et la vous pouvez faire l'activateur que vous voulez, mais vous devrez ajouter ceci :

    public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float par8, float par9, float par10)
    {
    
    }
    

    Qui permet de savoir quand le joueur fait un clique droit avec notre item.
    Complétez avec cette condition :

    if(world.getBlock(x, y, z).equals(Blocks.stone))
    {
    
    }
    
    return false;
    

    Ce qui permet de demander si le joueur fait un clic droit sur un bloc de stone (bien entendu vous pouvez changer par votre bloc), il faut savoir que nous pouvons tous faire en moins de ligne, mais elles sont très longues donc je le fais avec beaucoup de conditions, ce qui permet de mieux comprendre.
    Ajoutez ensuite :

    if(world.getBlock(x + 1, y, z).equals(Blocks.stone))
    {
    
    }
    
    if(world.getBlock(x - 1, y, z).equals(Blocks.stone))
    {
    
    }
    
    if(world.getBlock(x, y, z + 1).equals(Blocks.stone))
    {
    
    }
    
    if(world.getBlock(x, y, z - 1).equals(Blocks.stone))
    {
    
    }
    

    Ce sont de simples conditions qui permettent de faire apparaître notre portail dans toutes les directions.
    Nous allons compléter la première condition avec ceci :

    if(world.getBlock(x, y + 4, z).equals(Blocks.stone))
    {
        if(world.getBlock(x + 1, y + 4, z).equals(Blocks.stone))
        {
            if(world.getBlock(x - 1, y + 1, z).equals(Blocks.stone))
            {
                if(world.getBlock(x - 1, y + 2, z).equals(Blocks.stone))
                {
                    if(world.getBlock(x - 1, y + 3, z).equals(Blocks.stone))
                    {
                        if(world.getBlock(x + 2, y + 1, z).equals(Blocks.stone))
                        {
                            if(world.getBlock(x + 2, y + 2, z).equals(Blocks.stone))
                            {
                                if(world.getBlock(x + 2, y + 3, z).equals(Blocks.stone))
                                {
    
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    

    Nous avons la structure et nous allons finir avec :

    for(int l = 0; l < 2; l++)
    {
        for(int h = 0; h < 3; h++)
        {
            world.setBlock(x + l, y + 1 + h, z, TutoDimension.tutoPortail);
        }
    }
    

    Les deux "for" permettent qu'on obtienne la structure et à la fin on met les blocs avec les int des boucles en plus (sur le vecteur** y** il faut toujours mettre + 1), les boucles seront à chaque fois les mêmes, il y a juste le setBlock qui change.
    Dans la deuxième condition ajoutez cela (je vous donne tout, vous devriez avoir compris avec le premier)

    if(world.getBlock(x, y + 4, z).equals(Blocks.stone))
    {
        if(world.getBlock(x - 1, y + 4, z).equals(Blocks.stone))
        {
            if(world.getBlock(x - 2, y + 1, z).equals(Blocks.stone))
            {
                if(world.getBlock(x - 2, y + 2, z).equals(Blocks.stone))
                {
                    if(world.getBlock(x - 2, y + 3, z).equals(Blocks.stone))
                    {
                        if(world.getBlock(x + 1, y + 1, z).equals(Blocks.stone))
                        {
                            if(world.getBlock(x + 1, y + 2, z).equals(Blocks.stone))
                            {
                                if(world.getBlock(x + 1, y + 3, z).equals(Blocks.stone))
                                {
                                    for(int l = 0; l < 2; l++)
                                    {
                                        for(int h = 0; h < 3; h++)
                                        {
                                            world.setBlock(x - l, y + 1 + h, z, TutoDimension.tutoPortail);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    

    Dans la troisième ajoutez :

    if(world.getBlock(x, y + 4, z).equals(Blocks.stone))
    {
        if(world.getBlock(x, y + 4, z + 1).equals(Blocks.stone))
        {
            if(world.getBlock(x, y + 1, z - 1).equals(Blocks.stone))
            {
                if(world.getBlock(x, y + 2, z - 1).equals(Blocks.stone))
                {
                    if(world.getBlock(x, y + 3, z - 1).equals(Blocks.stone))
                    {
                        if(world.getBlock(x, y + 1, z + 2).equals(Blocks.stone))
                        {
                            if(world.getBlock(x, y + 2, z + 2).equals(Blocks.stone))
                            {
                                if(world.getBlock(x, y + 3, z + 2).equals(Blocks.stone))
                                {
                                    for(int l = 0; l < 2; l++)
                                    {
                                        for(int h = 0; h < 3; h++)
                                        {
                                            world.setBlock(x, y + 1 + h, z + l, TutoDimension.tutoPortail);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    

    Dans la dernière ajoutez :

    if(world.getBlock(x, y + 4, z).equals(Blocks.stone))
    {
        if(world.getBlock(x, y + 4, z - 1).equals(Blocks.stone))
        {
            if(world.getBlock(x, y + 1, z + 1).equals(Blocks.stone))
            {
                if(world.getBlock(x, y + 2, z + 1).equals(Blocks.stone))
                {
                    if(world.getBlock(x, y + 3, z + 1).equals(Blocks.stone))
                    {
                        if(world.getBlock(x, y + 1, z - 2).equals(Blocks.stone))
                        {
                            if(world.getBlock(x, y + 2, z - 2).equals(Blocks.stone))
                            {
                                if(world.getBlock(x, y + 3, z - 2).equals(Blocks.stone))
                                {
                                    for(int l = 0; l < 2; l++)
                                    {
                                        for(int h = 0; h < 3; h++)
                                        {
                                            world.setBlock(x, y + 1 + h, z - l, TutoDimension.tutoPortail);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    

    Donc voilà nous en avons fini avec cette classe.

    La classe principale

    Au dessus du preInit ajoutez :

    public static Block tutoPortail;
    public static Item tutoActivateur;
    

    Puis dans le preInit ajoutez :

    tutoPortail = new TutoPortail(Material.portal).setBlockName("portail").setBlockTextureName(MODID + ":portail");
    tutoActivateur = new TutoActivateur().setUnlocalizedName("activateur").setTextureName(MODID + ":activateur");
    
    GameRegistry.registerBlock(tutoPortail, "tuto_portail");
    GameRegistry.registerItem(tutoActivateur, "tuto_activateur");
    

    Jusque là je ne suis pas obligé de vous expliquer grand chose..
    Puis dans le postInit ajoutez ceci :

    DimensionManager.registerProviderType(TutoDimension.tutoDimID, TutoWorldProvider.class, false);
    DimensionManager.registerDimension(TutoDimension.tutoDimID, TutoDimension.tutoDimID);
    

    Dans le premier nous enregistrons l'ID et le WorldProvider, puis dans la seconde nous ajoutons les ID. Le false demande si nous gardons la dimension chargée. Voilà il vous reste plus qu'à lire le bonus.

    Bonus

    Dans ce bonus nous allons mettre en pratique les choses vues.

    • Modifier une dimension (Dans notre cas l'end)
    • Créer une dimension île volante
    • Faire que le bloc portail soit animé et que la forme de sa structure soit modifiée.

    Modifier une dimension :

    Pour modifier une dimension, allez dans votre classe principale, dans la fonction postInit faites comme cela :

    ​        try
    
            {
                Field f = DimensionManager.class.getDeclaredField("providers");
                f.setAccessible(true);
    
                Hashtable providers = (Hashtable)f.get(null);
    //dimension id et le world provider
                providers.put(Integer.valueOf(1), TutoEndWorldProvider.class);
                f.set(null, providers);
            }
            catch(NoSuchFieldException | IllegalArgumentException | IllegalAccessException e)
            {
                throw new RuntimeException("Could not change provider dimension!", e);
            }
    

    Il est possible qu'une exception se produise quandnous mettons dans un bloc "try", *notez que il peut vous demander de passer en JRE7 ! Si jamais vous ne voulez pas, alors il faut décomposer le catch. Et voilà vous avez changé "l'end", changez bien par votre classe et "l'end" est modifié.
    Si vous voulez changer la texture du ciel de "l'end" (je vous recommande de gardez "l'end" en une dimension sombre), il vous suffit d'aller dans votre dossier assets, créer un dossier qui aura cette arborescence : "***minecraft/textures/environment/end_sky.png"
    , ouvrez le .png et supprimez toutes les textures pour avoir une transparence du ciel et changer le ciel. La méthode donnée est valable pour toutes les dimensions, c'est-à-dire celle du Minecraft original, et même les dimension custom d'autres mods.

    Créer une dimension île volante :

    Créer un skyland c'est trop dur il faut au moins 20 mille lignes de code et tout et différent d'une dimension basique Créer un skyland et très simple, si vous partez perdant jamais vous ne gagnerez, là c'est la même chose. Un skyland et quasiment comme une dimension de base.
    Souvent dans les bonus vous avez constaté que nous changions ou ajoutions des petites choses, mais dans notre bonus nous allons faire toutes les classes qu'il nous faut.

    La classe principale :

    Dans la classe principale, vous pouvez enregistrer votre world provider comme nous le montrons juste au-dessus (si vous voulez remplacer une dimension). Vous pouvez aussi enregistrer normalement comme ça :

            DimensionManager.registerProviderType(TutoDimension.tutoDimIslandID, SkyWorldProvider.class, false);
            DimensionManager.registerDimension(TutoDimension.tutoDimIslandID, TutoDimension.tutoDimIslandID);
    

    Normalement vous connaissez l'enregistrement comme cela. En premier nous mettons l'ID de la dimension et en second le worldProvider, le boolean dit si nous gardons la dimension chargée.
    Dans le "registerDimension" il vous suffit de mettre l'ID. %(#ff3333)[NOTE : comme toujours je vous recommande de mettre des ID dans des int par rapport à une variable déclarée, pour que vous puissiez les mettre dans des fichiers de configuration.

    Le ChunkProvider :

    Je vais tenter de le faire varier du premier. Le chunk provider, la classe qui va nous permettre de créer notre skyland. Comme dans tous vos ChunkProviders, ajoutez l’interface IChunkProvider%(#333333)[. Ajoutez tous ces fields 🙂

    ​    private Random rand;
    
        private NoiseGeneratorOctaves noiseGen1;
        private NoiseGeneratorOctaves noiseGen2;
        private NoiseGeneratorOctaves noiseGen3;
        private NoiseGeneratorOctaves noiseGen4;
        public NoiseGeneratorOctaves noiseGen5;
        public NoiseGeneratorOctaves noiseGen6;
        private NoiseGeneratorOctaves noiseGen7;
        public NoiseGeneratorOctaves mobSpawnerNoise;
        private World worldObj;
        private double[] noiseArray;
    
        private double[] bNoise1;
        private double[] bNoise2;
        private double[] bNoise3;
        private BiomeGenBase[] biomesForGeneration;
        double[] noise1;
        double[] noise2;
        double[] noise3;
        double[] noise4;
        double[] noise5;
        int[][] field_914_i = new int[32][32];
        private double[] generatedTemperatures;
    
        public Block topBlock;
        public Block fillerBlock;
    

    Certaines choses doivent vous sauter aux yeux, en effet, nous avons trois noises pour les biomes et non une. Ensuite nous avons sept noises pour la génération. Je pense que je n'ai pas besoin de vous le dire, mais vous pouvez ajouter vos propres structures (si vous le faites regardez bien le tuto plus haut, mais nous aborderons une autre méthode que je ne vous ai pas montré)%(#333333)[. Le code sera décrit par le biais des commentaires. Ajoutez le constructeur, comme cela 🙂

    ​    public SkyChunkProvider(World world, long seed)
    
        {
            //nous initialisons des fields
            this.bNoise1 = new double[256];
            this.bNoise2 = new double[256];
            this.bNoise3 = new double[256];
            this.worldObj = world;
            this.rand = new Random(seed);
            this.noiseGen1 = new NoiseGeneratorOctaves(this.rand, 16);
            this.noiseGen2 = new NoiseGeneratorOctaves(this.rand, 16);
            this.noiseGen3 = new NoiseGeneratorOctaves(this.rand, 32);
            this.noiseGen4 = new NoiseGeneratorOctaves(this.rand, 64);
            this.noiseGen5 = new NoiseGeneratorOctaves(this.rand, 4);
            this.noiseGen6 = new NoiseGeneratorOctaves(this.rand, 10);
            this.noiseGen7 = new NoiseGeneratorOctaves(this.rand, 16);
            this.mobSpawnerNoise = new NoiseGeneratorOctaves(this.rand, 8);
        }
    

    Après cela nous allons ajouter une fonction importante, qui nous permet d'avoir un bon skyland.

    ​    public void generateTerrain(int i, int j, Block[] block, BiomeGenBase[] abiomes)
    
        {
            byte byte0 = 2;
            int k = byte0 + 1;
            byte byte1 = 33;
            int l = byte0 + 1;
            this.noiseArray = initializeNoiseField(this.noiseArray, i * byte0, 0, j * byte0, k, byte1, l);
    
            for(int i1 = 0; i1 < byte0; i1++)
            {
                for(int j1 = 0; j1 < byte0; j1++)
                {
                    for(int k1 = 0; k1 < 32; k1++)
                    {
                        double d = 0.25D;
                        double d1 = this.noiseArray[(((i1 + 0) * l + j1 + 0) * byte1 + k1 + 0)];
                        double d2 = this.noiseArray[(((i1 + 0) * l + j1 + 1) * byte1 + k1 + 0)];
                        double d3 = this.noiseArray[(((i1 + 1) * l + j1 + 0) * byte1 + k1 + 0)];
                        double d4 = this.noiseArray[(((i1 + 1) * l + j1 + 1) * byte1 + k1 + 0)];
                        double d5 = (this.noiseArray[(((i1 + 0) * l + j1 + 0) * byte1 + k1 + 1)] - d1) * d;
                        double d6 = (this.noiseArray[(((i1 + 0) * l + j1 + 1) * byte1 + k1 + 1)] - d2) * d;
                        double d7 = (this.noiseArray[(((i1 + 1) * l + j1 + 0) * byte1 + k1 + 1)] - d3) * d;
                        double d8 = (this.noiseArray[(((i1 + 1) * l + j1 + 1) * byte1 + k1 + 1)] - d4) * d;
                        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++)
                            {
                                int j2 = i2 + i1 * 8 << 11 | 0 + j1 * 8 << 7 | k1 * 4 + l1;
                                char c = '€';
                                double d14 = 0.125D;
                                double d15 = d10;
                                double d16 = (d11 - d10) * d14;
                                for(int k2 = 0; k2 < 8; k2++)
                                {
                                    Block l2 = Blocks.air;
                                    if(d15 > 0.0D)
                                    {
                                        l2 = Blocks.stone;
                                    }
                                    block[j2] = l2;
                                    j2 += c;
                                    d15 += d16;
                                }
    
                                d10 += d12;
                                d11 += d13;
                            }
    
                            d1 += d5;
                            d2 += d6;
                            d3 += d7;
                            d4 += d8;
                        }
                    }
                }
            }
        }
    

    Je ne peux pas vraiment vous expliquer car il est a vous de comprendre tous les calculs… Ce n'est pas vraiment explicable ligne par ligne, la fonction permet de générer des blocs. Vous devez avoir une erreur au début de la fonction, car nous avons pas encore créer notre fonction, ce que nous allons faire de suite.

    ​    private double[] initializeNoiseField(double[] ad, int i, int j, int k, int l, int i1, int j1)
    
        {
            if(ad == null)
            {
                ad = new double[l * i1 * j1];
            }
            double d = 684.41200000000003D;
            double d1 = 684.41200000000003D;
    
            this.noise4 = this.noiseGen6.generateNoiseOctaves(this.noise4, i, k, l, j1, 1.121D, 1.121D, 0.5D);
            this.noise5 = this.noiseGen7.generateNoiseOctaves(this.noise5, i, k, l, j1, 200.0D, 200.0D, 0.5D);
            d *= 2.0D;
            this.noise3 = this.noiseGen3.generateNoiseOctaves(this.noise3, i, j, k, l, i1, j1, d / 80.0D, d1 / 160.0D, d / 80.0D);
            this.noise1 = this.noiseGen1.generateNoiseOctaves(this.noise1, i, j, k, l, i1, j1, d, d1, d);
            this.noise2 = this.noiseGen2.generateNoiseOctaves(this.noise2, i, j, k, l, i1, j1, d, d1, d);
            int k1 = 0;
            int l1 = 0;
            for(int j2 = 0; j2 < l; j2++)
            {
                for(int l2 = 0; l2 < j1; l2++)
                {
                    double d4 = 1.0D;
                    d4 *= d4;
                    d4 *= d4;
                    d4 = 1.0D - d4;
                    double d5 = (this.noise4[l1] + 256.0D) / 512.0D;
                    d5 *= d4;
                    if(d5 > 1.0D)
                    {
                        d5 = 1.0D;
                    }
                    double d6 = this.noise5[l1] / 8000.0D;
                    if(d6 < 0.0D)
                    {
                        d6 = -d6 * 0.3D;
                    }
                    d6 = d6 * 3.0D - 2.0D;
                    if(d6 > 1.0D)
                    {
                        d6 = 1.0D;
                    }
                    d6 /= 8.0D;
                    d6 = 0.0D;
                    if(d5 < 0.0D)
                    {
                        d5 = 0.0D;
                    }
                    d5 += 0.5D;
                    d6 = d6 * i1 / 16.0D;
                    l1++;
                    double d7 = i1 / 2.0D;
                    for(int j3 = 0; j3 < i1; j3++)
                    {
                        double d8 = 0.0D;
                        double d9 = (j3 - d7) * 8.0D / d5;
                        if(d9 < 0.0D)
                        {
                            d9 *= -1.0D;
                        }
                        double d10 = this.noise1[k1] / 512.0D;
                        double d11 = this.noise2[k1] / 512.0D;
                        double d12 = (this.noise3[k1] / 10.0D + 1.0D) / 2.0D;
                        if(d12 < 0.0D)
                        {
                            d8 = d10;
                        }
                        else if(d12 > 1.0D)
                        {
                            d8 = d11;
                        }
                        else
                        {
                            d8 = d10 + (d11 - d10) * d12;
                        }
                        d8 -= 8.0D;
                        int k3 = 32;
                        if(j3 > i1 - k3)
                        {
                            double d13 = (j3 - (i1 - k3)) / (k3 - 1.0F);
                            d8 = d8 * (1.0D - d13) + -30.0D * d13;
                        }
                        k3 = 8;
                        if(j3 < k3)
                        {
                            double d14 = (k3 - j3) / (k3 - 1.0F);
                            d8 = d8 * (1.0D - d14) + -30.0D * d14;
                        }
                        ad[k1] = d8;
                        k1++;
                    }
    
                }
    
            }
    
            return ad;
        }
    

    Voilà, elle vient compléter l'autre fonction dans la génération, mais nous devons aussi ajouter :

    ​    public void replaceBlocksForBiome(int i, int j, Block[] block, BiomeGenBase[] abiome)
        {
            double d = 0.03125D;
            this.bNoise1 = this.noiseGen4.generateNoiseOctaves(this.bNoise1, i * 16, j * 16, 0, 16, 16, 1, d, d, 1.0D);
            this.bNoise2 = this.noiseGen4.generateNoiseOctaves(this.bNoise2, i * 16, 109, j * 16, 16, 1, 16, d, 1.0D, d);
            this.bNoise3 = this.noiseGen5.generateNoiseOctaves(this.bNoise3, i * 16, j * 16, 0, 16, 16, 1, d * 2.0D, d * 2.0D, d * 2.0D);
            for(int k = 0; k < 16; k++)
            {
                for(int l = 0; l < 16; l++)
                {
                    int i1 = (int)(this.bNoise3[(k + l * 16)] / 3.0D + 3.0D + this.rand.nextDouble() * 0.25D);
    
                    int j1 = -1;
                    this.topBlock = Blocks.grass;
                    this.fillerBlock = Blocks.dirt;
                    Block block1 = this.topBlock;
                    Block block2 = this.fillerBlock;
                    Block stone = Blocks.stone;
    
                    if(block1 == Blocks.air)
                    {
                        block1 = Blocks.grass;
                    }
                    if(block2 == Blocks.air)
                    {
                        block2 = Blocks.dirt;
                    }
                    if(stone == Blocks.air)
                    {
                        stone = Blocks.stone;
                    }
                    for(int k1 = 127; k1 >= 0; k1–)
                    {
                        int l1 = (l * 16 + k) * 128 + k1;
                        Block block3 = block[l1];
                        if(block3 == Blocks.air)
                        {
                            j1 = -1;
                        }
                        else if(block3 == stone)
                        {
    
                            if(j1 == -1)
                            {
    
                                if(i1 <= 0)
                                {
                                    block1 = Blocks.air;
                                    block2 = stone;
                                }
                                j1 = i1;
                                if(k1 >= 0)
                                {
                                    block[l1] = block1;
                                }
                                else
                                {
                                    block[l1] = block2;
                                }
    
                            }
                            else if(j1 > 0)
                            {
                                j1–;
                                block[l1] = block2;
                            }
                        }
                    }
                }
            }
        }
    

    Comme vous le remarquez nous mettons trois noises.
    Ajoutez cette fonction :

    ​    public Chunk provideChunk(int par1, int par2)
        {
            this.rand.setSeed(par1 * 391279128714L + par2 * 132894987741L);
            Block[] ablock = new Block[32768];
            this.biomesForGeneration = this.worldObj.getWorldChunkManager().loadBlockGeneratorData(this.biomesForGeneration, par1 * 16, par2 * 16, 16, 16);
            generateTerrain(par1, par2, ablock, this.biomesForGeneration);
            replaceBlocksForBiome(par1, par2, ablock, this.biomesForGeneration);
            Chunk chunk = new Chunk(this.worldObj, ablock, par1, par2);
            byte[] abyte = chunk.getBiomeArray();
    
            for(int k = 0; k < abyte.length; k++)
            {
                abyte[k] = ((byte)this.biomesForGeneration[k].biomeID);
            }
    
            chunk.generateSkylightMap();
            return chunk;
        }
    

    Vous remarquez que nous appelons les autres fonctions.
    Ajoutez cette fonction qui permet d'avoir la décoration, ou de générer des choses.

        public void populate(IChunkProvider ichunkprovider, int i, int j)
        {
            BlockSand.fallInstantly = true;
    
            int var4 = i * 16;
            int var5 = j * 16;
            BiomeGenBase var6 = this.worldObj.getWorldChunkManager().getBiomeGenAt(var4 + 16, var5 + 16);
            this.rand.setSeed(this.worldObj.getSeed());
    
            if(this.rand.nextInt(4) == 0)
            {
                int var13 = var4 + this.rand.nextInt(16) + 8;
                int var14 = this.rand.nextInt(256);
                int var15 = var5 + this.rand.nextInt(16) + 8;
                new WorldGenLakes(Blocks.water).generate(this.worldObj, this.rand, var13, var14, var15);
            }
    
            Random rand = new Random();
            int randomNum = rand.nextInt(6) + 1;
            if(randomNum == 2)
            {
                WorldGenTrees var17 = new WorldGenTrees(true);
    
                for(int var18 = 0; var18 < 5; var18++)
                {
                    int var19 = var4 + this.rand.nextInt(16);
                    int var20 = var5 + this.rand.nextInt(16);
                    int var21 = this.worldObj.getHeightValue(var19, var20);
                    var17.generate(this.worldObj, this.rand, var19, var21, var20);
                }
    
                SpawnerAnimals.performWorldGenSpawning(this.worldObj, var6, var4 + 8, var5 + 8, 16, 16, this.rand);
    
                for(int var21 = var4 + 8; var21 < var4 + 8 + 16; var21++)
                {
                    for(int var20 = var5 + 8; var20 < var5 + 8 + 16; var20++)
                    {
                        int var10000 = var21 - (var4 + 8);
                        var10000 = var20 - (var5 + 8);
                    }
                }
            }
            else if(randomNum == 3)
            {
                WorldGenTrees var17 = new WorldGenTrees(false);
    
                for(int var18 = 0; var18 < 5; var18++)
                {
                    int var19 = var4 + this.rand.nextInt(16);
                    int var20 = var5 + this.rand.nextInt(16);
                    int var21 = this.worldObj.getHeightValue(var19, var20);
                    var17.generate(this.worldObj, this.rand, var19, var21, var20);
                }
    
                SpawnerAnimals.performWorldGenSpawning(this.worldObj, var6, var4 + 8, var5 + 8, 16, 16, this.rand);
    
                for(int var21 = var4 + 8; var21 < var4 + 8 + 16; var21++)
                {
                    for(int var20 = var5 + 8; var20 < var5 + 8 + 16; var20++)
                    {
                        int var10000 = var21 - (var4 + 8);
                        var10000 = var20 - (var5 + 8);
                    }
    
                }
    
            }
            else if(randomNum == 4)
            {
                WorldGenBigTree var17 = new WorldGenBigTree(true);
    
                for(int var18 = 0; var18 < 5; var18++)
                {
                    int var19 = var4 + this.rand.nextInt(16);
                    int var20 = var5 + this.rand.nextInt(16);
                    int var21 = this.worldObj.getHeightValue(var19, var20);
                    var17.generate(this.worldObj, this.rand, var19, var21, var20);
                }
    
                SpawnerAnimals.performWorldGenSpawning(this.worldObj, var6, var4 + 8, var5 + 8, 16, 16, this.rand);
    
                for(int var21 = var4 + 8; var21 < var4 + 8 + 16; var21++)
                {
                    for(int var20 = var5 + 8; var20 < var5 + 8 + 16; var20++)
                    {
                        int var10000 = var21 - (var4 + 8);
                        var10000 = var20 - (var5 + 8);
                    }
    
                }
    
            }
    
            BlockSand.fallInstantly = false;
        }
    

    Vous voyez nous générons des lacs, des arbres, tout l'environnement.
    Je vais vous donner tout le reste des fonctions (elles sont expliquées plus haut).

    ​    public List getPossibleCreatures(EnumCreatureType enumcreaturetype, int i, int j, int k)
        {
            BiomeGenBase var5 = this.worldObj.getBiomeGenForCoords(i, k);
            return var5 == null ? null : var5.getSpawnableList(enumcreaturetype);
        }
    
        public boolean saveChunks(boolean flag, IProgressUpdate iprogressupdate)
        {
            return true;
        }
    
        public boolean unloadQueuedChunks()
        {
            return false;
        }
    
        public boolean canSave()
        {
            return true;
        }
    
        public String makeString()
        {
            return "RandomLevelSource";
        }
    
        public ChunkPosition func_147416_a(World world, String s, int i, int j, int k)
        {
            return null;
        }
    
        public int getLoadedChunkCount()
        {
            return 0;
        }
    
        public boolean chunkExists(int i, int j)
        {
            return true;
        }
    
        public Chunk loadChunk(int i, int j)
        {
            return provideChunk(i, j);
        }
    
        public void recreateStructures(int i, int j) {}
    
        public void saveExtraData() {}
    

    Le WorldProvider :

    Vous souvenez vous cette classe qui permet d'ajouter quelques propriétés, je vous donne ici celles que j'ai mises pour un skyland.

    ​    public String getDimensionName()
        {
            return "The Sky";
        }
    
        public IChunkProvider createChunkGenerator()
        {
            return new SkyChunkProvider(this.worldObj, this.worldObj.getSeed());
        }
    
        public float getCloudHeight()
        {
            return 128.0F;
        }
    
        public boolean canRespawnHere()
        {
            return false;
        }
    
        public float calculateCelestialAngle(long var1, float var3)
        {
            return 0.0F;
        }
    
        public String getSaveFolder()
        {
            return "sky";
        }
    
        public boolean isSurfaceWorld()
        {
            return false;
        }
    

    Ensuite, ajoutez :

    ​    public void registerWorldChunkManager()
    
        { // un autre chunk manager car nous en avons pas besoin. ensuite vous devez mettre le biome qui se génère.
            this.worldChunkMgr = new WorldChunkManagerHell(TutoDimension.tutoGaieBiome, 1.0F);
            //l'ID de la dimension.
            this.dimensionId = TutoDimension.tutoDimIslandID;
        }
    

    Le Biome :

    Vous devez mettre ces deux fonctions dans la classe de votre biome principal :

    ​    public void func_150573_a(World world, Random rand, Block[] block, byte[] abyte, int x, int z, double par7)
        {
          this.topBlock = Blocks.grass;
          this.field_150604_aj = 0;
          this.fillerBlock = Blocks.dirt;
    
          this.generateBiomeTerrain(world, rand, block, abyte, x, z, par7);
        }
    
        public final void generateBiomeTerrain(World world, Random rand, Block[] ablock, byte[] abyte, int x, int z, double par7)
        {
          boolean flag = true;
          Block block = this.topBlock;
          byte b0 = (byte)(this.field_150604_aj & 255);
          Block block1 = this.fillerBlock;
          int k = -1;
          int l = (int)(par7 / 3.0D + 3.0D + rand.nextDouble() * 0.25D);
          int i1 = x & 0xF;
          int j1 = z & 0xF;
          int k1 = ablock.length / 256;
    
          for (int l1 = 255; l1 >= 0; l1–)
          {
            int i2 = (j1 * 16 + i1) * k1 + l1;
    
            if (l1 <= 94)
            {
              ablock[i2] = Blocks.air;
            }
            else
            {
              Block block2 = ablock[i2];
    
              if ((block2 != null) && (block2.getMaterial() != Material.air))
              {
                if (block2 == Blocks.stone)
                {
                  if (k == -1)
                  {
                    if (l <= 0)
                    {
                      block = null;
                      b0 = 0;
                      block1 = Blocks.stone;
                    }
                    else if ((l1 >= 59) && (l1 <= 64))
                    {
                      block = this.topBlock;
                      b0 = (byte)(this.field_150604_aj & 0xFF);
                      block1 = this.fillerBlock;
                    }
    
                    if ((l1 < 63) && ((block == null) || (block.getMaterial() == Material.air)))
                    {
                      if (getFloatTemperature(x, l1, z) < 0.15F)
                      {
                        block = Blocks.ice;
                        b0 = 0;
                      }
                      else
                      {
                        block = Blocks.water;
                        b0 = 0;
                      }
                    }
    
                    k = l;
    
                    if (l1 >= 62)
                    {
                      ablock[i2] = block;
                      abyte[i2] = b0;
                    }
                    else if (l1 < 56 - l)
                    {
                      block = null;
                      block1 = Blocks.stone;
                      ablock[i2] = Blocks.gravel;
                    }
                    else
                    {
                      ablock[i2] = block1;
                    }
                  }
                  else if (k > 0)
                  {
                    k–;
                    ablock[i2] = block1;
    
                    if ((k == 0) && (block1 == Blocks.sand))
                    {
                      k = rand.nextInt(4) + Math.max(0, l1 - 63);
                      block1 = Blocks.air;
                    }
                  }
                }
              }
              else
              {
                k = -1;
              }
            }
          }
        }
    

    Je vous conseille également de ne pas mettre une hauteur trop basse.

    La classe de Génération :

    Donc si vous voulez générer, comme moi, les minerais de base, ajoutez dans la fonction generate de votre classe de génération :

    ​        if(world.provider.dimensionId == TutoDimension.tutoDimIslandID)
    
            {
                this.generateSky(world, chunkX * 16, chunkZ * 16, random);
            }
    

    N'oubliez pas la fonction :

    ​    public void generateSky(World world, int x, int z, Random rand)
        { }
    

    Personnaliser le portail :

    Le Bloc :

    Donc nous allons un peu changer notre bloc, nous allons faire :

    • Apparaître des particules (comme le portail du nether)
    • Animer la texture du bloc
    • Lui faire jouer un son
    • Changer la forme (hit box) du bloc

    Si vous voulez faire apparaître votre propre particule, il faudra ajouter la fonction suivante.

    ​    @Override
        @SideOnly(Side.CLIENT)
        public void randomDisplayTick(World world, int coordX, int coordY, int coordZ, Random rand)
        {
            for(int l = 0; l < 4; l++)
            {
                double x = coordX + rand.nextFloat();
                double y = coordY + rand.nextFloat();
                double z = coordZ + rand.nextFloat();
                double mX = 0.0D;
                double mY = 0.0D;
                double mZ = 0.0D;
                int i1 = rand.nextInt(2) * 2 - 1;
                mX = (rand.nextFloat() - 0.5D) * 0.5D;
                mY = (rand.nextFloat() - 0.5D) * 0.5D;
                mZ = (rand.nextFloat() - 0.5D) * 0.5D;
    
                if((world.getBlock(coordX - 1, coordY, coordZ) != this) && (world.getBlock(coordX + 1, coordY, coordZ) != this))
                {
                    x = coordX + 0.5D + 0.25D * i1;
                    mX = rand.nextFloat() * 2.0F * i1;
                }
                else
                {
                    z = coordZ + 0.5D + 0.25D * i1;
                    mZ = rand.nextFloat() * 2.0F * i1;
                }
    
                TutoDimension.proxy.spawnParticle(world, "portal", x, y, z, mX, mY, mZ);
            }
        }
    

    Si au contraire vous désirez utiliser une particule de base, il vous faut ajouter à la place de la dernière ligne :

    ​            world.spawnParticle("portal", x, y, z, mX, mY, mZ);
    

    Bien entendu, vous pouvez changer le "portal" par autre chose, pour avoir une autre particule.
    Voici la liste des particules (à mettre à la place de "portal") :

    • bubble
    • suspended
    • depthsuspend
    • townaura
    • crit
    • magicCrit
    • smoke
    • mobSpell
    • mobSpellAmbient
    • spell
    • instantSpell
    • witchMagic
    • note
    • portal
    • enchantmenttable
    • explode
    • flame
    • lava
    • footstep
    • splash
    • wake
    • largesmoke
    • cloud
    • reddust
    • snowballpoof
    • dripWater
    • dripLava
    • snowshovel
    • slime
    • heart
    • angryVillager
    • happyVillager

    Animer votre texture :

    Donc pour animer votre bloc il vous faut créer une texture de taille (zone de dessin) 16 x 512 (note : si vous utilisez une texture 32 x 32 alors il faut doubler les valeurs. Vous aurez donc : 32 x 1024, et pour 64 : 64 x 2048 ). Ensuite, votre texture doit être mise par la taille choisie par celle-ci. En image :

    Donc, chaque couleur représente un carré de la taille de mon format (16x16 ou 32x32 par exemple). Donc vous avez juste a faire la même chose, en modifiant les carrés pour que ce soit animé. Si jamais vous avez des problèmes, allez voir la texture du portail de base : minecraft/textures/blocks/portal.
    Une fois que votre fichier est créé aller dans le dossier de la texture et créer un fichier qui porte le nom de la texture .png plus ajouter .mcmeta (nom_block.png.mcmeta). Ouvrez votre nouveau fichier avec un éditeur de texte (notepad est bien) et ajoutez ceci :

    {
      "animation": {
        "frames": [
          0,
          1,
          2,
          3,
          4,
          5,
          6,
          7,
          8,
          9,
          10,
          11,
          12,
          13,
          14,
          15,
          16,
          17,
          18,
          19,
          20,
          21,
          22,
          23,
          24,
          25,
          26,
          27,
          28,
          29,
          30,
          31
        ]
      }
    }
    

    Ceci permet de dire au jeu d'animer le bloc. Si vous le faites pas (ou mal) il y aura une texture manquante. C'est simple il vous suffit de mettre le numéro de chaque image de votre .png, 1 correspond au premier carré de l'image au-dessus, 2 à la seconde, etc….

    Faire jouer un son :

    Pour faire jouer un son au bloc, allez dans la fonction "randomDisplayTick" et ajoutez :

    ​        if(rand.nextInt(25) == 0)
            {
                world.playSound(coordX + 0.5D, coordY + 0.5D, coordZ + 0.5D, "portal.portal", 0.5F, rand.nextFloat() * 0.4F + 0.8F, false);
            }
    

    Ce qui fera jouer un son de portail, il existe plein d'autre son, dont les vôtres.

    Changer la forme :

    Pour ce faire nous allons changer les fonctions : "setBlockBoundsBasedOnState" et "setBlockBoundsForItemRender". Dans notre cas, je vais faire en sorte que le bloc soit comme un tapis, mais qui vole.

    Donc une petite explication du : setBlockBounds. Cela permet de mettre la hit box et donc de changer la forme. Ces float représentent les points, les trois premiers représentent les x, y et z minimums et les trois autres les x, y et z maximums. En claire "0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F" fait un bloc normal et "0.0F, 0.0F, 0.0F, 0.5F, 0.5F, 0.5F" fait une dalle. Nous allons faire ce qu'il faut pour que notre bloc soit comme nous le souhaitons. Ajoutez ceci dans vos deux fonctions :

    ​        float f = 1F;
            this.setBlockBounds(0.0F, 0.950F, 0.0F, 1.0F, f, 1.0F);
    

    La structure :

    Dans cette petite partie nous changerons la structure de notre portail en :

    • Modifiant la forme pour que le joueur doive tomber dans le portail
    • Faisant apparaître notre joueur sur une plateforme fixe sans portail

    Donc nous allons changer la forme de notre petit portail pour qu'il soit comme cela :

    Vous allez retrouver la ligne de code dans la fonction de création du portail dans le teleporter :

    this.worldServerInstance.setBlock(l3, i4, j4, (flag ? Blocks.stone : TutoDimension.tutoPortail), 0, 2);
    

    Remplacez la par :

    ​                    this.worldServerInstance.setBlock(k3 + 1, j3 + 1, i4, Blocks.stone, 0, 2);
    
                        this.worldServerInstance.setBlock(k3 + 1, j3, i4 + 1, Blocks.stone, 0, 2);
                        this.worldServerInstance.setBlock(k3 + 0, j3 + 1, i4 + 1, Blocks.stone, 0, 2);
                        this.worldServerInstance.setBlock(k3 + 1, j3 + 1, i4 + 1, TutoDimension.tutoPortail, 0, 2);
                        this.worldServerInstance.setBlock(k3 + 2, j3 + 1, i4 + 1, Blocks.stone, 0, 2);
                        this.worldServerInstance.setBlock(k3 + 1, j3 + 1, i4 + 2, Blocks.stone, 0, 2);
    

    Dans la classe de votre activateur changez le contenu de la fonction "onItemUse", vous allez supprimer le contenu et ajoutez à la place :

    ​
    
            if(world.getBlock(x, y, z).equals(Blocks.stone))
            {
                if(world.getBlock(x + 2, y, z).equals(Blocks.stone))
                {
                    if(world.getBlock(x + 1, y, z + 1).equals(Blocks.stone))
                    {
                        if(world.getBlock(x + 1, y, z - 1).equals(Blocks.stone))
                        {
                            world.setBlock(x + 1, y, z, TutoDimension.tutoPortail);
                        }
                    }
                }
    
                else if(world.getBlock(x -2 , y, z).equals(Blocks.stone))
                {
                    if(world.getBlock(x - 1, y, z + 1).equals(Blocks.stone))
                    {
                        if(world.getBlock(x - 1, y, z - 1).equals(Blocks.stone))
                        {
                            world.setBlock(x - 1, y, z, TutoDimension.tutoPortail);
                        }
                    }
                }
                else if(world.getBlock(x, y, z + 2).equals(Blocks.stone))
                {
                    if(world.getBlock(x + 1, y, z + 1).equals(Blocks.stone))
                    {
                        if(world.getBlock(x - 1, y, z + 1).equals(Blocks.stone))
                        {
                            world.setBlock(x, y, z + 1, TutoDimension.tutoPortail);
                        }
                    }
                }
    
                else if(world.getBlock(x, y, z - 2).equals(Blocks.stone))
                {
                    if(world.getBlock(x + 1, y, z - 1).equals(Blocks.stone))
                    {
                        if(world.getBlock(x - 1, y, z - 1).equals(Blocks.stone))
                        {
                            world.setBlock(x, y, z - 1, TutoDimension.tutoPortail);
                        }
                    }
                }
            }
    
            return false;
    

    Et voilà, en lançant votre jeu votre portail est modifié comme vous le vouliez. Si vous voulez faire apparaître votre portail dans une structure, vous devrez ajouter le code pour générer votre structure (oublier pas de générer la bonne forme du portail dans votre structure sinon cela risque de perdre du sens), en plus de celui du portail.
    Si vous avez envie de faire spawn le joueur sur une plateforme fixe, cela revient au même, mais en suppriment la génération du portail et en ajoutant "-1" après le j3.
    Si vous voulez que le joueur spawn dans votre portail sans même être à la surface (par rapport au coordonné relative en y depuis la dimension de base) il vous faut changer :

    • k3 ==> x
    • j3 ==> y
    • i4 ==> z

    Donc voilà le tour est joué.

    Résultat



    Crédits

    Rédaction :

    Correction :

    Creative Commons
    Ce tutoriel de Minecraft Forge France est mis à disposition selon les termes de la licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International

    retourRetour vers le sommaire des tutoriels



  • Bonjour, jai un crash

    [16:24:52] [main/INFO] [GradleStart]: Extra: []
    [16:24:52] [main/INFO] [GradleStart]: Running with arguments: [–userProperties, {}, --assetsDir, C:/Users/timour/.gradle/caches/minecraft/assets, --assetIndex, 1.7.10, --accessToken, {REDACTED}, --version, 1.7.10, --tweakClass, cpw.mods.fml.common.launcher.FMLTweaker, --tweakClass, net.minecraftforge.gradle.tweakers.CoremodTweaker]
    [16:24:53] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.FMLTweaker
    [16:24:53] [main/INFO] [LaunchWrapper]: Using primary tweak class name cpw.mods.fml.common.launcher.FMLTweaker
    [16:24:53] [main/INFO] [LaunchWrapper]: Loading tweak class name net.minecraftforge.gradle.tweakers.CoremodTweaker
    [16:24:53] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLTweaker
    [16:24:53] [main/INFO] [FML]: Forge Mod Loader version 7.10.85.1291 for Minecraft 1.7.10 loading
    [16:24:53] [main/INFO] [FML]: Java is Java HotSpot(TM) Client VM, version 1.8.0_05, running on Windows 7:x86:6.1, installed at C:\Program Files\Java\jdk1.8.0_05\jre
    [16:24:53] [main/INFO] [FML]: Managed to load a deobfuscated Minecraft name- we are in a deobfuscated environment. Skipping runtime deobfuscation
    [16:24:53] [main/INFO] [LaunchWrapper]: Calling tweak class net.minecraftforge.gradle.tweakers.CoremodTweaker
    [16:24:53] [main/INFO] [GradleStart]: Injecting location in coremod cpw.mods.fml.relauncher.FMLCorePlugin
    [16:24:53] [main/INFO] [GradleStart]: Injecting location in coremod net.minecraftforge.classloading.FMLForgePlugin
    [16:24:53] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker
    [16:24:53] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.FMLDeobfTweaker
    [16:24:53] [main/INFO] [LaunchWrapper]: Loading tweak class name net.minecraftforge.gradle.tweakers.AccessTransformerTweaker
    [16:24:53] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker
    [16:24:53] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker
    [16:24:53] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper
    [16:24:54] [main/ERROR] [FML]: The binary patch set is missing. Either you are in a development environment, or things are not going to work!
    [16:25:02] [main/ERROR] [FML]: FML appears to be missing any signature data. This is not a good thing
    [16:25:02] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper
    [16:25:02] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLDeobfTweaker
    [16:25:03] [main/INFO] [LaunchWrapper]: Calling tweak class net.minecraftforge.gradle.tweakers.AccessTransformerTweaker
    [16:25:03] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.TerminalTweaker
    [16:25:03] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.TerminalTweaker
    [16:25:03] [main/INFO] [LaunchWrapper]: Launching wrapped minecraft {net.minecraft.client.main.Main}
    [16:25:07] [main/INFO]: Setting user: Player683
    [16:25:11] [Client thread/INFO]: LWJGL Version: 2.9.1
    [16:25:13] [Client thread/INFO] [MinecraftForge]: Attempting early MinecraftForge initialization
    [16:25:13] [Client thread/INFO] [FML]: MinecraftForge v10.13.2.1291 Initialized
    [16:25:13] [Client thread/INFO] [FML]: Replaced 183 ore recipies
    [16:25:13] [Client thread/INFO] [MinecraftForge]: Completed early MinecraftForge initialization
    [16:25:14] [Client thread/INFO] [FML]: Searching C:\Users\timour\Documents\Battlefield Heroes\Timour\forge-1.7.10-10.13.2.1291-src\eclipse\mods for mods
    [16:25:19] [Client thread/INFO] [FML]: Forge Mod Loader has identified 4 mods to load
    [16:25:20] [Client thread/INFO] [FML]: Attempting connection with missing mods [mcp, FML, Forge, flightnight] at CLIENT
    [16:25:20] [Client thread/INFO] [FML]: Attempting connection with missing mods [mcp, FML, Forge, flightnight] at SERVER
    [16:25:21] [Client thread/INFO]: Reloading ResourceManager: Default, FMLFileResourcePack:Forge Mod Loader, FMLFileResourcePack:Minecraft Forge, FMLFileResourcePack:FlightNight
    [16:25:21] [Client thread/INFO] [FML]: Processing ObjectHolder annotations
    [16:25:21] [Client thread/INFO] [FML]: Found 341 ObjectHolder annotations
    [16:25:21] [Client thread/INFO] [FML]: Configured a dormant chunk cache size of 0
    [16:25:22] [Client thread/INFO] [FML]: Applying holder lookups
    [16:25:22] [Client thread/INFO] [FML]: Holder lookups applied
    [16:25:22] [Sound Library Loader/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:
    [16:25:22] [Sound Library Loader/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: Starting up SoundSystem…
    [16:25:22] [Thread-6/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: Initializing LWJGL OpenAL
    [16:25:22] [Thread-6/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:     (The LWJGL binding of OpenAL.  For more information, see http://www.lwjgl.org)
    [16:25:23] [Thread-6/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: OpenAL initialized.
    [16:25:23] [Sound Library Loader/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:
    [16:25:23] [Sound Library Loader/INFO]: Sound engine started
    [16:25:38] [Client thread/ERROR]: Using missing texture, unable to load flightnight:textures/blocks/portail.png
    java.io.FileNotFoundException: flightnight:textures/blocks/portail.png
    at net.minecraft.client.resources.FallbackResourceManager.getResource(FallbackResourceManager.java:65) ~[FallbackResourceManager.class:?]
    at net.minecraft.client.resources.SimpleReloadableResourceManager.getResource(SimpleReloadableResourceManager.java:67) ~[SimpleReloadableResourceManager.class:?]
    at net.minecraft.client.renderer.texture.TextureMap.loadTextureAtlas(TextureMap.java:126) [TextureMap.class:?]
    at net.minecraft.client.renderer.texture.TextureMap.loadTexture(TextureMap.java:91) [TextureMap.class:?]
    at net.minecraft.client.renderer.texture.TextureManager.loadTexture(TextureManager.java:89) [TextureManager.class:?]
    at net.minecraft.client.renderer.texture.TextureManager.loadTickableTexture(TextureManager.java:71) [TextureManager.class:?]
    at net.minecraft.client.renderer.texture.TextureManager.loadTextureMap(TextureManager.java:58) [TextureManager.class:?]
    at net.minecraft.client.Minecraft.startGame(Minecraft.java:582) [Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:931) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:164) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_05]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_05]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_05]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[?:1.8.0_05]
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.11.jar:?]
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.11.jar:?]
    at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?]
    at GradleStart.main(Unknown Source) [start/:?]
    [16:25:38] [Client thread/ERROR]: Using missing texture, unable to load flightnight:textures/blocks/Tardis.png
    java.io.FileNotFoundException: flightnight:textures/blocks/Tardis.png
    at net.minecraft.client.resources.FallbackResourceManager.getResource(FallbackResourceManager.java:65) ~[FallbackResourceManager.class:?]
    at net.minecraft.client.resources.SimpleReloadableResourceManager.getResource(SimpleReloadableResourceManager.java:67) ~[SimpleReloadableResourceManager.class:?]
    at net.minecraft.client.renderer.texture.TextureMap.loadTextureAtlas(TextureMap.java:126) [TextureMap.class:?]
    at net.minecraft.client.renderer.texture.TextureMap.loadTexture(TextureMap.java:91) [TextureMap.class:?]
    at net.minecraft.client.renderer.texture.TextureManager.loadTexture(TextureManager.java:89) [TextureManager.class:?]
    at net.minecraft.client.renderer.texture.TextureManager.loadTickableTexture(TextureManager.java:71) [TextureManager.class:?]
    at net.minecraft.client.renderer.texture.TextureManager.loadTextureMap(TextureManager.java:58) [TextureManager.class:?]
    at net.minecraft.client.Minecraft.startGame(Minecraft.java:582) [Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:931) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:164) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_05]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_05]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_05]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[?:1.8.0_05]
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.11.jar:?]
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.11.jar:?]
    at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?]
    at GradleStart.main(Unknown Source) [start/:?]
    [16:25:38] [Client thread/INFO]: Created: 512x256 textures/blocks-atlas
    [16:25:38] [Client thread/ERROR]: Using missing texture, unable to load flightnight:textures/items/activateur.png
    java.io.FileNotFoundException: flightnight:textures/items/activateur.png
    at net.minecraft.client.resources.FallbackResourceManager.getResource(FallbackResourceManager.java:65) ~[FallbackResourceManager.class:?]
    at net.minecraft.client.resources.SimpleReloadableResourceManager.getResource(SimpleReloadableResourceManager.java:67) ~[SimpleReloadableResourceManager.class:?]
    at net.minecraft.client.renderer.texture.TextureMap.loadTextureAtlas(TextureMap.java:126) [TextureMap.class:?]
    at net.minecraft.client.renderer.texture.TextureMap.loadTexture(TextureMap.java:91) [TextureMap.class:?]
    at net.minecraft.client.renderer.texture.TextureManager.loadTexture(TextureManager.java:89) [TextureManager.class:?]
    at net.minecraft.client.renderer.texture.TextureManager.loadTickableTexture(TextureManager.java:71) [TextureManager.class:?]
    at net.minecraft.client.renderer.texture.TextureManager.loadTextureMap(TextureManager.java:58) [TextureManager.class:?]
    at net.minecraft.client.Minecraft.startGame(Minecraft.java:583) [Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:931) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:164) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_05]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_05]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_05]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[?:1.8.0_05]
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.11.jar:?]
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.11.jar:?]
    at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?]
    at GradleStart.main(Unknown Source) [start/:?]
    [16:25:39] [Client thread/INFO]: Created: 512x256 textures/items-atlas
    [16:25:39] [Client thread/INFO] [FML]: Forge Mod Loader has successfully loaded 4 mods
    [16:25:39] [Client thread/INFO]: Reloading ResourceManager: Default, FMLFileResourcePack:Forge Mod Loader, FMLFileResourcePack:Minecraft Forge, FMLFileResourcePack:FlightNight
    [16:25:39] [Client thread/ERROR]: Using missing texture, unable to load flightnight:textures/blocks/portail.png
    java.io.FileNotFoundException: flightnight:textures/blocks/portail.png
    at net.minecraft.client.resources.FallbackResourceManager.getResource(FallbackResourceManager.java:65) ~[FallbackResourceManager.class:?]
    at net.minecraft.client.resources.SimpleReloadableResourceManager.getResource(SimpleReloadableResourceManager.java:67) ~[SimpleReloadableResourceManager.class:?]
    at net.minecraft.client.renderer.texture.TextureMap.loadTextureAtlas(TextureMap.java:126) [TextureMap.class:?]
    at net.minecraft.client.renderer.texture.TextureMap.loadTexture(TextureMap.java:91) [TextureMap.class:?]
    at net.minecraft.client.renderer.texture.TextureManager.loadTexture(TextureManager.java:89) [TextureManager.class:?]
    at net.minecraft.client.renderer.texture.TextureManager.onResourceManagerReload(TextureManager.java:170) [TextureManager.class:?]
    at net.minecraft.client.resources.SimpleReloadableResourceManager.notifyReloadListeners(SimpleReloadableResourceManager.java:134) [SimpleReloadableResourceManager.class:?]
    at net.minecraft.client.resources.SimpleReloadableResourceManager.reloadResources(SimpleReloadableResourceManager.java:118) [SimpleReloadableResourceManager.class:?]
    at net.minecraft.client.Minecraft.refreshResources(Minecraft.java:643) [Minecraft.class:?]
    at cpw.mods.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:303) [FMLClientHandler.class:?]
    at net.minecraft.client.Minecraft.startGame(Minecraft.java:586) [Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:931) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:164) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_05]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_05]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_05]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[?:1.8.0_05]
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.11.jar:?]
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.11.jar:?]
    at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?]
    at GradleStart.main(Unknown Source) [start/:?]
    [16:25:40] [Client thread/ERROR]: Using missing texture, unable to load flightnight:textures/blocks/Tardis.png
    java.io.FileNotFoundException: flightnight:textures/blocks/Tardis.png
    at net.minecraft.client.resources.FallbackResourceManager.getResource(FallbackResourceManager.java:65) ~[FallbackResourceManager.class:?]
    at net.minecraft.client.resources.SimpleReloadableResourceManager.getResource(SimpleReloadableResourceManager.java:67) ~[SimpleReloadableResourceManager.class:?]
    at net.minecraft.client.renderer.texture.TextureMap.loadTextureAtlas(TextureMap.java:126) [TextureMap.class:?]
    at net.minecraft.client.renderer.texture.TextureMap.loadTexture(TextureMap.java:91) [TextureMap.class:?]
    at net.minecraft.client.renderer.texture.TextureManager.loadTexture(TextureManager.java:89) [TextureManager.class:?]
    at net.minecraft.client.renderer.texture.TextureManager.onResourceManagerReload(TextureManager.java:170) [TextureManager.class:?]
    at net.minecraft.client.resources.SimpleReloadableResourceManager.notifyReloadListeners(SimpleReloadableResourceManager.java:134) [SimpleReloadableResourceManager.class:?]
    at net.minecraft.client.resources.SimpleReloadableResourceManager.reloadResources(SimpleReloadableResourceManager.java:118) [SimpleReloadableResourceManager.class:?]
    at net.minecraft.client.Minecraft.refreshResources(Minecraft.java:643) [Minecraft.class:?]
    at cpw.mods.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:303) [FMLClientHandler.class:?]
    at net.minecraft.client.Minecraft.startGame(Minecraft.java:586) [Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:931) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:164) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_05]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_05]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_05]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[?:1.8.0_05]
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.11.jar:?]
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.11.jar:?]
    at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?]
    at GradleStart.main(Unknown Source) [start/:?]
    [16:25:40] [Client thread/INFO]: Created: 512x256 textures/blocks-atlas
    [16:25:40] [Client thread/ERROR]: Using missing texture, unable to load flightnight:textures/items/activateur.png
    java.io.FileNotFoundException: flightnight:textures/items/activateur.png
    at net.minecraft.client.resources.FallbackResourceManager.getResource(FallbackResourceManager.java:65) ~[FallbackResourceManager.class:?]
    at net.minecraft.client.resources.SimpleReloadableResourceManager.getResource(SimpleReloadableResourceManager.java:67) ~[SimpleReloadableResourceManager.class:?]
    at net.minecraft.client.renderer.texture.TextureMap.loadTextureAtlas(TextureMap.java:126) [TextureMap.class:?]
    at net.minecraft.client.renderer.texture.TextureMap.loadTexture(TextureMap.java:91) [TextureMap.class:?]
    at net.minecraft.client.renderer.texture.TextureManager.loadTexture(TextureManager.java:89) [TextureManager.class:?]
    at net.minecraft.client.renderer.texture.TextureManager.onResourceManagerReload(TextureManager.java:170) [TextureManager.class:?]
    at net.minecraft.client.resources.SimpleReloadableResourceManager.notifyReloadListeners(SimpleReloadableResourceManager.java:134) [SimpleReloadableResourceManager.class:?]
    at net.minecraft.client.resources.SimpleReloadableResourceManager.reloadResources(SimpleReloadableResourceManager.java:118) [SimpleReloadableResourceManager.class:?]
    at net.minecraft.client.Minecraft.refreshResources(Minecraft.java:643) [Minecraft.class:?]
    at cpw.mods.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:303) [FMLClientHandler.class:?]
    at net.minecraft.client.Minecraft.startGame(Minecraft.java:586) [Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:931) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:164) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_05]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_05]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_05]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[?:1.8.0_05]
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.11.jar:?]
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.11.jar:?]
    at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?]
    at GradleStart.main(Unknown Source) [start/:?]
    [16:25:40] [Client thread/INFO]: Created: 512x256 textures/items-atlas
    [16:25:40] [Client thread/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:
    [16:25:40] [Client thread/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: SoundSystem shutting down…
    [16:25:40] [Client thread/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:importantMessage:90]:     Author: Paul Lamb, www.paulscode.com
    [16:25:40] [Client thread/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:
    [16:25:40] [Sound Library Loader/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:
    [16:25:40] [Sound Library Loader/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: Starting up SoundSystem…
    [16:25:40] [Thread-8/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: Initializing LWJGL OpenAL
    [16:25:40] [Thread-8/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:     (The LWJGL binding of OpenAL.  For more information, see http://www.lwjgl.org)
    [16:25:41] [Thread-8/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: OpenAL initialized.
    [16:25:41] [Sound Library Loader/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:
    [16:25:41] [Sound Library Loader/INFO]: Sound engine started
    [16:25:57] [Server thread/INFO]: Starting integrated minecraft server version 1.7.10
    [16:25:57] [Server thread/INFO]: Generating keypair
    [16:25:58] [Server thread/INFO] [FML]: Injecting existing block and item data into this server instance
    [16:25:58] [Server thread/INFO] [FML]: Found a missing id from the world flightnight:Dimension
    [16:25:58] [Server thread/INFO] [FML]: Found a missing id from the world flightnight:Dimension
    [16:25:58] [Server thread/ERROR] [FML]: There are unidentified mappings in this world - we are going to attempt to process anyway
    [16:25:58] [Server thread/ERROR] [FML]: Unidentified block: flightnight:Dimension, id 169
    [16:25:58] [Server thread/ERROR] [FML]: Unidentified item: flightnight:Dimension, id 169
    [16:26:05] [Server thread/INFO] [FML]: World backup created at C:\Users\timour\Documents\Battlefield Heroes\Timour\forge-1.7.10-10.13.2.1291-src\eclipse\saves\New World-20150531-162602.zip.
    [16:26:05] [Server thread/ERROR] [FML]: This world contains block and item mappings that may cause world breakage
    [16:26:05] [Server thread/INFO] [FML]: Injecting new block and item data into this server instance.
    [16:26:05] [Server thread/INFO] [FML]: Injected new block/item flightnight:portail: 165 (init) -> 176 (map).
    [16:26:05] [Server thread/INFO] [FML]: Injected new block/item flightnight:activateur: 4096 (init) -> 4098 (map).
    [16:26:05] [Server thread/INFO] [FML]: Injected new block/item flightnight:portail: 165 (init) -> 176 (map).
    [16:26:05] [Server thread/INFO] [FML]: Applying holder lookups
    [16:26:05] [Server thread/INFO] [FML]: Holder lookups applied
    [16:26:06] [Server thread/INFO] [FML]: Loading dimension 0 (New World) (net.minecraft.server.integrated.IntegratedServer@267d64)
    [16:26:09] [Server thread/INFO] [FML]: Loading dimension 20 (New World) (net.minecraft.server.integrated.IntegratedServer@267d64)
    [16:26:10] [Server thread/INFO] [FML]: Applying holder lookups
    [16:26:10] [Server thread/INFO] [FML]: Holder lookups applied
    [16:26:10] [Server thread/INFO] [FML]: The state engine was in incorrect state SERVER_STARTING and forced into state SERVER_STOPPED. Errors may have been discarded.
    [16:26:17] [Server thread/INFO]: Starting integrated minecraft server version 1.7.10
    [16:26:17] [Server thread/INFO]: Generating keypair
    [16:26:18] [Server thread/INFO]: Converting map!
    [16:26:18] [Server thread/INFO]: Scanning folders…
    [16:26:18] [Server thread/INFO]: Total conversion count is 0
    [16:26:18] [Server thread/INFO] [FML]: Injecting existing block and item data into this server instance
    [16:26:18] [Server thread/INFO] [FML]: Applying holder lookups
    [16:26:18] [Server thread/INFO] [FML]: Holder lookups applied
    [16:26:21] [Server thread/INFO] [FML]: Loading dimension 0 (New World) (net.minecraft.server.integrated.IntegratedServer@25910f)
    [16:26:21] [Server thread/INFO] [FML]: Loading dimension 20 (New World) (net.minecraft.server.integrated.IntegratedServer@25910f)
    [16:26:21] [Server thread/INFO] [FML]: Loading dimension 1 (New World) (net.minecraft.server.integrated.IntegratedServer@25910f)
    [16:26:21] [Server thread/INFO] [FML]: Loading dimension -1 (New World) (net.minecraft.server.integrated.IntegratedServer@25910f)
    [16:26:21] [Server thread/INFO]: Preparing start region for level 0
    [16:26:22] [Server thread/INFO]: Preparing spawn area: 91%
    [16:26:23] [Server thread/INFO]: Changing view distance to 8, from 10
    [16:26:24] [Netty Client IO #1/INFO] [FML]: Server protocol version 1
    [16:26:24] [Netty IO #3/INFO] [FML]: Client protocol version 1
    [16:26:24] [Netty IO #3/INFO] [FML]: Client attempting to join with 4 mods : FML@7.10.85.1291,flightnight@1.0.0,Forge@10.13.2.1291,mcp@9.05
    [16:26:24] [Netty IO #3/INFO] [FML]: Attempting connection with missing mods [] at CLIENT
    [16:26:24] [Netty Client IO #1/INFO] [FML]: Attempting connection with missing mods [] at SERVER
    [16:26:24] [Client thread/INFO] [FML]: [Client thread] Client side modded connection established
    [16:26:24] [Server thread/INFO] [FML]: [Server thread] Server side modded connection established
    [16:26:24] [Server thread/INFO]: Player683[local:E:b07da388] logged in with entity id 0 at (-1013.5, 4.0, 42.5)
    [16:26:24] [Server thread/INFO]: Player683 joined the game
    [16:26:47] [Server thread/INFO]: Player683 has just earned the achievement [Taking Inventory]
    [16:26:47] [Client thread/INFO]: [CHAT] Player683 has just earned the achievement [Taking Inventory]
    [16:27:16] [Server thread/ERROR]: Encountered an unexpected exception
    net.minecraft.util.ReportedException: Exception generating new chunk
    at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:198) ~[NetworkSystem.class:?]
    at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:726) ~[MinecraftServer.class:?]
    at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:614) ~[MinecraftServer.class:?]
    at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:118) ~[IntegratedServer.class:?]
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:485) [MinecraftServer.class:?]
    at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:752) [MinecraftServer$2.class:?]
    Caused by: java.lang.ClassCastException: net.minecraft.world.biome.BiomeGenDesert cannot be cast to net.minecraft.world.biome.BiomeGenPlains
    at com.XDoctorX.main.world.ChunkProviderTardis.replaceBlocksForBiome(ChunkProviderTardis.java:202) ~[ChunkProviderTardis.class:?]
    at com.XDoctorX.main.world.ChunkProviderTardis.provideChunk(ChunkProviderTardis.java:218) ~[ChunkProviderTardis.class:?]
    at net.minecraft.world.gen.ChunkProviderServer.originalLoadChunk(ChunkProviderServer.java:190) ~[ChunkProviderServer.class:?]
    at net.minecraft.world.gen.ChunkProviderServer.loadChunk(ChunkProviderServer.java:149) ~[ChunkProviderServer.class:?]
    at net.minecraft.world.gen.ChunkProviderServer.loadChunk(ChunkProviderServer.java:119) ~[ChunkProviderServer.class:?]
    at net.minecraft.world.gen.ChunkProviderServer.provideChunk(ChunkProviderServer.java:221) ~[ChunkProviderServer.class:?]
    at net.minecraft.world.World.getChunkFromChunkCoords(World.java:482) ~[World.class:?]
    at net.minecraft.world.World.getBlock(World.java:387) ~[World.class:?]
    at com.XDoctorX.main.dimension.TeleporterTardis.placeInExistingPortal(TeleporterTardis.java:110) ~[TeleporterTardis.class:?]
    at com.XDoctorX.main.dimension.TeleporterTardis.placeInPortal(TeleporterTardis.java:37) ~[TeleporterTardis.class:?]
    at net.minecraft.server.management.ServerConfigurationManager.transferEntityToWorld(ServerConfigurationManager.java:625) ~[ServerConfigurationManager.class:?]
    at net.minecraft.server.management.ServerConfigurationManager.transferPlayerToDimension(ServerConfigurationManager.java:529) ~[ServerConfigurationManager.class:?]
    at com.XDoctorX.main.Block.Portail.onEntityCollidedWithBlock(Portail.java:148) ~[Portail.class:?]
    at net.minecraft.entity.Entity.func_145775_I(Entity.java:962) ~[Entity.class:?]
    at net.minecraft.entity.Entity.moveEntity(Entity.java:895) ~[Entity.class:?]
    at net.minecraft.entity.EntityLivingBase.moveEntityWithHeading(EntityLivingBase.java:1680) ~[EntityLivingBase.class:?]
    at net.minecraft.entity.player.EntityPlayer.moveEntityWithHeading(EntityPlayer.java:1862) ~[EntityPlayer.class:?]
    at net.minecraft.entity.EntityLivingBase.onLivingUpdate(EntityLivingBase.java:2023) ~[EntityLivingBase.class:?]
    at net.minecraft.entity.player.EntityPlayer.onLivingUpdate(EntityPlayer.java:612) ~[EntityPlayer.class:?]
    at net.minecraft.entity.EntityLivingBase.onUpdate(EntityLivingBase.java:1816) ~[EntityLivingBase.class:?]
    at net.minecraft.entity.player.EntityPlayer.onUpdate(EntityPlayer.java:327) ~[EntityPlayer.class:?]
    at net.minecraft.entity.player.EntityPlayerMP.onUpdateEntity(EntityPlayerMP.java:330) ~[EntityPlayerMP.class:?]
    at net.minecraft.network.NetHandlerPlayServer.processPlayer(NetHandlerPlayServer.java:329) ~[NetHandlerPlayServer.class:?]
    at net.minecraft.network.play.client.C03PacketPlayer.processPacket(C03PacketPlayer.java:37) ~[C03PacketPlayer.class:?]
    at net.minecraft.network.play.client.C03PacketPlayer$C04PacketPlayerPosition.processPacket(C03PacketPlayer.java:163) ~[C03PacketPlayer$C04PacketPlayerPosition.class:?]
    at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:241) ~[NetworkManager.class:?]
    at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:182) ~[NetworkSystem.class:?]
    … 5 more
    [16:27:16] [Server thread/ERROR]: This crash report has been saved to: C:\Users\timour\Documents\Battlefield Heroes\Timour\forge-1.7.10-10.13.2.1291-src\eclipse\.\crash-reports\crash-2015-05-31_16.27.16-server.txt
    [16:27:16] [Server thread/INFO]: Stopping server
    [16:27:16] [Server thread/INFO]: Saving players
    [16:27:16] [Client thread/INFO] [STDOUT]: [net.minecraft.client.Minecraft:displayCrashReport:388]: –-- Minecraft Crash Report ----
    // Hey, that tickles! Hehehe!
    
    Time: 31/05/15 16:27
    Description: Exception generating new chunk
    
    java.lang.ClassCastException: net.minecraft.world.biome.BiomeGenDesert cannot be cast to net.minecraft.world.biome.BiomeGenPlains
    at com.XDoctorX.main.world.ChunkProviderTardis.replaceBlocksForBiome(ChunkProviderTardis.java:202)
    at com.XDoctorX.main.world.ChunkProviderTardis.provideChunk(ChunkProviderTardis.java:218)
    at net.minecraft.world.gen.ChunkProviderServer.originalLoadChunk(ChunkProviderServer.java:190)
    at net.minecraft.world.gen.ChunkProviderServer.loadChunk(ChunkProviderServer.java:149)
    at net.minecraft.world.gen.ChunkProviderServer.loadChunk(ChunkProviderServer.java:119)
    at net.minecraft.world.gen.ChunkProviderServer.provideChunk(ChunkProviderServer.java:221)
    at net.minecraft.world.World.getChunkFromChunkCoords(World.java:482)
    at net.minecraft.world.World.getBlock(World.java:387)
    at com.XDoctorX.main.dimension.TeleporterTardis.placeInExistingPortal(TeleporterTardis.java:110)
    at com.XDoctorX.main.dimension.TeleporterTardis.placeInPortal(TeleporterTardis.java:37)
    at net.minecraft.server.management.ServerConfigurationManager.transferEntityToWorld(ServerConfigurationManager.java:625)
    at net.minecraft.server.management.ServerConfigurationManager.transferPlayerToDimension(ServerConfigurationManager.java:529)
    at com.XDoctorX.main.Block.Portail.onEntityCollidedWithBlock(Portail.java:148)
    at net.minecraft.entity.Entity.func_145775_I(Entity.java:962)
    at net.minecraft.entity.Entity.moveEntity(Entity.java:895)
    at net.minecraft.entity.EntityLivingBase.moveEntityWithHeading(EntityLivingBase.java:1680)
    at net.minecraft.entity.player.EntityPlayer.moveEntityWithHeading(EntityPlayer.java:1862)
    at net.minecraft.entity.EntityLivingBase.onLivingUpdate(EntityLivingBase.java:2023)
    at net.minecraft.entity.player.EntityPlayer.onLivingUpdate(EntityPlayer.java:612)
    at net.minecraft.entity.EntityLivingBase.onUpdate(EntityLivingBase.java:1816)
    at net.minecraft.entity.player.EntityPlayer.onUpdate(EntityPlayer.java:327)
    at net.minecraft.entity.player.EntityPlayerMP.onUpdateEntity(EntityPlayerMP.java:330)
    at net.minecraft.network.NetHandlerPlayServer.processPlayer(NetHandlerPlayServer.java:329)
    at net.minecraft.network.play.client.C03PacketPlayer.processPacket(C03PacketPlayer.java:37)
    at net.minecraft.network.play.client.C03PacketPlayer$C04PacketPlayerPosition.processPacket(C03PacketPlayer.java:163)
    at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:241)
    at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:182)
    at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:726)
    at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:614)
    at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:118)
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:485)
    at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:752)
    
    A detailed walkthrough of the error, its code path and all known details is as follows:
    ---------------------------------------------------------------------------------------
    
    -- Head --
    Stacktrace:
    at com.XDoctorX.main.world.ChunkProviderTardis.replaceBlocksForBiome(ChunkProviderTardis.java:202)
    at com.XDoctorX.main.world.ChunkProviderTardis.provideChunk(ChunkProviderTardis.java:218)
    
    -- Chunk to be generated --
    Details:
    Location: -15,-8
    Position hash: -30064771087
    Generator: RandomLevelSource
    Stacktrace:
    at net.minecraft.world.gen.ChunkProviderServer.originalLoadChunk(ChunkProviderServer.java:190)
    at net.minecraft.world.gen.ChunkProviderServer.loadChunk(ChunkProviderServer.java:149)
    at net.minecraft.world.gen.ChunkProviderServer.loadChunk(ChunkProviderServer.java:119)
    at net.minecraft.world.gen.ChunkProviderServer.provideChunk(ChunkProviderServer.java:221)
    at net.minecraft.world.World.getChunkFromChunkCoords(World.java:482)
    
    -- Requested block coordinates --
    Details:
    Found chunk: true
    Location: World: (-229,255,-124), Chunk: (at 11,15,4 in -15,-8; contains blocks -240,0,-128 to -225,255,-113), Region: (-1,-1; contains chunks -32,-32 to -1,-1, blocks -512,0,-512 to -1,255,-1)
    Stacktrace:
    at net.minecraft.world.World.getBlock(World.java:387)
    at com.XDoctorX.main.dimension.TeleporterTardis.placeInExistingPortal(TeleporterTardis.java:110)
    at com.XDoctorX.main.dimension.TeleporterTardis.placeInPortal(TeleporterTardis.java:37)
    at net.minecraft.server.management.ServerConfigurationManager.transferEntityToWorld(ServerConfigurationManager.java:625)
    at net.minecraft.server.management.ServerConfigurationManager.transferPlayerToDimension(ServerConfigurationManager.java:529)
    at com.XDoctorX.main.Block.Portail.onEntityCollidedWithBlock(Portail.java:148)
    
    -- Block being collided with --
    Details:
    Block type: ID #165 (tile.portail // com.XDoctorX.main.Block.Portail)
    Block data value: 0 / 0x0 / 0b0000
    Block location: World: (-1014,4,44), Chunk: (at 10,0,12 in -64,2; contains blocks -1024,0,32 to -1009,255,47), Region: (-2,0; contains chunks -64,0 to -33,31, blocks -1024,0,0 to -513,255,511)
    Stacktrace:
    at net.minecraft.entity.Entity.func_145775_I(Entity.java:962)
    
    -- Entity being checked for collision --
    Details:
    Entity Type: null (net.minecraft.entity.player.EntityPlayerMP)
    Entity ID: 0
    Entity Name: Player683
    Entity's Exact location: -101,00, 4,92, 4,00
    Entity's Block location: World: (-101,4,4), Chunk: (at 11,0,4 in -7,0; contains blocks -112,0,0 to -97,255,15), Region: (-1,0; contains chunks -32,0 to -1,31, blocks -512,0,0 to -1,255,511)
    Entity's Momentum: 0,00, -0,08, 0,00
    Stacktrace:
    at net.minecraft.entity.Entity.moveEntity(Entity.java:895)
    at net.minecraft.entity.EntityLivingBase.moveEntityWithHeading(EntityLivingBase.java:1680)
    at net.minecraft.entity.player.EntityPlayer.moveEntityWithHeading(EntityPlayer.java:1862)
    at net.minecraft.entity.EntityLivingBase.onLivingUpdate(EntityLivingBase.java:2023)
    at net.minecraft.entity.player.EntityPlayer.onLivingUpdate(EntityPlayer.java:612)
    at net.minecraft.entity.EntityLivingBase.onUpdate(EntityLivingBase.java:1816)
    at net.minecraft.entity.player.EntityPlayer.onUpdate(EntityPlayer.java:327)
    
    -- Player being ticked --
    Details:
    Entity Type: null (net.minecraft.entity.player.EntityPlayerMP)
    Entity ID: 0
    Entity Name: Player683
    Entity's Exact location: -101,00, 4,92, 4,00
    Entity's Block location: World: (-101,4,4), Chunk: (at 11,0,4 in -7,0; contains blocks -112,0,0 to -97,255,15), Region: (-1,0; contains chunks -32,0 to -1,31, blocks -512,0,0 to -1,255,511)
    Entity's Momentum: 0,00, -0,08, 0,00
    Stacktrace:
    at net.minecraft.entity.player.EntityPlayerMP.onUpdateEntity(EntityPlayerMP.java:330)
    at net.minecraft.network.NetHandlerPlayServer.processPlayer(NetHandlerPlayServer.java:329)
    at net.minecraft.network.play.client.C03PacketPlayer.processPacket(C03PacketPlayer.java:37)
    at net.minecraft.network.play.client.C03PacketPlayer$C04PacketPlayerPosition.processPacket(C03PacketPlayer.java:163)
    at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:241)
    
    -- Ticking connection --
    Details:
    Connection: net.minecraft.network.NetworkManager@205046
    Stacktrace:
    at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:182)
    at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:726)
    at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:614)
    at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:118)
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:485)
    at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:752)
    
    -- System Details --
    Details:
    Minecraft Version: 1.7.10
    Operating System: Windows 7 (x86) version 6.1
    Java Version: 1.8.0_05, Oracle Corporation
    Java VM Version: Java HotSpot(TM) Client VM (mixed mode), Oracle Corporation
    Memory: 968343496 bytes (923 MB) / 1060372480 bytes (1011 MB) up to 1060372480 bytes (1011 MB)
    JVM Flags: 3 total; -Xincgc -Xmx1024M -Xms1024M
    AABB Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used
    IntCache: cache: 0, tcache: 0, allocated: 1, tallocated: 14
    FML: MCP v9.05 FML v7.10.85.1291 Minecraft Forge 10.13.2.1291 4 mods loaded, 4 mods active
    mcp{9.05} [Minecraft Coder Pack] (minecraft.jar) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available->Available->Available
    FML{7.10.85.1291} [Forge Mod Loader] (forgeSrc-1.7.10-10.13.2.1291.jar) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available->Available->Available
    Forge{10.13.2.1291} [Minecraft Forge] (forgeSrc-1.7.10-10.13.2.1291.jar) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available->Available->Available
    flightnight{1.0.0} [FlightNight] (bin) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available->Available->Available
    Profiler Position: N/A (disabled)
    Vec3 Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used
    Player Count: 1 / 8; [EntityPlayerMP['Player683'/0, l='New World', x=-101,00, y=4,92, z=4,00]]
    Type: Integrated Server (map_client.txt)
    Is Modded: Definitely; Client brand changed to 'fml,forge'
    [16:27:16] [Client thread/INFO] [STDOUT]: [net.minecraft.client.Minecraft:displayCrashReport:393]: #@!@# Game crashed! Crash report saved to: #@!@# .\crash-reports\crash-2015-05-31_16.27.16-server.txt
    [16:27:16] [Client thread/INFO] [FML]: Waiting for the server to terminate/save.
    [16:27:16] [Server thread/INFO]: Saving worlds
    [16:27:16] [Server thread/INFO]: Saving chunks for level 'New World'/Overworld
    [16:27:16] [Server thread/INFO]: Saving chunks for level 'New World'/Nether
    [16:27:17] [Server thread/INFO]: Saving chunks for level 'New World'/The End
    [16:27:17] [Server thread/INFO]: Saving chunks for level 'New World'/Tardis
    [16:27:20] [Server thread/INFO] [FML]: Unloading dimension 0
    [16:27:20] [Server thread/INFO] [FML]: Unloading dimension -1
    [16:27:20] [Server thread/INFO] [FML]: Unloading dimension 1
    [16:27:20] [Server thread/INFO] [FML]: Unloading dimension 20
    [16:27:20] [Server thread/INFO] [FML]: Applying holder lookups
    [16:27:20] [Server thread/INFO] [FML]: Holder lookups applied
    [16:27:20] [Server thread/INFO] [FML]: The state engine was in incorrect state SERVER_STOPPING and forced into state SERVER_STOPPED. Errors may have been discarded.
    [16:27:20] [Client thread/INFO] [FML]: Server terminated.
    AL lib: (EE) alc_cleanup: 1 device not closed
    Java HotSpot(TM) Client VM warning: Using incremental CMS is deprecated and will likely be removed in a future release
    
    


  • On peut pas deviner les classes de ton mod… Je ne possède pas encore ce pouvoir.

    "Bonjour, jai un crash" ça donne envie d'aider...



  • This post is deleted!

  • Administrateurs

                BiomeGenPlains /*TODO ce biome est a remplacer par le votre*/ biomegenbase = (BiomeGenPlains /*TODO ce biome est a remplacer par le votre*/)biomeList[l + k * 16];
    
    java.lang.ClassCastException: net.minecraft.world.biome.BiomeGenDesert cannot be cast to net.minecraft.world.biome.BiomeGenPlains
    

    Vu l'erreur il faudrait plutôt mettre BiomeGenDesert à la place de BiomeGenPlains, voir mettre BiomeGenBase.



  • This post is deleted!


  • 
    public void func_150573_a(World world, Random rand, Block[] block, byte[] abyte, int x, int z, double par7)
    {
    this.field_150604_aj = 0;
    }
    

    Je suppose.



  • This post is deleted!


  • @'XDoctorX':

    le mettre ou ?

    à l'endroit où il y a une fonction du même nom, dans la classe biome.

    PS : essaie de comprendre le code avant de l'utiliser



  • @'SCAREX':

    PS : essaie de comprendre le code avant de l'utiliser

    Je dit la même chose, avant d'utiliser le code assure toi d'avoir compris en grosse partie. En plus met toi dans ta tête pour se genre de chose simple "comment faire (pour générer un monde vide) ? ", et sit tu trouve pas tu peux demander ^^.



  • This post is deleted!


  • This post is deleted!


  • This post is deleted!


  • c'est dans la classes téléporte, à la place de get l'entity pos tu get la pos du world. Pour la structure dans le chunk Provider il faut générer un structure selon les coordonnées fix.



  • Jcomprend toujours pas un truc , jdois être débile tu dis ```java
    this.dimensionId = TutoDimension.TutodimID;

    
    Mais dans ton post ou est la classe TutoDimension ? Désolé je suis le tuto a la lettre je loupe peut - être mais ca me cause plein d'erreur Oo


  • TutoDimension est la classe principale du mod.



  • Ok merci j'ai un crash lié a l'ID de la dimension mais je comprend pas pourquoi je l'ai en fait

    DimensionRegister

    package mod.common.world.structure;
    
    import cpw.mods.fml.common.registry.GameRegistry;
    import mod.common.world.type.AncientWorldProvider;
    import net.minecraft.block.Block;
    import net.minecraft.block.material.Material;
    import net.minecraft.item.Item;
    import net.minecraftforge.common.DimensionManager;
    
    public class DimensionRegister {
    
    public static Block AncientPortail;
    public static Item AncientActivateur;
    public static int tutoDimAncient4;
    
    public static void register()
    {
    AncientPortail = new AncientPortail(Material.portal).setBlockName("portail");
    AncientActivateur = new AncientActivateur().setUnlocalizedName("activateur");
    
    GameRegistry.registerBlock(AncientPortail, "tuto_portail");
    GameRegistry.registerItem(AncientActivateur, "tuto_activateur");
    
    DimensionManager.registerProviderType(DimensionRegister.tutoDimAncient4, AncientWorldProvider.class, false);
    DimensionManager.registerDimension(DimensionRegister.tutoDimAncient4, DimensionRegister.tutoDimAncient4);
    }
    }
    
    

    le crash en entier

    [00:45:46] [main/INFO] [GradleStart]: Extra: []
    [00:45:46] [main/INFO] [GradleStart]: Running with arguments: [–userProperties, {}, --accessToken, {REDACTED}, --assetIndex, 1.7.10, --assetsDir, C:/Users/Legrandfifou/.gradle/caches/minecraft/assets, --version, 1.7.10, --tweakClass, cpw.mods.fml.common.launcher.FMLTweaker, --tweakClass, net.minecraftforge.gradle.tweakers.CoremodTweaker]
    [00:45:46] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.FMLTweaker
    [00:45:46] [main/INFO] [LaunchWrapper]: Using primary tweak class name cpw.mods.fml.common.launcher.FMLTweaker
    [00:45:46] [main/INFO] [LaunchWrapper]: Loading tweak class name net.minecraftforge.gradle.tweakers.CoremodTweaker
    [00:45:46] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLTweaker
    [00:45:46] [main/INFO] [FML]: Forge Mod Loader version 7.99.16.1448 for Minecraft 1.7.10 loading
    [00:45:46] [main/INFO] [FML]: Java is Java HotSpot(TM) 64-Bit Server VM, version 1.7.0_75, running on Windows 8.1:amd64:6.3, installed at C:\Program Files\Java\jre7
    [00:45:46] [main/INFO] [FML]: Managed to load a deobfuscated Minecraft name- we are in a deobfuscated environment. Skipping runtime deobfuscation
    [00:45:46] [main/INFO] [LaunchWrapper]: Calling tweak class net.minecraftforge.gradle.tweakers.CoremodTweaker
    [00:45:46] [main/INFO] [GradleStart]: Injecting location in coremod cpw.mods.fml.relauncher.FMLCorePlugin
    [00:45:46] [main/INFO] [GradleStart]: Injecting location in coremod net.minecraftforge.classloading.FMLForgePlugin
    [00:45:46] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker
    [00:45:46] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.FMLDeobfTweaker
    [00:45:46] [main/INFO] [LaunchWrapper]: Loading tweak class name net.minecraftforge.gradle.tweakers.AccessTransformerTweaker
    [00:45:46] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker
    [00:45:46] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker
    [00:45:46] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper
    [00:45:46] [main/ERROR] [FML]: The binary patch set is missing. Either you are in a development environment, or things are not going to work!
    [00:45:47] [main/ERROR] [FML]: FML appears to be missing any signature data. This is not a good thing
    [00:45:47] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper
    [00:45:47] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLDeobfTweaker
    [00:45:48] [main/INFO] [LaunchWrapper]: Calling tweak class net.minecraftforge.gradle.tweakers.AccessTransformerTweaker
    [00:45:48] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.TerminalTweaker
    [00:45:48] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.TerminalTweaker
    [00:45:48] [main/INFO] [LaunchWrapper]: Launching wrapped minecraft {net.minecraft.client.main.Main}
    [00:45:49] [main/INFO]: Setting user: Player140
    [00:45:50] [Client thread/INFO]: LWJGL Version: 2.9.1
    [00:45:50] [Client thread/INFO] [STDOUT]: [cpw.mods.fml.client.SplashProgress:start:188]: –-- Minecraft Crash Report ----
    // Everything's going to plan. No, really, that was supposed to happen.
    
    Time: 11/07/15 0:45
    Description: Loading screen debug info
    
    This is just a prompt for computer specs to be printed. THIS IS NOT A ERROR
    
    A detailed walkthrough of the error, its code path and all known details is as follows:
    ---------------------------------------------------------------------------------------
    
    -- System Details --
    Details:
    Minecraft Version: 1.7.10
    Operating System: Windows 8.1 (amd64) version 6.3
    Java Version: 1.7.0_75, Oracle Corporation
    Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
    Memory: 817696760 bytes (779 MB) / 1037959168 bytes (989 MB) up to 1037959168 bytes (989 MB)
    JVM Flags: 3 total; -Xincgc -Xmx1024M -Xms1024M
    AABB Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used
    IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
    FML:
    GL info: ' Vendor: 'NVIDIA Corporation' Version: '4.5.0 NVIDIA 350.12' Renderer: 'GeForce GTX 770/PCIe/SSE2'
    [00:45:50] [Client thread/INFO] [MinecraftForge]: Attempting early MinecraftForge initialization
    [00:45:50] [Client thread/INFO] [FML]: MinecraftForge v10.13.4.1448 Initialized
    [00:45:50] [Client thread/INFO] [FML]: Replaced 183 ore recipies
    [00:45:50] [Client thread/INFO] [MinecraftForge]: Completed early MinecraftForge initialization
    [00:45:51] [Client thread/INFO] [FML]: Found 0 mods from the command line. Injecting into mod discoverer
    [00:45:51] [Client thread/INFO] [FML]: Searching C:\Users\Legrandfifou\Pictures\forge\eclipse\mods for mods
    [00:45:52] [Client thread/INFO] [FML]: Forge Mod Loader has identified 4 mods to load
    [00:45:53] [Client thread/INFO] [FML]: Attempting connection with missing mods [mcp, FML, Forge, modminecraft] at CLIENT
    [00:45:53] [Client thread/INFO] [FML]: Attempting connection with missing mods [mcp, FML, Forge, modminecraft] at SERVER
    [00:45:53] [Client thread/INFO]: Reloading ResourceManager: Default, FMLFileResourcePack:Forge Mod Loader, FMLFileResourcePack:Minecraft Forge, FMLFileResourcePack:Mod Minecraft
    [00:45:53] [Client thread/INFO] [FML]: Processing ObjectHolder annotations
    [00:45:53] [Client thread/INFO] [FML]: Found 341 ObjectHolder annotations
    [00:45:53] [Client thread/INFO] [FML]: Identifying ItemStackHolder annotations
    [00:45:53] [Client thread/INFO] [FML]: Found 0 ItemStackHolder annotations
    [00:45:53] [Client thread/INFO] [FML]: Configured a dormant chunk cache size of 0
    [00:45:53] [Client thread/INFO] [FML]: Applying holder lookups
    [00:45:53] [Client thread/INFO] [FML]: Holder lookups applied
    [00:45:53] [Client thread/INFO] [FML]: Injecting itemstacks
    [00:45:53] [Client thread/INFO] [FML]: Itemstack injection complete
    [00:45:53] [Sound Library Loader/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:
    [00:45:53] [Sound Library Loader/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: Starting up SoundSystem…
    [00:45:53] [Thread-8/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: Initializing LWJGL OpenAL
    [00:45:53] [Thread-8/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: (The LWJGL binding of OpenAL. For more information, see http://www.lwjgl.org)
    [00:45:53] [Thread-8/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: OpenAL initialized.
    [00:45:54] [Sound Library Loader/INFO] [STDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:
    [00:45:54] [Sound Library Loader/INFO]: Sound engine started
    [00:45:54] [Client thread/INFO]: Created: 512x256 textures/blocks-atlas
    [00:45:54] [Client thread/INFO]: Created: 256x256 textures/items-atlas
    [00:45:54] [Client thread/INFO] [STDOUT]: [mod.client.ClientProxy:registerRender:36]: render
    [00:45:55] [Client thread/INFO] [FML]: Injecting itemstacks
    [00:45:55] [Client thread/INFO] [FML]: Itemstack injection complete
    [00:45:55] [Client thread/ERROR] [FML]: Fatal errors were detected during the transition from POSTINITIALIZATION to AVAILABLE. Loading cannot continue
    [00:45:55] [Client thread/ERROR] [FML]:
    States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored
    UCHIJ mcp{9.05} [Minecraft Coder Pack] (minecraft.jar)
    UCHIJ FML{7.10.99.99} [Forge Mod Loader] (forgeSrc-1.7.10-10.13.4.1448-1.7.10.jar)
    UCHIJ Forge{10.13.4.1448} [Minecraft Forge] (forgeSrc-1.7.10-10.13.4.1448-1.7.10.jar)
    UCHIE modminecraft{1.0} [Mod Minecraft] (bin)
    [00:45:55] [Client thread/ERROR] [FML]: The following problems were captured during this phase
    [00:45:55] [Client thread/ERROR] [FML]: Caught exception from modminecraft
    java.lang.IllegalArgumentException: Failed to register dimension for id 0, One is already registered
    at net.minecraftforge.common.DimensionManager.registerDimension(DimensionManager.java:118) ~[forgeSrc-1.7.10-10.13.4.1448-1.7.10.jar:?]
    at mod.common.world.structure.DimensionRegister.register(DimensionRegister.java:26) ~[bin/:?]
    at mod.ModMinecraft.postInit(ModMinecraft.java:64) ~[bin/:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_75]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_75]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_75]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_75]
    at cpw.mods.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:532) ~[forgeSrc-1.7.10-10.13.4.1448-1.7.10.jar:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_75]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_75]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_75]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_75]
    at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.post(EventBus.java:275) ~[guava-17.0.jar:?]
    at cpw.mods.fml.common.LoadController.sendEventToModContainer(LoadController.java:212) ~[forgeSrc-1.7.10-10.13.4.1448-1.7.10.jar:?]
    at cpw.mods.fml.common.LoadController.propogateStateMessage(LoadController.java:190) ~[forgeSrc-1.7.10-10.13.4.1448-1.7.10.jar:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_75]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_75]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_75]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_75]
    at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.post(EventBus.java:275) ~[guava-17.0.jar:?]
    at cpw.mods.fml.common.LoadController.distributeStateMessage(LoadController.java:119) [LoadController.class:?]
    at cpw.mods.fml.common.Loader.initializeMods(Loader.java:742) [Loader.class:?]
    at cpw.mods.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:311) [FMLClientHandler.class:?]
    at net.minecraft.client.Minecraft.startGame(Minecraft.java:597) [Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:942) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:164) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_75]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_75]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_75]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_75]
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.11.jar:?]
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.11.jar:?]
    at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?]
    at GradleStart.main(Unknown Source) [start/:?]
    [00:45:55] [Client thread/INFO] [STDOUT]: [net.minecraft.client.Minecraft:displayCrashReport:388]: –-- Minecraft Crash Report ----
    // On the bright side, I bought you a teddy bear!
    
    Time: 11/07/15 0:45
    Description: Initializing game
    
    java.lang.IllegalArgumentException: Failed to register dimension for id 0, One is already registered
    at net.minecraftforge.common.DimensionManager.registerDimension(DimensionManager.java:118)
    at mod.common.world.structure.DimensionRegister.register(DimensionRegister.java:26)
    at mod.ModMinecraft.postInit(ModMinecraft.java:64)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    


  • Parce que tu ne set jamais l'ID, donc l'ID est toujours à 0, il faut choisir un ID, sachant que -1,0 et 1 sont déjà pris, pour les autres faut faire en fonction des mods, le maximum est 100 je crois.



  • Désolé mais pour set l'ID je dois faire quoi ? Je suppose un int quelquechose mais je sais pas 😕


Log in to reply