Résolu Détection jour/nuit

ImperoMaximo

Aventurier
30 Juillet 2020
7
0
1
23
Bonjour,
j'ai commencé récemment un mod et je cherche a savoir s'il fait jour ou nuit au moment ou mon block se casse, de cette réponse en dépendras l'item drop (mon mod serais en rapport avec le soleil et la nuit voila pourquoi j'ai besoin de cela) , j'ai galéré pendant quelques heures et j'ai finalement trouvé un moyen, voici ce que j'ai mis dans la classe de mon bloc:
Code:
package fr.minecraftforgefrance.tutorial.blocks;

import fr.minecraftforgefrance.tutorial.items.TutorialItems;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.world.World;

public class SolariumOre extends Block
{   
    public World world;
    public boolean isDaytime() {
        return world.getSkylightSubtracted() < 4;
    }
   
    public SolariumOre(Material materialIn) {
        super(materialIn);
        this.setUnlocalizedName("minerais de solarium").setCreativeTab(CreativeTabs.BUILDING_BLOCKS).setHardness(6.0F).setResistance(20.0F);
        if(isDaytime() == true) Item.getIdFromItem(TutorialItems.SOLARIUM);
        else Item.getItemFromBlock(Blocks.DIAMOND_BLOCK);
   
    }   
}
donc jusqu'ici aucune erreur, voici le contenu de ma classe TutorialBlocks:
Code:
package fr.minecraftforgefrance.tutorial.blocks;

import fr.minecraftforgefrance.tutorial.ModTutorial;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

public class TutorialBlocks {
   
    public static final  Block SOLARIUMBLOCK = new IngotBlock(Material.IRON).setCreativeTab(CreativeTabs.BUILDING_BLOCKS).setHardness(6.0F).setResistance(20.0F).setUnlocalizedName("bloc_de_solarium");
    public static final  Block SOLARIUMORE = new SolariumOre(Material.IRON).setCreativeTab(CreativeTabs.BUILDING_BLOCKS).setHardness(6.0F).setResistance(20.0F).setUnlocalizedName("minerais_de_solarium");

   
    public static void registerBlocks() {
        GameRegistry.registerBlock(SOLARIUMBLOCK, "bloc_de_solarium");
        GameRegistry.registerBlock(SOLARIUMORE, "minerais_de_solarium");

    }
   
    @SideOnly(Side.CLIENT)
    public static void registerBlocksModels()
    {
        //ModelLoader.setCustomModelRessourceLocation(nomblockitem, , new ModelRessourceLocation(Modtutorial.modid + ":nomblock_blocks", "inventory"));
        ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(SOLARIUMBLOCK), 0, new ModelResourceLocation(ModTutorial.MODID + ":bloc_de_solarium", "inventory"));
        ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(SOLARIUMORE), 0, new ModelResourceLocation(ModTutorial.MODID + ":minerais_de_solarium", "inventory"));
    }

}
PS: ce n'est encore qu'un test pour le nom du block et le drop.
Mais voila, a chaque fois que je lance le jeu il me met une erreur, et lorsque j’enlève mon bloc de ma classe TutorialBlocks, l'erreur disparaît et mon mode fonctionne correctement, je ne sais plus quoi faire voir même si cela en deviens possible ou non, j’espère sincèrement que quelqu'un pourra me donner une réponse merci d'avance toute aide est la bienvenue.
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 131
162
462
247
21
Mìlhüsa
Bonjour,

Tout d'abord, la 1.7 est vieille de sept ans. La plupart des forums de modding ne font plus de support pour ces versions, tout simplement parce que l'API de Forge a énormément évoluée, et que celle-ci est désormais beaucoup plus « propre ».
En d'autres termes, si tu veux commencer le Java et le modding, commence avec la 1.12 ou la 1.16. Je ne vois vraiment aucune raison valable de continuer à jouer en 1.7.

Pour commenter ton code :

Java:
public class SolariumOre extends Block {
    // un 'Block' est la classe commune à TOUTES LES INSTANCES d'un bloc,
    // les blocs que tu poses sont des BlockStates.
    //
    // Le BlockState est au Block ce que l'Homme est à l'Humanité.
    // vouloir savoir dans quel monde est ton Block, c'est du même niveau
    // que de vouloir savoir sur quelle planète est l'Humanité.
    public World world;
    
    public boolean isDaytime() {
        // tu n'initialises jamais 'world'
        
        return world.getSkylightSubtracted() < 4;
        // l'appel d'une fonction d'une variable 'null' produit donc un NullPointerException
    }
   
    public SolariumOre(Material materialIn) {
        // 'materialIn' vaut toujours 'Material.IRON',
        // pas besoin de l'avoir en paramètre
        
        super(materialIn);
        
        // setUnlocalizedName: le nom doit être en anglais, sans espace, et en minuscules
        this.setUnlocalizedName("minerais de solarium").setCreativeTab(CreativeTabs.BUILDING_BLOCKS).setHardness(6.0F).setResistance(20.0F);
        
        // + tu appelles ces fonctions une deuxième fois dans 'TutorialBlocks',
        // elles n'ont donc aucun effet, puisque tu les réécris derrière
        
        // qu'est-ce ?
        // tu appelles une fonction, mais tu ne stocke le résultat nulle part
        // = le compilateur peut supprimer ces lignes, vu qu'elles ne font strictement rien
        if(isDaytime() == true) Item.getIdFromItem(TutorialItems.SOLARIUM);
        else Item.getItemFromBlock(Blocks.DIAMOND_BLOCK);
   
    }   
}

public class TutorialBlocks {
    // (avis personnel)
    // ce n'est pas à cette classe, qui répertorie tous tes blocs,
    // de définir ceux-ci [.setCreativeTab().setHardness()...]
    // déplace-les dans le constructeur
    // + dans ton cas, tu appelles ces fonctions plusieurs fois, donc
    //   'qui a le dernier mot', ça m'étonnerait que tu le saches.
    public static final  Block SOLARIUMBLOCK = new IngotBlock(Material.IRON).setCreativeTab(CreativeTabs.BUILDING_BLOCKS).setHardness(6.0F).setResistance(20.0F).setUnlocalizedName("bloc_de_solarium");
    public static final  Block SOLARIUMORE = new SolariumOre(Material.IRON).setCreativeTab(CreativeTabs.BUILDING_BLOCKS).setHardness(6.0F).setResistance(20.0F).setUnlocalizedName("minerais_de_solarium");

    public static void registerBlocks() {
        // idem, les IDs doivent être en anglais
        // + au lieu de réécrire l'ID, utilise Block#getUnlocalizedName,
        //   ça évitera de devoir changer l'ID à plusieurs endroits si tu veux le changer
        //   + ce sera moins sujet à l'erreur (« j'ai changé l'ID pourtant rien ne change »)
        GameRegistry.registerBlock(SOLARIUMBLOCK, "bloc_de_solarium");
        GameRegistry.registerBlock(SOLARIUMORE, "minerais_de_solarium");

    }
   
    @SideOnly(Side.CLIENT)
    public static void registerBlocksModels()
    // bon là soit tu mets les '{' sur la même ligne soit sur la suivante,
    // mais pas l'un ou l'autre de façon anarchique, tu dois rester cohérent
    {
        //ModelLoader.setCustomModelRessourceLocation(nomblockitem, , new ModelRessourceLocation(Modtutorial.modid + ":nomblock_blocks", "inventory"));
        ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(SOLARIUMBLOCK), 0, new ModelResourceLocation(ModTutorial.MODID + ":bloc_de_solarium", "inventory"));
        ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(SOLARIUMORE), 0, new ModelResourceLocation(ModTutorial.MODID + ":minerais_de_solarium", "inventory"));
    }

}

Ce que tu dois faire, c'est vérifier l'heure lorsque l'item se casse, et non lorsque tu le créés, typiquement en surchangeant une méthode.
Je n'ai ni la fonction ni le comment en tête, alors je te laisse chercher de ton côté. Je pourrais t'aider si tu décides de passer en 1.12.

Cordialement,
ShE3py.
 

ImperoMaximo

Aventurier
30 Juillet 2020
7
0
1
23
Bonsoir,
je code ce mod en 1.10.2, merci de m'expliquer tout cela car je débute dans le modding et d'après les tutos de minecraftforgefrance, il fallait répertorier les blocs dans TutorialBlocks, un petit truc me chiffonne, quand vous dites l'heure quand le bloc est cassé, ce n'est pas déjà le cas avec la méthode Item.getIdFromItem() ? cette fonction parle bien du drop du bloc de ce que j'ai compris, le soucis viendrais donc de la méthode utilisée pour savoir s'il faisait jour ou non, merci beaucoup pour ces conseils,
Une dernière chose, quand vous dites "le résultat n'est stocké nul part" vous voulez dire qu'il faut une variable pour cette méthode? (voir toutes les méthodes en général)
Merci encore et je vais me renseigner sur le moyen de connaitre l'heure du jeu et comment en déduire le moment de la journée,
cordialement,
ImperoMaximo.
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 131
162
462
247
21
Mìlhüsa
je code ce mod en 1.10.2
Autant pour moi, mais pourquoi ne pas prendre la 1.12 ou la 1.16 ?
La 1.12 est plus populaire, et l'API de Forge 1.16 est plus propre.

il fallait répertorier les blocs dans TutorialBlocks
Le principe de cette classe est de pouvoir accéder efficacement à un bloc, je disais juste que personnellement, cette classe ne doit qu'énumérer les blocs que ton mod rajoute, c'est à la classe du bloc en lui-même de se définir. Et comme dit, tu utilises deux fois Block#setUnlocalizedName(String), donc l'un devient superflu, cela peut induire en erreur puisque l'appel dans le constructeur n'a aucun effet, c'est l'appel dans TutorialBlocks qui a le dernier mot.

un petit truc me chiffonne, quand vous dites l'heure quand le bloc est cassé, ce n'est pas déjà le cas avec la méthode Item.getIdFromItem() ?
Item#getIdFromItem(Item) renvois l'identifiant numérique de l'item spécifié.
Item#getItemFromBlock(Block) renvois l'item qui correspond au bloc spécifié.

Ces fonctions renvoient des valeurs, que tu dois stocker :
Java:
int solariumId = Item.getIdFromItem(TutorialItems.SOLARIUM);
Item diamondBlockItem = Item.getItemFromBlock(Blocks.DIAMOND_BLOCK);

C'est à toi d'utiliser ensuite ces variables pour ce que tu veux faire. À aucun moment, tu donnes quelque chose.
Par analogie :
Code:
x = cos(90)
sin(90)

À aucun moment cela ne résoudra une équation. De plus, la deuxième ligne ne stocke pas le résultat. Libre à celui qui exécute les instructions de ne pas calculer le sinus, puisque cela n'a strictement aucun effet.


Ensuite, le but du constructeur est de construire l'objet, comme par exemple définir dans quel onglet créatif il se trouve.
Toi, tu regardes s'il fait jour, et tu cherches à donner un item. Le jeu n'a même pas encore atteint le menu principal.

Tu dois regarder s'il fait jour lorsqu'on te demande ce que le bloc drop. Pas lorsque tu le créé.
Je te montre comment faire en 1.15, je n'ai pas de MDK 1.10 installé :
Java:
public class DirunalOre extends Block {
   public DirunalOre() {
      super(
         Block.Properties.create(Material.ROCK)
                     .hardnessAndResistance(3f) // valeur de tous les minerais vanilla
      );
      
      this.setRegistryName("pospoppylickalick:dirunal_ore");
   }
   
   @Override
   public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
      ServerWorld world = builder.getWorld();
      
      if(world.isDaytime())
         return Collections.singletonList(new ItemStack(this));
      else
         return Collections.emptyList();
   }
   
   @Override
   public int getExpDrop(BlockState state, IWorldReader world, BlockPos pos, int fortune, int silktouch) {
      if(silktouch != 0 || !world.getDimension().isDaytime())
         return 0;
      
      // entre 3 et 7 xp (valeur du diamond et de l'émeraude)
      return MathHelper.nextInt(RANDOM, 3, 7);
   }
}

Le code devrait suivre la même idée en 1.10, par contre au lieu de copier/coller bêtement le code, écrit le nom de la fonction, ton IDE devrait te proposer d'override la méthode.
Cela te permettra d'avoir les bons paramètres si ceux-ci sont différents.

Une dernière chose, quand vous dites "le résultat n'est stocké nul part" vous voulez dire qu'il faut une variable pour cette méthode? (voir toutes les méthodes en général)
Cela dépend de la fonction. Si tu changes ta tapisserie, pas besoin de savoir quel motif a ta nouvelle tapisserie, tu le sais déjà.
Si tu demandes à ton voisin de quelle couleur est sa tapisserie, tu n'es pas obligé d'ouvrir son mail de réponse, mais ça n'a pas beaucoup de sens de ne pas le faire.
Dans ton cas, tu demandes quel est l'identifiant numérique de ton item. Si tu n'utilises pas ledit identifiant obtenu, la fonction n'a aucun effet.


N'hésite pas si tu as encore des questions.
 

ImperoMaximo

Aventurier
30 Juillet 2020
7
0
1
23
Bonjour,
Alors, j'ai écouté vos conseils comme j'ai pu et voici ce que cela donne pour ma classe de bloc:
Code:
package fr.minecraftforgefrance.tutorial.blocks;

import java.util.Random;

import fr.minecraftforgefrance.tutorial.items.TutorialItems;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.world.World;

public class SolariumOre extends Block
{    

    public SolariumOre(Material materialIn) {
        super(Material.IRON);
        this.setUnlocalizedName("minerais_de_solarium").setCreativeTab(CreativeTabs.BUILDING_BLOCKS).setHardness(3.0F).setResistance(3.0F);
        
    }    
    
    public int id;
        

    
    @Override
    public Item getItemDropped(IBlockState state, Random rand, int fortune) {
        World world = null;
        if(world.isDaytime() == true) id = Item.getIdFromItem(TutorialItems.ECLATDESOLARIUM);
        else id  = Item.getIdFromItem(TutorialItems.ECLATDELUNARIUM);
        return Item.getItemById(id);
    }
}
Lorsque je lance le jeu il continue de crash, et en essayant de trouver d'ou venait le problème, j'ai enlevé le ModelLoader.setCustomModelResourceLocation() et le jeu réussissais a se lancer comme cela, mais je n'obtenais rien en cassant le bloc, j'ai pourtant utilisé votre méthode getItemDropped en utilisant bien les ID comme vous me l'avez montré et rien ne change, il n'y aurais pas un autre moyen d'enregistrer les blocks models autrement que par la customlocation car ce dernier m'oblige a redonner le drop du bloc (j'ai essayé diverses manières telles que mettre la méthode dans la classe TutorialBlocks mais rien ne change), j'espère sincèrement que vous saurez m'aider, merci a vous de prendre le temps de répondre aux questions d'un débutant ;-)
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 131
162
462
247
21
Mìlhüsa
Java:
World world = null;
if(world.isDaytime() == true)
    // ...

Ta variable world sera toujours nulle, cela veut dire qu'elle n'a pas de valeur valide.
Tu demandes au programme s'il fait jour dans le monde. Quel monde ? Il n'en a aucune idée.
Résultat : un NullPointerException est throw, le jeu crash.

Maintenant le problème, c'est que la méthode getItemDropped ne propose aucun moyen de récupérer le monde dans lequel de bloc détruit se situe.
En d'autres termes : je ne sais pas comment faire en 1.10, ni même si cela est possible. C'est pour ça que je te demandais si tu avais une vraie raison d'utiliser la 1.10 au lieu de la 1.12/1.16.

Ensuite :
Java:
if(world.isDaytime() == true)
    id = Item.getIdFromItem(TutorialItems.ECLATDESOLARIUM);
else
    id  = Item.getIdFromItem(TutorialItems.ECLATDELUNARIUM);

return Item.getItemById(id);
  • Le champ d'application de ta variable id est trop large. Tu le fais appartenir à ta classe ; a-t-elle réellement besoin d'exister en dehors de cette fonction ?

  • Tu récupère l'identifiant numérique d'un item, puis à partir de ce même identifiant, tu récupères l'item. Pourquoi ne pas stocker directement cet item ?

  • Par convention, les noms doivent être en anglais. Pourquoi ? Parce que sinon, tu obtiens un mélange de deux langues et que jaWohl.getBar().faitÇa(), c'est pas très cohérent.

  • Utilise des tirets bas dans les noms de constantes pour les espaces : TutorialItems.SOLARIUM_SLIVER

Maintenant, un autre problème, c'est que tu ne sais pas vraiment programmer. Tu ne t'en sortiras pas en copiant/collant du code par-ci par-là.
La programmation est déjà un art, mais tu cherches à développer un jeu vidéo en même temps, qui apporte lui des concepts. Ces concepts se basent eux-mêmes sur des concepts de programmation, tu essayes d'apprendre les multiplications et les additions en même temps. Oui, c'est possible, mais pas forcément très instructif.

Pour apprendre la programmation, commence par un livre ou un cours introductif. Tu ne peux pas commencer directement en créant des mods. Si tu tiens à faire des trucs sur Minecraft, je pense que créer un plugin Bukkit/Spigot sera plus simple qu'un mod Forge. L'API est plus simple, et tu définis explicitement les points d'entrées.
Pour faire des multiplications, c'est mieux de comprendre les additions.
 

ImperoMaximo

Aventurier
30 Juillet 2020
7
0
1
23
Bonjour, désolé de répondre si tard,
Je sais que le modding est déjà un cran au-dessus de ce que j'avais déjà programmé (un petit jeu Mario), le soucis c'est que je suis borné (désolé) et j'aime beaucoup Minecraft donc y apporter des modifications c'est juste trop bien, je vous demande alors si c'est possible d’utiliser les méthodes de la classe World ou WorldInfo dans ma classe de bloc et si oui comment faire pour les utiliser sans leur donner une valeur null, et aussi comment enregistrer les Model dans le ModelLoader sans devoir mettre un autre drop.
En tout cas merci beaucoup a vous de m'avertir sur la difficulté du modding et de quand bien même me donner tout ces conseils,
Code:
Java:
public class SolariumOre extends Block
{   

    public SolariumOre(Material materialIn) {
        super(Material.IRON);
        this.setUnlocalizedName("solarium_ore").setCreativeTab(CreativeTabs.BUILDING_BLOCKS).setHardness(3.0F).setResistance(3.0F);

WorldInfo winfo;
        if(getWorldTime() > 1000) Item.getItemById(Item.getIdFromItem(TutorialItems.ECLATDESOLARIUM));
        else Item.getItemById(Item.getIdFromItem(TutorialItems.ECLATDELUNARIUM));
    }
La valeur de temps 1000 est un test et j'ai modifié la méthode getItemById() pour récupérer directement la valeur de getIdFromItem() comme vous me l'avez suggéré
 
Dernière édition:

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 131
162
462
247
21
Mìlhüsa
utiliser les méthodes de la classe World ou WorldInfo dans ma classe de bloc
Ce que tu dois bien comprendre, c'est que ta classe SolariumOre ne correspond à un bloc. Elle correspond à TOUS les blocks ayant pour nom « solarium_ore ».
Tu ne peux pas récupérer son monde, tout simplement parce qu'il peut en avoir une infinité comme aucun.
Le constructeur SolariumOre(Material materialIn) { ... } est appelé au chargement du jeu, le menu principal n'a même pas encore été affiché.

La fonction getItemDropped est appelée par le jeu lorsque celui-ci veut savoir quel item le bloc donnerait s'il était détruit. Et il ne semblerait pas qu'on puisse avoir les coordonnées ou le monde en question, du moins en 1.10. Je me répète : je ne sais pas si ce que tu veux faire est possible en 1.10.

Et sinon, Item.getItemById(int) renvoi l'Item associé à l'identifiant numérique spécifié.
Item.getIdFromItem(Item) renvoi l'identifiant numérique associé à l'item spécifié.

En d'autres termes :
Java:
Item.getItemById(Item.getIdFromItem(TutorialItems.ECLATDESOLARIUM)) == TutorialItems.ECLATDESOLARIUM
De la même manière que pour tout nombre réel x positif, (√x)² = x, ces deux fonctions s'annulent.

Et de plus, ton code ne fait strictement rien. Je ne sais pas si tu veux donner l'item au joueur ou définir l'item que le bloc donne, mais là ton code n'a aucun effet et peut être supprimé dans le .jar produit.

Mathématiquement, cela équivaudrait à :
C-like:
x;
if(f() > 1000) -(-a);
else -(-b);

winfo [x] est initialisé et inutilisé, getWorldTime() [f()] est potentiellement indéfini, les deux instructions après le if et le else ne font que des calculs, le résultat est inutilisé.

Je ne peux pas vraiment t'aider plus si tu ne sais pas programmer. Ce que tu fais n'a tellement pas de sens qu'il faudrait que je te réponde par un cours sur la programmation.
 

ImperoMaximo

Aventurier
30 Juillet 2020
7
0
1
23
Euh sinon vous ne connaîtriez pas un bon guide en java car j’étais sur openclassroom puis j'ai bifurqué sur des vidéos, et j'aimerais beaucoup mieux connaitre le java et surtout la façon de penser quand tu programme.