Problème de GUI
-
Ça ne fonctionnera jamais. Tu ne peux pas utiliser les interfaces de java pour un gui dans minecraft.
Si les gars de Forge sont parvenus à coder un système permettant d’automatiser la création de GUI c’est que c’est possible.
Franchement, comment pourrais-je faire autrement ? Vous avez bien vu la complexité du GUI, ça m’étonnerai que j’arriverai à reproduire ça dans Minecraft. De base, je sais coder en Java, pas en Minecraft ^^.
J’ai tenté de comprendre les codes de Minecraft, j’ai compris un certain nombre de choses mais les GUI, ça me dépasse de loin ^^.Ce que je veux faire c’est simplement un GUI vide (pour utiliser les méthodes de Forge et avoir la version Serveur et Client) et la fenêtre que j’ai programmé remplacera le “contenu” du GUI (boutons, fenêtre etc.).
Je demandais donc si je pouvais obtenir de l’aide sur les GUI car je n’ai pas compris la fonction de chaque élément du GUI, et comment ils sont liés entre eux. En ce qui concerne l’intégration du GUI et de ma fenêtre je m’en charge, ne vous inquiétez pas.
Voici ce que j’aimerais savoir :- Comment le bloc lance-t-il notre GUI ?
- Quelle est l’utilité d’un GUIHandler ?
- Comment créer un bloc ayant un GUI sans qu’il n’ait d’inventaire ? (Par exemple, dans RailCraft lors du clic sur un rail, ou BuildCraft lorsqu’on veut éditer un pipe)
Merci d’avance

-
1)C’est le joueur et non le bloc qui lance le gui en faisant un clic droit sur le bloc.
2)Le guiHandler fais le pont entre le tileEntity, et le gui du bloc.
3)Un livre n’a pas d’inventaire mais il a un gui.
Pour BuildCraft, regarde ici -
@‘Superloup10’:
1)C’est le joueur et non le bloc qui lance le gui en faisant un clic droit sur le bloc.
2)Le guiHandler fais le pont entre le tileEntity, et le gui du bloc.
3)Un livre n’a pas d’inventaire mais il a un gui.
Pour BuildCraft, regarde iciMerci ! Je vais voir le livre alors ! Le seul inconvénient c’est qu’il n’utilise pas Forge, donc c’est différent xD. Je te tiens au courant, si j’y arrive j’arrête de vous embêter.

-
Tiens, cadeau: ContainerPedia est l’interface du livre
GuiHandler
ContainerPedia -
@‘EclipseOnFire’:
Ça ne fonctionnera jamais. Tu ne peux pas utiliser les interfaces de java pour un gui dans minecraft.
Si les gars de Forge sont parvenus à coder un système permettant d’automatiser la création de GUI c’est que c’est possible.
Non, car la méthode qui ouvre une gui a besoin d’un objet extends Gui, or ta gui est extends JDialog.
@‘EclipseOnFire’:
Franchement, comment pourrais-je faire autrement ? Vous avez bien vu la complexité du GUI, ça m’étonnerai que j’arriverai à reproduire ça dans Minecraft. De base, je sais coder en Java, pas en Minecraft ^^.
J’ai tenté de comprendre les codes de Minecraft, j’ai compris un certain nombre de choses mais les GUI, ça me dépasse de loin ^^.Pourtant ça c’est possible, il suffit de voir ce que Kévin et moi avont fait sur Nanotech mod (je pense principalement au projecteur de lumière et de texte), les mods est open source : https://github.com/FFMT/nanotech_mod
Regarde aussi FFMT libs, il y a quelques classes que Nanotech mod utilise pour les sliders :
https://github.com/FFMT/FFMT-libs@‘EclipseOnFire’:
Ce que je veux faire c’est simplement un GUI vide (pour utiliser les méthodes de Forge et avoir la version Serveur et Client) et la fenêtre que j’ai programmé remplacera le “contenu” du GUI (boutons, fenêtre etc.).
Je demandais donc si je pouvais obtenir de l’aide sur les GUI car je n’ai pas compris la fonction de chaque élément du GUI, et comment ils sont liés entre eux. En ce qui concerne l’intégration du GUI et de ma fenêtre je m’en charge, ne vous inquiétez pas.
Voici ce que j’aimerais savoir :- Comment le bloc lance-t-il notre GUI ?
- Quelle est l’utilité d’un GUIHandler ?
- Comment créer un bloc ayant un GUI sans qu’il n’ait d’inventaire ? (Par exemple, dans RailCraft lors du clic sur un rail, ou BuildCraft lorsqu’on veut éditer un pipe)
Merci d’avance

Superloup a donné des bonnes explications, je tiens juste à ajouter que ce n’est pas parcequ’il n’y a pas de slot d’inventaire qu’il n’y a pas de container. Les tuyaux de buildcraft ont bien un container, preuve ici :
https://github.com/BuildCraft/BuildCraft/blob/nightly/common/buildcraft/transport/gui/ -
Bon voilà, j’ai tout recodé et mon système de fenêtre fonctionne. Il reste seulement deux problèmes :
- Ma fenêtre s’ouvre deux fois de suite (Je sais pas s’il faut check isRemote ou pas en fait)
- Ma TileEntity ne se sauvegarde pas (lorsque je quitte le monde et que je le charge, ma TileEntity perd ses paramètres…)
Si le problème vient de ma fenêtre, je recoderai en utilisant la méthode Minecraft mais comme je le gère pas je préfère éviter en fait.
Voici mes classes :
TileEntity.javapublic class TileEntitySoundBlock extends TileEntity{ private boolean loop = false; private String sound = "alarm.ogg"; private float volume = 1.0F; private int delay = 0; @Override public void readFromNBT(NBTTagCompound nbtTag){ super.readFromNBT(nbtTag); nbtTag.setBoolean("Loop",this.loop); nbtTag.setString("Sound",this.sound); nbtTag.setFloat("Volume",this.volume); nbtTag.setInteger("Delay",this.delay); } @Override public void writeToNBT(NBTTagCompound nbtTag){ super.writeToNBT(nbtTag); this.loop = nbtTag.getBoolean("Loop"); this.sound = nbtTag.getString("Sound"); this.volume = nbtTag.getFloat("Volume"); this.delay = nbtTag.getInteger("Delay"); } public void setVolume(float volume){ this.volume = volume; } public float getVolume(){ return this.volume; } public void setDelay(int delay){ this.delay = delay; } public int getDelay(){ return this.delay; } public void setSound(String sound){ System.out.println("setSound = " + sound); this.sound = sound; } public String getSound(){ System.out.println("getSound = " + this.sound); return this.sound; } public String getSoundToPlay(){ return "wsmod:" + this.sound; } public void setIsLoop(boolean loop){ this.loop = loop; } public boolean getIsLoop(){ return this.loop; } }GuiHandlerSoundBlock.java
public class GuiHandlerSoundBlock implements IGuiHandler{ @Override public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z){ TileEntity te = world.getBlockTileEntity(x, y, z); if(te instanceof TileEntitySoundBlock){ return new ContainerSoundBlock(player.inventory, (TileEntitySoundBlock)te); } return null; } @Override public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { TileEntity te = world.getBlockTileEntity(x, y, z); if(te instanceof TileEntitySoundBlock){ return new GuiSoundBlock(player.inventory, (TileEntitySoundBlock)te); } return null; } }GuiSoundBlock.java
public class GuiSoundBlock extends GuiContainer{ private TileEntitySoundBlock soundBlock; public GuiSoundBlock(InventoryPlayer inventory, TileEntitySoundBlock tileEntity){ super(new ContainerSoundBlock(inventory, tileEntity)); this.soundBlock = tileEntity; this.ySize = 230; } @SideOnly(Side.CLIENT) @Override protected void drawGuiContainerForegroundLayer(int par1, int par2){ new SoundBlockDialog(soundBlock); } @Override protected void drawGuiContainerBackgroundLayer(float f, int i, int j){} }Merci d’avance ! (Désolé d’être aussi têtu mais je gère vraiment pas les GUI Minecraft donc je ne l’utiliserai qu’en dernier recours)
-
Pour les variables, il faut les synchroniser à l’aide de paquet.
Une fois de plus, regarde nanotech mod, le smoker, le jumper ou le projecteur.Il y a également ça pour les paquets :
http://www.minecraftforgefrance.fr/showthread.php?tid=391&pid=4167#pid4167 -
En lisant ton Smoker.java, j’ai vu que tu as laissé le “player.isSneaking” alors que Forge gère cet élément, c’est écrit dans ton tuto

-
Oui, il y a encore beaucoup de résidu de vieux code qui date du début de nanotech mod, je vais profiter de la 1.7 pour faire un gros nettoyage.
-
@‘robin4002’:
Oui, il y a encore beaucoup de résidu de vieux code qui date du début de nanotech mod, je vais profiter de la 1.7 pour faire un gros nettoyage.
Perso quand ça m’embête d’avoir de vieux trucs et des erreurs dans mon code, je m’énerve et je recode tout xD (c’est pas productif mais c’est efficace
).Bref, j’ai réussi à faire un packet mais je sais vraiment pas quoi mettre dedans ^^.
Mon PacketHandler.javapublic class PacketHandler implements IPacketHandler{ @Override public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player){ EntityPlayer playerSender = (EntityPlayer)player; if(packet.channel.equals("wsmod|soundBlock")){ handleSoundBlockPacket(packet, playerSender); } } private void handleSoundBlockPacket(Packet250CustomPayload packet, EntityPlayer player){ try{ DataInputStream data = new DataInputStream(new ByteArrayInputStream(packet.data)); //Je met quoi ici ? :P }catch(Exception e){ e.printStackTrace(); } } }TileEntitySoundBlock.java (je met que la partie modifiée hein)
public Packet getDescriptionPacket(){ NBTTagCompound nbttagcompound = new NBTTagCompound(); this.writeToNBT(nbttagcompound); return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 4, nbttagcompound); } @Override public void onDataPacket(INetworkManager net, Packet132TileEntityData pkt){ this.readFromNBT(pkt.data); }Pour la partie “actionPerformed” je sais pas quoi mettre non plus.
Merci d’avance !
-
actionPerformed = un switch avec l’id du bouton en param, et dans le case id: tu mets ton code a effectuer
-
@‘Gugu42’:
actionPerformed = un switch avec l’id du bouton en param, et dans le case id: tu mets ton code a effectuer
Non, ça d’accord ! Je veux dire le code pour les packets.
-
Dans ton gui, tu remplace :
tileEntity.setIsLoop(loopCheckBox.isSelected()); tileEntity.setSound((String)soundChooser.getSelectedItem()); tileEntity.setDelay((int)delayChooser.getValue()); tileEntity.setVolume((float)volumeChooser.getValue()/100);Par :
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream(); DataOutputStream dataoutputstream = new DataOutputStream(bytearrayoutputstream); try { dataoutputstream.writeBoolean(loopCheckBox.isSelected()); dataoutputstream.writeString((String)soundChooser.getSelectedItem()); dataoutputstream.writeInt((int)delayChooser.getValue()); dataoutputstream.writeFloat((float)volumeChooser.getValue()/100)); this.mc.getNetHandler().addToSendQueue(new Packet250CustomPayload("wsmod|soundBlock", bytearrayoutputstream.toByteArray())); } catch(Exception exception) { exception.printStackTrace(); }Et dans ton //Je mets quoi la
tu mets :boolean isLoop = data.readBoolean(); String sound = data.readString(); int delay = data.readInt(); float volume = data.readFloat(); ContainerSoundBlock container = (ContainerSoundBlock)player.openContainer; TileEntitySoundBlock tileSoundBlock = container.getSoundBlockTile(); tileSoundBlock.setIsLoop(isLoop); tileSoundBlock.setSound(sound); tileSoundBlock.setDelay(delay); tileSoundBlock.setVolume(volume); player.worldObj.markBlockForUpdate(tileSoundBlock.xCoord, tileSoundBlock.yCoord, tileSoundBlock.zCoord);Et normalement devrait être bon. Si ça fonctionne pas, c’est qu’il n’aime pas la gui java (d’ailleurs, elle s’affiche comment en jeu ? j’aimerai bien voir ça). Ou alors que le nom du chanel est trop long, ou que tu ne l’a pas enregistré dans la classe principale. (Dans le @NetworkMod il faut mettre la classe du packet handler et les chanel utilisés)
-
@‘robin4002’:
dataoutputstream.writeString((String)soundChooser.getSelectedItem());Cette méthode n’existe pas O_o. Ya writeUTF(String s) ou writeChars(String s). Je vais tenter le writeUTF…
-
UTF oui, sinon tente le char. J’ai donné les codes de tête, je ne les connais pas tous par cœurs.
-
@‘robin4002’:
UTF oui, sinon tente le char. J’ai donné les codes de tête, je ne les connais pas tous par cœurs.
Ouais j’ai dû changer le readUTF() de l’autre côté, ça à l’air de marcher. J’ai juste un souci de cast au niveau du
(ContainerSoundBlock)player.openContainer; -
Importe ton container, si tu en a pas il faut en créer un.
-
Nan c’est un problème de cast, pas d’import (ClassCastException). J’ai dû gaffer quelque part en suivant le tuto je pense…
public class ContainerSoundBlock extends Container{ private TileEntitySoundBlock tileEntity; public ContainerSoundBlock(InventoryPlayer playerInventory, TileEntitySoundBlock teChest){ this.tileEntity = teChest; } @Override public boolean canInteractWith(EntityPlayer player){ return true; } public TileEntitySoundBlock getSoundBlockTile() { return tileEntity; } }En parlant d’imports, vu que ça arrive souvent (j’ai pu le constater :P), je conseille vivement (pour ceux qui ne le savent pas) d’utiliser Ctrl + Shift + O ça génère les imports nécéssaires, supprime ceux qui ne sont pas utilisés et les organise automatiquement (tellement plus simple ^^).
-
La classe est bonne, envoie le crash report et ton guiHandler
-
@‘robin4002’:
La classe est bonne, envoie le crash report et ton guiHandler
Ca roule !
Voilà le stackTrace :
java.lang.ClassCastException: net.minecraft.inventory.ContainerPlayer cannot be cast to fr.wsmod.ContainerSoundBlock 2014-01-12 15:33:58 [Infos] [STDERR] at fr.wsmod.PacketHandler.handleSoundBlockPacket(PacketHandler.java:29) 2014-01-12 15:33:58 [Infos] [STDERR] at fr.wsmod.PacketHandler.onPacketData(PacketHandler.java:18) 2014-01-12 15:33:58 [Infos] [STDERR] at cpw.mods.fml.common.network.NetworkRegistry.handlePacket(NetworkRegistry.java:255) 2014-01-12 15:33:58 [Infos] [STDERR] at cpw.mods.fml.common.network.NetworkRegistry.handleCustomPacket(NetworkRegistry.java:245) 2014-01-12 15:33:58 [Infos] [STDERR] at cpw.mods.fml.common.network.FMLNetworkHandler.handlePacket250Packet(FMLNetworkHandler.java:85) 2014-01-12 15:33:58 [Infos] [STDERR] at net.minecraft.network.NetServerHandler.handleCustomPayload(NetServerHandler.java:1130) 2014-01-12 15:33:58 [Infos] [STDERR] at net.minecraft.network.packet.Packet250CustomPayload.processPacket(Packet250CustomPayload.java:70) 2014-01-12 15:33:58 [Infos] [STDERR] at net.minecraft.network.MemoryConnection.processReadPackets(MemoryConnection.java:89) 2014-01-12 15:33:58 [Infos] [STDERR] at net.minecraft.network.NetServerHandler.networkTick(NetServerHandler.java:141) 2014-01-12 15:33:58 [Infos] [STDERR] at net.minecraft.network.NetworkListenThread.networkTick(NetworkListenThread.java:54) 2014-01-12 15:33:58 [Infos] [STDERR] at net.minecraft.server.integrated.IntegratedServerListenThread.networkTick(IntegratedServerListenThread.java:109) 2014-01-12 15:33:58 [Infos] [STDERR] at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:691) 2014-01-12 15:33:58 [Infos] [STDERR] at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:587) 2014-01-12 15:33:58 [Infos] [STDERR] at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:129) 2014-01-12 15:33:58 [Infos] [STDERR] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:484) 2014-01-12 15:33:58 [Infos] [STDERR] at net.minecraft.server.ThreadMinecraftServer.run(ThreadMinecraftServer.java:16)GuiHandler.java
public class GuiHandlerSoundBlock implements IGuiHandler{ @Override public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z){ TileEntity te = world.getBlockTileEntity(x, y, z); if(te instanceof TileEntitySoundBlock){ return new ContainerSoundBlock(player.inventory, (TileEntitySoundBlock)te); } return null; } @Override public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { TileEntity te = world.getBlockTileEntity(x, y, z); if(te instanceof TileEntitySoundBlock){ return new GuiSoundBlock(player.inventory, (TileEntitySoundBlock)te); } return null; } }
