Dans ce tutoriels nous allons voir comment générer des blocs dans un monde, de la même façon qu’un minerai.
Pre-requis
Dans la classe principale
Dans la méthode init(FMLInitializationEvent) enregistrer votre WorldGenerator à l’aide de la fonction suivante :
GameRegistry.registerWorldGenerator(new WorldGeneratorTutoriel());
Ensuite créez la classe WorldGeneratorTutoriel.
La classe du générateur
Votre classe devrait ressembler à ça :
package tutoriel.common;
import cpw.mods.fml.common.IWorldGenerator;
public class WorldGeneratorTutoriel implements IWorldGenerator
{
@Override
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider)
{
}
}
Nous allons ajouter un switch par rapport à l’id de la dimension du monde, et faire 3 fonction différentes :
switch(world.provider.dimensionId)
{
case -1:
this.generateNether(world, chunkX * 16, chunkZ * 16, random);
break;
case 0:
this.generateSurface(world, chunkX * 16, chunkZ * 16, random);
break;
case 1:
this.generateEnd(world, chunkX * 16, chunkZ * 16, random);
break;
}
Vous n’êtes pas obligés de mettre les trois fonction, si vous souhaitez juste générer quelque chose dans le monde normal, mettez juste la case 0. Si vous avez des dimensions customs, ajoutez les cases supplémentaires.
Une fois les fonctions créées, vous devrez avoir ceci :
@Override
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider)
{
switch(world.provider.dimensionId)
{
case -1:
this.generateNether(world, chunkX * 16, chunkZ * 16, random);
break;
case 0:
this.generateSurface(world, chunkX * 16, chunkZ * 16, random);
break;
case 1:
this.generateEnd(world, chunkX * 16, chunkZ * 16, random);
break;
}
}
private void generateSurface(World world, int x, int z, Random rand)
{
}
private void generateEnd(World world, int x, int z, Random rand)
{
}
private void generateNether(World world, int x, int z, Random rand)
{
}
Pour générer un minerai, ajoutez les lignes suivantes dans la fonction du monde correspondant :
for(int i = 0; i < probabilité; i++)
{
(new WorldGenMinable(id du bloc à générer, metadata du bloc à générer, taille maximum d un filon, id du bloc qui va être remplacé)).generate(world, rand, x + rand.nextInt(16), rand.nextInt(hauteur maximum), z + rand.nextInt(16));
}
- probabilité : un int, pour donner un ordre de grandeur, le diamant est à 1 (enlever la boucle for revient au même que mettre 1), l’or est à 2, la redstone à 8, le gravier à 10, et le charbon, le fer et la terre à 20.
- id du bloc à générer : classePrincipale.monBloc.blockID par exemple.
- metadata du bloc à générer : je pense pas qu’il y est besoin d’explication
- taille maximum d’un filon : par combien votre minerai va se générer au maximum.
- id du bloc qui va être remplacé : sur quoi le bloc peu se générer. Par exemple Block.stone.blockID. Pour la génération dans le nether, il faut utiliser Block.netherrack.blockID ou Block.slowSand.blockID pour générer sur la soulsand. Pour l’end, Block.whiteStone.blockID pour l’end.
- hauteur maximum : la hauteur maximum où votre minerai peu se générer (diamant = 16, or = 32, fer = 64, charbon, terre et gravier = 128
Pour ceux qui se poseraient la question “Pourquoi rand.nextInt(16) et pas autres choses”
-> Car un chuck contient 16x16 blocs, avec des valeurs plus petites les minerais ne pourraient que se générer sur une parti du chunk, et avec des valeurs plus grande, ils pourraient se générer sur les chunks qui sont à côté. C’est d’ailleurs pour ça que cette valeur peut aussi jouer sur la probabilité de la génération du minerai.
Petit rappel, la fonction nextInt(int) dans Random donne au hasard un nombre entre 0 et la valeur donnée. Vous pouvez par exemple mettre “16 + rand.nextInt(16)” pour générer votre minerai entre le niveau 16 et 32.
Vous pouvez également utiliser des conditions pour faire apparaitre vos minerais uniquement dans certains biomes.
if(world.getBiomeGenForCoords(x, z).equals(BiomeGenBase.field_du_biome))
{
//Code de génération
}
La génération de votre minerai devrait fonctionner.
Quelques exemples
private void generateSurface(World world, int x, int z, Random rand)
{
for(int i = 0; i < 2; i++)
{
(new WorldGenMinable(ModTutoriel.TutorialMetadata.blockID, 0, 4, Block.stone.blockID)).generate(world, rand, x + rand.nextInt(16), rand.nextInt(32), z + rand.nextInt(16));
}
if(world.getBiomeGenForCoords(x, z).equals(BiomeGenBase.extremeHills))
{
for(int i = 0; i < 8; i++)
{
(new WorldGenMinable(ModTutoriel.TutorialMetadata.blockID, 5, 12, Block.stone.blockID)).generate(world, rand, x + rand.nextInt(16), 16 + rand.nextInt(32), z + rand.nextInt(16));
}
}
}
Ici, mon bloc métadata tutoriel de metadata 0 se génère dans le monde normal, par filon de 4 au maximum sur la pierre entre le niveau (coordonnée y) 0 et 32 et se probabilité est aussi faible de l’or. Mon bloc métadata tutoriel de metadata 5 se génère dans le monde normal et uniquement dans les extreme hills (et pas dans les extreme hills edge, par filon de 12 au maximum sur la pierre entre le niveau (coordonnée y) 16 et 48 et il est aussi fréquent que la redstone.
Questions / Réponses
Q: Le tuto est pour la 1.6.2 ou la 1.6.4 ?
R: Les deux, le changement dans la génération ne concerne que les StructureComponent, pas les WorldGenerator.