Résolu Faire spawn un block ou une structure
-
Salut
J’ai un problème pour faire spawner mon block (une citrouille). J’ai cherché ici, sur le site officiel, dans la classe WorldGenerator et dans les codes de Minecraft, mais rien ne peut m’aider.Voilà ma classe :
[size=small**package**] This_is_Halloween.Generation; [size=small**import**] java.util.Random; [size=small**import**] net.minecraft.block.Block; [size=small**import**] net.minecraft.block.material.Material; [size=small**import**] net.minecraft.block.state.IBlockState; [size=small**import**] net.minecraft.init.Blocks; [size=small**import**] net.minecraft.util.BlockPos; [size=small**import**] net.minecraft.world.World; [size=small**import**] net.minecraft.world.gen.feature.WorldGenerator; [size=small**public**] **[size=smallclass]** WorldGenPumpkinLantern **[size=smallextends]** WorldGenerator { [size=small@Override] **[size=smallpublic]** **[size=smallboolean]** generate(World [size=smallworld], Random [size=smallrandom], BlockPos [size=smallpos]) { **[size=smallfor]**(**[size=smallint]** [size=smallx] = [size=smallpos].getX(); [size=smallx] == [size=smallpos].getX();) { **[size=smallfor]**(**[size=smallint]** [size=smally] = [size=smallpos].getY(); [size=smally] == [size=smallpos].getY();) { **[size=smallfor]**(**[size=smallint]** [size=smallz] = [size=smallpos].getZ(); [size=smallz] == [size=smallpos].getZ();) { **[size=smallboolean]** [size=smallisAir] = [size=smallworld].isAirBlock(**[size=smallnew]** BlockPos([size=smallx], [size=smally], [size=smallz])); **[size=smallif]**(([size=smallworld].getBlockState(**[size=smallnew]** BlockPos([size=smallx], [size=smally] - 1, [size=smallz])) == Blocks.***[size=smallgrass]*** && [size=smallisAir])) { System.***[size=smallout]***.println([size=small"CITROUILLE"]); [size=smallworld].setBlockState(**[size=smallnew]** BlockPos([size=smallx], [size=smally], [size=smallz]), Blocks.***[size=smalllit_pumpkin]***.getDefaultState()); **[size=smallreturn]** **[size=smalltrue]**; } **[size=smallelse]** { System.***[size=smallout]***.println([size=small"pas citrouille"]); **[size=smallreturn]** **[size=smallfalse]**; } } **[size=smallreturn]** **[size=smallfalse]**; } **[size=smallreturn]** **[size=smallfalse]**; } **[size=smallreturn]** **[size=smallfalse]**; } }
Je sais que le problème vient de la condition, mais je ne sais pas où dedans. Je pense que c’est le BlockPos, mais pas sûr.
La classe est appelé dans :
package This_is_Halloween.Generation; import java.util.Random; import net.minecraft.util.BlockPos; import net.minecraft.world.World; import net.minecraft.world.chunk.IChunkProvider; import net.minecraftforge.fml.common.IWorldGenerator; public class AddPumpkinLanternInBiome implements IWorldGenerator { @Override public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) { switch(world.provider.getDimensionId()) { case 0: generateSurface(world, random, chunkX * 16, chunkZ * 16); } } private void generateSurface(World world, Random rand, int x, int z) { for(int i = 0; i < 10; i ++) { int randPosX = x + rand.nextInt(16); int randPosY = rand.nextInt(128); int randPosZ = z + rand.nextInt(16); (new WorldGenPumpkinLantern()).generate(world, rand, new BlockPos(randPosX, randPosY, randPosZ)); } } }
qui est enregistré par :
GameRegistry.*registerWorldGenerator*(**%(#7f0055)[[size=small]new]** AddPumpkinLanternInBiome(), 0);
dans la fonction init de la classe principale.
Pas d’erreur dans Eclipse, ni dans les logs. Dans les logs, ca ne marque seulement que
[Server thread/INFO] [STDOUT]: [This_is_Halloween.Generation.WorldGenPumpkinLantern:generate:38]: pas citrouille
ce que j’ai demandé d’afficher si le block ne spawn pas.
Comment résoudre et faire spawn ce block ?
Merci d’avance -
Renvoi la classe du générateur en désactivant les smileys, et indenté si possible
-
La voilà :
package This_is_Halloween.Generation; import java.util.Random; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenerator; public class WorldGenPumpkinLantern extends WorldGenerator { @Override public boolean generate(World world, Random random, BlockPos pos) { for(int x = pos.getX(); x == pos.getX();) { for(int y = pos.getY(); y == pos.getY();) { for(int z = pos.getZ(); z == pos.getZ();) { boolean isAir = world.isAirBlock(new BlockPos(x, y, z)); if((world.getBlockState(new BlockPos(x, y - 1, z)) == Blocks.grass && isAir)) { System.out.println("CITROUILLE"); world.setBlockState(new BlockPos(x, y, z), Blocks.lit_pumpkin.getDefaultState()); return true; } else { System.out.println("pas citrouille"); return false; } } return false; } return false; } return false; } }
-
Ne mettez pas les codes java dans des spoiler, c’est plus chiant qu’autre chose. La balise java ajoute déjà un scroller si c’est trop long.
for(int x = pos.getX(); x == pos.getX(); ){
for(int y = pos.getY(); y == pos.getY(); ){
for(int z = pos.getZ(); z == pos.getZ(); )???
il manquerai pas x ++, y ++ etc … ?
En fait non, ces boucles for ne devrait même pas être là x)
Je ferai plutôt une for qui commence à y et qui augmente y jusqu’à trouver de l’aire et de l’herbe. Ensuite tu poses le bloc et tu break. -
1. **package** This_is_Halloween.Generation; 2. **import** java.util.Random; 3. **import** net.minecraft.block.Block; 4. **import** net.minecraft.block.material.Material; 5. **import** net.minecraft.block.state.IBlockState; 6. **import** net.minecraft.init.Blocks; 7. **import** net.minecraft.util.BlockPos; 8. **import** net.minecraft.world.World; 9. **import** net.minecraft.world.gen.feature.WorldGenerator; 10. **public** **class** WorldGenPumpkinLantern **extends** WorldGenerator 11. { 12. @Override 13. **public** **boolean** generate(World world, Random random, BlockPos pos) 14. { 15. **for**(**int** x = pos.getX(); x == pos.getX();) // Ici tu incrémentes pas la variable, donc boucle infinie 16. { 17. **for**(**int** y = pos.getY(); y == pos.getY();) // même cchose 18. { 19. **for**(**int** z = pos.getZ(); z == pos.getZ();) // et encore la même chose 20. { 21. **boolean** isAir = world.isAirBlock(**new** BlockPos(x, y, z)); 22. **if**((world.getBlockState(**new** BlockPos(x, y - 1, z)) == Blocks.grass && isAir)) // Tu regardes si le bloc correspond 23. { 24. System.**out**.println("CITROUILLE"); 25. world.setBlockState(**new** BlockPos(x, y, z), Blocks.lit_pumpkin.getDefaultState()); // Si oui, tu pose le bloc 26. **return** **true**; // et tu quittes la fonction 27. } 28. **else** 29. { 30. System.**out**.println("pas citrouille"); 31. **return** **false**; // Sinon tu quittes la fonction, donc dans tous les cas ta boucle ne sert à rien 32. } 33. } 34. **return** **false**; 35. } 36. **return** **false**; 37. } 38. **return** **false**; // Pourquoi y'a 3 return à la suite ? un seul à la fin suffit 39. } 40. }
Voilà le code commenté car je crois que tu n’as pas compris ton code
-
Je ferai plutôt une for qui commence à y et qui augmente y jusqu’à trouver de l’aire et de l’herbe. Ensuite tu poses le bloc et tu break
Je n’ai pas vraiment compris.
Sinon, je vais expliquer pourquoi j’ai mis ce code et comment je l’ai interprété :
A l’époque de la 1.7, le code était comme ça et marchait :
package This_is_Halloween.Generation; import java.util.Random; import net.minecraft.init.Blocks; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenerator; public class WorldGenPumpkinLantern extends WorldGenerator { @Override public boolean generate(World world, Random random, int x, int y, int z) { boolean isAir = world.isAirBlock(x, y , z); if((world.getBlock(x, y - 1, z) == Blocks.grass && isAir)|| (world.getBlock(x, y - 1, z) == Blocks.dirt && isAir)||(world.getBlock(x, y - 1, z) == Blocks.sand && isAir)||(world.getBlock(x, y - 1, z) == Blocks.stone && isAir)||(world.getBlock(x, y - 1, z) == Blocks.snow && isAir)||(world.getBlock(x, y - 1, z) == Blocks.monster_egg && isAir)||(world.getBlock(x, y - 1, z) == Blocks.cobblestone && isAir)|| (world.getBlock(x, y - 1, z) == Blocks.gravel && isAir)||(world.getBlock(x, y - 1, z) == Blocks.ice && isAir)||(world.getBlock(x, y - 1, z) == Blocks.mycelium && isAir)||(world.getBlock(x, y - 1, z) == Blocks.obsidian && isAir)||(world.getBlock(x, y - 1, z) == Blocks.sandstone && isAir)||(world.getBlock(x, y - 1, z) == Blocks.stonebrick && isAir)||(world.getBlock(x, y - 1, z) == Blocks.monster_egg && isAir)|| (world.getBlock(x, y - 1, z) == Blocks.end_stone && isAir)|| (world.getBlock(x, y - 1, z) == Blocks.netherrack && isAir)) { world.setBlock(x, y, z, Blocks.lit_pumpkin, 4, 2); return true; } else { return false; } } }
Au passage à la 1.8, ça me demandait d’enelever l’Override et de mettre les méthodes non-implémentées (un autre generate, mais à la place de int x, int y, int z mettre BlockPos pos)
J’ai donc modifié la première méthode en remplaçant par BlockPos pos. Mais à l’intérieur de la méthode, les x, y et z n’étaient plus initialisées. J’ai donc passer des jours à réfléchir comment je pourrais faire (j’ai en parralèlle continuer le reste du mod).
j’ai finalement trouvé, et j’ai mis ça : (mon interprétation sera en commentaire)package This_is_Halloween.Generation; import java.util.Random; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenerator; public class WorldGenPumpkinLantern extends WorldGenerator { @Override public boolean generate(World world, Random random, BlockPos pos) { for(int x = pos.getX(); x == pos.getX();) //comme le x n'était plus initialisée, je l'ai fait comme ça. Au départ, je comprenait : pour x égale à la postion x qui est égale à x (donc à la postion x (j'étais obligé de faire comme ça, sion erreur)) { for(int y = pos.getY(); y == pos.getY();) //pareil { for(int z = pos.getZ(); z == pos.getZ();) //pareil { boolean isAir = world.isAirBlock(new BlockPos(x, y, z)); if((world.getBlockState(new BlockPos(x, y - 1, z)) == Blocks.grass && isAir)) //Ca vérifie si le block à la position était le block "énoncé" (ici de l'herbe) (j'ai enlevé presque tout les blocks par rapport à la 1.7, je les remettrais quand ça remarchera { System.out.println("CITROUILLE"); world.setBlockState(new BlockPos(x, y, z), Blocks.lit_pumpkin.getDefaultState()); //Si la condition est vérifié, ça fait spawner une citrouille aux coordonnées données (ici, juste au-dessus de l'herbe). Sinon, ça ne fait rien return true; } else { System.out.println("pas citrouille"); return false; } } return false; //Je pensait qu'il faillait mettre un return pour chaque for. } return false;//Pareil } return false;//Pareil + c'est le return de la méthode } }
Moi, j’ai compris comme ça. Mais a ce que j’ai lue au dessus, j’ai mal interprétées certaines choses, nottemment les for.
EDIT : J’ai trouvé, ça remarche. Il suffit d’ajouter (IBlockState) avant le block à vérifier dans la condition et .getDefaultState après. Voilà la classe :
package This_is_Halloween.Generation; import java.util.Random; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenerator; public class WorldGenPumpkinLantern extends WorldGenerator { @Override public boolean generate(World world, Random random, BlockPos pos) { boolean isAir = world.isAirBlock(new BlockPos(pos.getX(), pos.getY(), pos.getZ())); if((world.getBlockState(new BlockPos(pos.getX(), pos.getY() - 1, pos.getZ())) == (IBlockState) Blocks.grass.getDefaultState() && isAir)) { System.out.println("CITROUILLE"); world.setBlockState(new BlockPos(pos.getX(), pos.getY(), pos.getZ()), Blocks.lit_pumpkin.getDefaultState()); return true; } else { System.out.println("pas citrouille"); return false; } } }
(ligne 23 la modif)