Generation d'une couche de pierre dans le sol



  • Yop,
    ayant évolué dans le modding et acquit des notions de java correctes ces derniers mois, je voulais me tenter à des choses plus complexe : mon objectif est en fait de transformer la génération des couches de MC afin de faire en sorte que la couche 0 à 12 soit d'un type de pierre (nommée trachyandesite) particulier, celle de 12 à 32 une autre (basalt), etc. jusqu'à 64.
    Actuellement sur MC, le sol est composé de stone, et je voulais remplacer cette dernière par mes pierres selon le modèle défini ci-dessus.
    J'ai donc fouillé dans les src les packages world.gen mais j'ai toujours un sérieux problème avec l'API, les fonctions pas traduites et le manque de commentaires me perdent complètement…
    J'ai pensé à m'inspirer du modèle que j'utilise pour la génération de mes minerais appelant le constructeur WorldGenMinable dans une méthode de génération afin de remplacer toutes les stones par un block précis sur une hauteur précise, puis ce block par un autre sur une hauteur plus basse, etc. , puis en faire de même pour la génération des minerais spécifique à ces couches, mais j'ai peur que cela ne soit pas réellement efficace...

    Je voulais savoir s'il y avait des moyens existants pour définir des couches dans Minecraft, ou si cette méthode que je propose semble la plus pratique ? (l'initialisation du monde serait vraiment longue je pense).
    J'ai malheureusement encore beaucoup à apprendre. 😕

    Merci d'avance pour vos conseils.
    Nox'



  • Coucou, alors ^^

    Si tu veux que ton truc soit pas trop laggy,  le mieux c'est de le faire lors de la création des chunks (Chunkprovider.java)
    Es tu sous forge, et est ce que tu souhaites généré ça dans le monde "normal" ou dans une autre dimension? (J'ai besoin de savoir ca pour t'aider davantage)

    Sinon si tu veux un truc laggy / dégueulasse:
    Tu crées un Worldgenerator qui est appelé à chaque chunks generés, et qui génère tes couches de roches:
    (J'ai pas de code sous les yeux, mais un truc du style:)
    (La également j'ai besoin de savoir si tu utilises forge ou non pour un code plus précis)

    void generate (World world, Random r, int x, int z)
    {
    for (int y = 4; y < 20; y++)
    {
    for (int i = 0; i < 16; i++)
    {
    for (int i = 0; i < 16; i++)
    {
    world.setBlock (x + i, y, z + j, trachyandesite);
    }
    }
    }
    
    }
    


  • J'utilise Forge et je parle bien du monde "normal". 🙂  Justement je voudrais utiliser un code qui ne génère pas trop de latence.
    pour ta troisième boucle, il faut plutôt utiliser j en variable entière, non ?



  • oui mais je te conseille comme a dis toss de faire un ChunkProvider sinon ca va lagger un truc de fou



  • Go chunkProvider, si tu arrive pas a créer tous, utilise l'asm et patch le chunkProvider (jamais tester de patch cette classe) et fait générer dans la fonction de génération.



    • le Chunkprovider est appelé en 1er (avant la generation des WorldGenerator (caves, stronghold, minerais etc…))
      Un IWorldGenerator est generé apres les WorldGenerator originaux (donc risque de generé par dessus)

    Recréer le ChunkProvider du monde est bien mieux, je te file un début 🙂

    /** c'est à mettre lors de l'initialisation de ton mod (aka CommonProxy)
            DimensionManager.unregisterProviderType(0);     //On retire le WorldProvider original du World (dimension 0)
    
            DimensionManager.registerProviderType(0, MonWorldProvider.class, true); //On enregistre ton custom WorldProvider, dimension 0
    
    

    MonWorldProvider héritera de la class WorldProvider, et contiendra obligatoirement ceci
    (afin que ce soit ton ChunkProvider custom qui soit appelé:))

    
        /** Retournes le ChunkProvider (objet qui genere les chunks uns à uns */
    
        public IChunkProvider createChunkGenerator()
        {
            return new ChunkGeneratorCustom(this.worldObj, this.worldObj.getSeed(), this.worldObj.getWorldInfo().isMapFeaturesEnabled(), 0);
        }
    
    

    ChunkProviderCustom implementera **IChunkProvider
    **(à moins que tu sois très chaud, je ne te conseille pas de refaire toutes la génération du monde, copies colles le contenu de ChunkProviderGenerate qui est la génération des chunk originaux, et supprimes / modifies ce qu'il te faut)

    EDIT: pour moi, la fonction général qui genere un chunk (dans ChunkProviderGenerate) est encore obfusqué et est sous la forme:

    
    /** Params:
    * x : coordonées X du chunk
    * z : coordonées Z du chunk
    * blocks: tableau contenant tous les blocks du chunk (blocks = new Block[16 * 16 * 256])
    */
    void func_147424_a(int x, int z, Block[] blocks);
    
    


  • Tu peux créer un world type aussi, sinon pour changer les chunk provider je te conseille plutôt :

    ​
    try
    
            {
                Field f = DimensionManager.class.getDeclaredField("providers");
                f.setAccessible(true);
    
                Hashtable providers = (Hashtable)f.get(null);
                providers.put(Integer.valueOf(1), WorldProviderHardcoreEnd.class);
                f.set(null, providers);
            }
            catch(NoSuchFieldException | IllegalArgumentException | IllegalAccessException e)
            {
                throw new RuntimeException("Could not override the DimensionManager providers!", e);
            }
    
    


  • Merci beaucoup pour tout vos conseils ! 🙂
    Je vais déjà essayer la technique que m'a donné Toss dès que j'en ai l'occasion, je suis pas mal occupé en ce moment, je suis désolé de laisser "trainer" ce sujet.