Résolu Autre problème avec mon effet
-
Salut
J’ai encore un autre problème avec mon mod.
J’ai créé un effet que le joueur obtient à un nombre random quand il se lève et qu’il neige. Pour la neige, j’ai dû passé par un timer. Ca marchait bien, mais le seul inconvénient, c’est que quand on quitte le lit sans qu’il fasse jour (donc échap ou le bouton leave bed), le joueur l’obtient quand même. J’ai donc rajouté une condition, s’il fait jour. Mais, là je comprend pas tout. Déjà, voilà le code :System.out.println(event.getEntityPlayer().worldObj.isDaytime()); if(event.getEntityPlayer().worldObj.isDaytime()) { System.out.println("appelé"); MagicOfChristmasEffect(event.getEntityPlayer()); System.out.println("effet appliqué"); timer = 0; System.out.println("neige"); TextComponentTranslation test = new TextComponentTranslation("test"); event.getEntityPlayer().addChatMessage(test); }
Que le joueur quitte le lit quand il fait encore nuit ou qu’il attende le jour, il obtient la même chose de la part des logs :
false true [15:57:06] [Client thread/INFO] [STDOUT]: [This_is_Christmas.CommonEventHandler:MagicOfChristmasEffectActivator:74]: appelé [15:57:06] [Client thread/INFO] [STDOUT]: [This_is_Christmas.CommonEventHandler:MagicOfChristmasEffectActivator:76]: effet appliqué [15:57:06] [Client thread/INFO] [STDOUT]: [This_is_Christmas.CommonEventHandler:MagicOfChristmasEffectActivator:78]: neige [15:57:06] [Client thread/INFO]: [CHAT] test
Mais en jeu, rien à part le message test. Je ne comprend pas deux choses dans les logs : qu’il fasse nuit ou jour quand il quitte le lit, ça dit qu’il fait nuit et jour en même temps. Et pourquoi ça affiche bien les messages si ça appelle pas la fonction ? Pourtant, si vous regardez le code java, vous pouvez voir que j’ai mis un message avant et trois message après l’appel de la fonction. Tous s’affiche mais la fonction ne marche pas. Alors que dans cette dernière, y’a aucune condition : ```java
public void MagicOfChristmasEffect(EntityPlayer player)
{
ChristmasPotion potion = ChristmasPotion.MagicOfChristmasEffect;
PotionEffect potioneffect = new PotionEffect(potion, 12536, 0, false, true);
TextComponentTranslation textcomponenttranslation = new TextComponentTranslation(“msg.christmas.effect”);
textcomponenttranslation.getStyle().setColor(TextFormatting.RED);if(!player.worldObj.isRemote)
{
player.addPotionEffect(potioneffect);
player.addChatMessage(textcomponenttranslation);
}
}
Et ça ne met pas non plus le timer à 0, parce que sinon il neigerait par cette event :
java
@SubscribeEvent
public void SnowTimer(WorldTickEvent event)
{
if(timer == 4)
{
WorldInfo worldinfo = event.world.getWorldInfo();
worldinfo.setRainTime(12532);
worldinfo.setThunderTime(0);
worldinfo.setRaining(true);
worldinfo.setThundering(false);
}
if(timer <= 4)
{
timer++;
}
}Du coup, si cette méthode ne marche pas, comment faire pour faire que le joueur ait l'effet seulement s'il attend le lever du soleil ? Merci d'avance
-
Je ne suis pas sûr de tout avoir compris. En gros tu essaies d’appliquer ton effet custom au joueur quand il se lève le matin, après avoir dormi toute la nuit, c’est bien ça ?? Et le problème rencontré est qu’il l’obtient quand même lorsqu’il se lève à n’importe quel moment du lit, même si il n’a pas passé toute la nuit, oui ?
Au passage vérifie ta convention Java, je vais essayer de faire quelque rechercheEDIT = Alors tu as deux moyens de t’y prendre.
1)Override la méthode WorldServer#wakeAllPlayers à l’aide d’un Class Transformer, assez difficile, mais je peux bien t’expliquer si tu veux, de manière à rajouter ton effet à tous les joueurs, accessibles via un iterator de la liste World#playerEntities. Bref c’est suffisamment explicite.
2)La deuxième reste de check dans l’event InputKeyEvent, ou quelque chose du genre, si la touche appuyé est échap, ou celle pour quitter un gui (je ne sais plus si un keybinding existe spécifiquement pour cette action ou non), et de check si le boolean EntityPlayer#isPlayerFullyAsleep renvoie true (Returns whether or not the player is asleep and the screen has fully faded.), si c’est le cas, encore une fois, tu lui appliques ton effet de popo.La première méthode a une portée directe sur tous les joueurs du serveur, mais reste + compliquée. Tandis que la deuxième se fait au niveau local puisqu’on est côté client, mais nécessitera sûrement l’envoie d’un packet pour ajouter ton nouvel effet de popo. A toi de voir laquelle choisir.
PS = Pour check si il neige, tu regardes si le biome où se trouve le joueur (World#getBiomeGenForCoords()), hérite de BiomeGenSnow, et si World#isRaining()) .
-
Oui, c’est exactement ça. Je n’y pense jamais à la convention, je vais coriger
-
J’ai édité au cas où personne n’aurait vu
-
world.isDaytime() ne fonctionne que côté serveur.
Côté client il renvoie toujours false.Ce qui explique surement ton problème.
-
Salut
Au départ je pensais utilisé la deuxième méthode, mais maintenant j’hésite. J’avais essayé de détecté le pressage de échap. Quand j’appuie sur échap alors que je suis en jeu, ça détecte bien mais quand je fait échap en étant dans le lit, rien du tout. Mais le problème avec la 1ère, c’est que (d’après ce que j’ai compris) on applique l’effet à tout les joueurs connectés. Or, moi je voudrais que ça soit aléatoire (comme ce que ça fait pour l’instant), qu’il y ai seulement que quelques joueurs qui aient l’effet. Tu me conseillerais quoi ? -
De te servir de la classe Random.
Bizarre pour ton problème de key input. Quels event utlises-tu ? Y’en pas des centaines je sais bien mais au cas où …
Sinon je crois que lorsqu’on dort et qu’on quitte le lit, il s’agit également de quitter le gui spécialement ouvert, le GuiSleep, ou quelque chose dans le genre…Si mes dires sont vrais, tu peux alors remplacer le GuiSleep vanilla par le tien, à la manière du MainMenu, afin d’override la méthode keyTyped, et de gérer ton effet, etc…lors du pressage de la touche échap. -
Salut
J’ai remplacé le GuiSleep par un gui qui y est extends, et Override deux fonctions : actionPerformed et keyTyped. J’ai ensuite créé un packet qui est censé être envoyé au serveur quand le joueur fais échap et appuie sur le bouton leave Bed. Le packet ajoute au joueur la potion avec un temps total de 0 tick. Comme vous pouvez le voir, j’ai dit que le packet est censé être envoyé. Hélas, il ne s’envoie pas, ça met plutôt des erreurs dans les logssDéjà, voilà mes classes :
Le guipackage ThisisChristmas.Client; import java.io.IOException; import ThisisChristmas.ChristmasEffectMessage; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiSleepMP; import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.network.play.client.CPacketEntityAction; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; public class GuiSleepMPExt extends GuiSleepMP{ @Override protected void actionPerformed(GuiButton button) throws IOException { if (button.id == 1) { ThisisChristmas.ThisisChristmas.network.sendToServer(new ChristmasEffectMessage("effect")); System.out.println("send"); this.wakeFromSleep(); } else { super.actionPerformed(button); } } @Override protected void keyTyped(char typedChar, int keyCode) throws IOException { if (keyCode == 1) { ThisisChristmas.ThisisChristmas.network.sendToServer(new ChristmasEffectMessage("effect")); System.out.println("send"); this.wakeFromSleep(); } else if (keyCode != 28 && keyCode != 156) { super.keyTyped(typedChar, keyCode); } else { String s = this.inputField.getText().trim(); if (!s.isEmpty()) { this.sendChatMessage(s); // Forge: fix vanilla not adding messages to the sent list while sleeping } this.inputField.setText(""); this.mc.ingameGUI.getChatGUI().resetScroll(); } } private void wakeFromSleep() { NetHandlerPlayClient nethandlerplayclient = this.mc.thePlayer.connection; nethandlerplayclient.sendPacket(new CPacketEntityAction(this.mc.thePlayer, CPacketEntityAction.Action.STOP_SLEEPING)); } }
Dans la classe principale :
//Avant le pré init public static SimpleNetworkWrapper network = NetworkRegistry.INSTANCE.newSimpleChannel(MODID); // dans le init network.registerMessage(ChristmasEffectMessageHandler.class, ChristmasEffectMessage.class, 0, Side.SERVER);
ChristmasEffectMessage
package ThisisChristmas; import io.netty.buffer.ByteBuf; import net.minecraftforge.fml.common.network.ByteBufUtils; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; public class ChristmasEffectMessage implements IMessage{ protected String msg; public ChristmasEffectMessage() { } public ChristmasEffectMessage(String message) { message = msg; } @Override public void fromBytes(ByteBuf buf) { msg = ByteBufUtils.readUTF8String(buf); } @Override public void toBytes(ByteBuf buf) { ByteBufUtils.writeUTF8String(buf, msg); } }
ChristmasEffectMessageHander
package ThisisChristmas; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.network.Packet; import net.minecraft.util.text.ITextComponent; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; public class ChristmasEffectMessageHandler implements IMessageHandler<christmaseffectmessage, imessage="">{ @Override public IMessage onMessage(ChristmasEffectMessage message, MessageContext ctx) { if(message.msg.equals("effect")) { EntityPlayerMP playerName = ctx.getServerHandler().playerEntity; ThisisChristmas.proxy.MagicOfChristmasEffect(playerName, 0); } return null; } }
Et voilà l’erreurs : Partie 1
[17:22:02] [Client thread/ERROR] [FML]: FMLIndexedMessageCodec exception caught io.netty.handler.codec.EncoderException: java.lang.NullPointerException at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:107) ~[MessageToMessageEncoder.class:4.0.23.Final] at io.netty.handler.codec.MessageToMessageCodec.write(MessageToMessageCodec.java:116) ~[MessageToMessageCodec.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:658) ~[AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:716) ~[AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:706) ~[AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:741) ~[AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:895) ~[DefaultChannelPipeline.class:4.0.23.Final] at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:240) ~[AbstractChannel.class:4.0.23.Final] at net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper.sendToServer(SimpleNetworkWrapper.java:270) [SimpleNetworkWrapper.class:?] at ThisisChristmas.Client.GuiSleepMPExt.actionPerformed(GuiSleepMPExt.java:19) [GuiSleepMPExt.class:?] at net.minecraft.client.gui.GuiScreen.mouseClicked(GuiScreen.java:494) [GuiScreen.class:?] at net.minecraft.client.gui.GuiChat.mouseClicked(GuiChat.java:181) [GuiChat.class:?] at net.minecraft.client.gui.GuiScreen.handleMouseInput(GuiScreen.java:609) [GuiScreen.class:?] at net.minecraft.client.gui.GuiChat.handleMouseInput(GuiChat.java:141) [GuiChat.class:?] at net.minecraft.client.gui.GuiScreen.handleInput(GuiScreen.java:575) [GuiScreen.class:?] at net.minecraft.client.Minecraft.runTick(Minecraft.java:1796) [Minecraft.class:?] at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1119) [Minecraft.class:?] at net.minecraft.client.Minecraft.run(Minecraft.java:404) [Minecraft.class:?] at net.minecraft.client.main.Main.main(Main.java:118) [Main.class:?] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_92] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_92] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_92] at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_92] at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?] at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_92] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_92] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_92] at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_92] at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) [start/:?] at GradleStart.main(GradleStart.java:26) [start/:?] Caused by: java.lang.NullPointerException at net.minecraftforge.fml.common.network.ByteBufUtils.writeUTF8String(ByteBufUtils.java:132) ~[ByteBufUtils.class:?] at ThisisChristmas.ChristmasEffectMessage.toBytes(ChristmasEffectMessage.java:30) ~[ChristmasEffectMessage.class:?] at net.minecraftforge.fml.common.network.simpleimpl.SimpleIndexedCodec.encodeInto(SimpleIndexedCodec.java:11) ~[SimpleIndexedCodec.class:?] at net.minecraftforge.fml.common.network.simpleimpl.SimpleIndexedCodec.encodeInto(SimpleIndexedCodec.java:7) ~[SimpleIndexedCodec.class:?] at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.encode(FMLIndexedMessageToMessageCodec.java:54) ~[FMLIndexedMessageToMessageCodec.class:?] at io.netty.handler.codec.MessageToMessageCodec$1.encode(MessageToMessageCodec.java:67) ~[MessageToMessageCodec$1.class:4.0.23.Final] at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:89) ~[MessageToMessageEncoder.class:4.0.23.Final] … 30 more
Partie 2```
nov. 30, 2016 5:22:02 PM io.netty.channel.embedded.EmbeddedChannel recordException
AVERTISSEMENT: More than one exception was raised. Will report only the first one and log others.
io.netty.handler.codec.EncoderException: java.lang.NullPointerException
at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:107)
at io.netty.handler.codec.MessageToMessageCodec.write(MessageToMessageCodec.java:116)
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:658)
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:716)
at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:706)
at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:741)
at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:895)
at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:240)
at net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper.sendToServer(SimpleNetworkWrapper.java:270)
at ThisisChristmas.Client.GuiSleepMPExt.actionPerformed(GuiSleepMPExt.java:19)
at net.minecraft.client.gui.GuiScreen.mouseClicked(GuiScreen.java:494)
at net.minecraft.client.gui.GuiChat.mouseClicked(GuiChat.java:181)
at net.minecraft.client.gui.GuiScreen.handleMouseInput(GuiScreen.java:609)
at net.minecraft.client.gui.GuiChat.handleMouseInput(GuiChat.java:141)
at net.minecraft.client.gui.GuiScreen.handleInput(GuiScreen.java:575)
at net.minecraft.client.Minecraft.runTick(Minecraft.java:1796)
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1119)
at net.minecraft.client.Minecraft.run(Minecraft.java:404)
at net.minecraft.client.main.Main.main(Main.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
at GradleStart.main(GradleStart.java:26)
Caused by: java.lang.NullPointerException
at net.minecraftforge.fml.common.network.ByteBufUtils.writeUTF8String(ByteBufUtils.java:132)
at ThisisChristmas.ChristmasEffectMessage.toBytes(ChristmasEffectMessage.java:30)
at net.minecraftforge.fml.common.network.simpleimpl.SimpleIndexedCodec.encodeInto(SimpleIndexedCodec.java:11)
at net.minecraftforge.fml.common.network.simpleimpl.SimpleIndexedCodec.encodeInto(SimpleIndexedCodec.java:7)
at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.encode(FMLIndexedMessageToMessageCodec.java:54)
at io.netty.handler.codec.MessageToMessageCodec$1.encode(MessageToMessageCodec.java:67)
at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:89)
… 30 more[17:22:02] [Client thread/INFO] [STDOUT]: [ThisisChristmas.Client.GuiSleepMPExt:actionPerformed:20]: send
J'ai découpé l'erreur en deux parties. Elle s'affichent en même temps, mais la première partie s'affiche normalement (en blanc) mais la deuxième partie s'affiche en rouge (ça me l'a encore jamais fait, c'est que ça doit être très grave comme erreur :[ ) L'erreur me referre à l'envoie du packet au serveur (donc à ThisisChristmas.ThisisChristmas.network.sendToServer(new ChristmasEffectMessage("effect"));) Pourquoi ça me fait cet erreur ? Est-ce que la méthode que j'ai fait est bonne ? (Autrement dit, est-ce que ça marchera une fois l'erreur résolu ?) PS : j'ai aussi découvert un nouveau problème : quand je suis dans le lit et que je le quitte manuellement (échap ou bouton), ça me lève bien mais il fait toujours nuit, le temps ne change pas. Et là, je comprend pas pourquoi</christmaseffectmessage,>
-
Visiblement tu as essayé d’envoyer un string qui est null.
-
J’ai trouvé d’où ça vient. Après t’avoir lu, je comprenait pas d’où ça pouvait venir. J’ai regardé et c’est dans ma classe extends IMessage que ça coinçait. En fait, j’ai une fonction avec en paramètre un String, et j’avais créer une variable de type String. Je disais que le paramètre String de la fonction prenait le contenu de la variable String. C’était l’inverse qu’il fallait faire. Ca ne crash plus, mais ça me remet la potion quand je me lève. L’envoie de packet doit se faire avant l’appel de l’event PlayerWakeUpEvent. Du coup, comment faire ?
ÉDIT : j’ai peut-être trouver une solution. Je pourrais essayer de créer une variable de type boolean (qui vaut false au départ), et à l’envoie du packet je le passe à true. Dans l’event PlayerWakeUp, je vérifie l’était de la variable : si elle est à true, je ne fais rien et si elle est à false, je fais l’action (ajout de la magie de Noël). Vous pensé que c’est une bonne idée ?
Re-EDIT :Salut. En fait ça ne marchera pas, il suffit qu’un mec fasse échap et mersonne n’aura l’effet. Mais j’ai pensé à créer une variable de type liste UUID et dans la packet, j’envoie l’uuid du joueur qui l’envoie. Quand je le reçois, je l’ajoute à la liste. Et dans le PlayerWakeUpEvent, je n’aurai qu’à vérifier si le joueur qui se lève a un uuid qui correspond à un de ceux que il y a dans la liste. Si il y est, ça ne fait rien. Si il n’y est pas, ça fait l’action (effet). Après; dans le SleepInBedEvent, si celui qui se couche se trouve dans la liste, ça le supprime. Ensuite; je vide la liste. C’est une bonne idée ?
-
Salut
Je sais pas si vous avez vu mon édit, mais j’ai fait ce que j’ai dit et ça marche.
En gros, j’ai créé une liste de type String. Avec mon packet, j’envoie le string de l’uuid du joueur et quand je le reçois, (je fais déjà un null check) je l’ajoute à la liste. Dans mon PlayerWakeUpEvent, je fais une condition qui vérifie si le string de l’uuid du joueur n’est pas dans la liste, S’il y est, ça nbe fait rien. Et j’ai utilisé un autre event : PlayerSleepBedEvent, où je supprime le string de l’uuid du joueur de la liste.
Voilà les codes :public List <string>uuids = new ArrayList(); // la liste de type String // Dans le MessageHandler du packet if(message.msg != null) { ThisisChristmas.instance.uuids.add(message.msg); } // Mon event PlayerWakeUp if(!(ThisisChristmas.instance.uuids.contains(event.getEntityPlayer().getUniqueID().toString()))) { ThisisChristmas.proxy.MagicOfChristmasEffect(event.getEntityPlayer(), 12536); timer = 0; } // et mon event PlayerSleepInBed String uuid = event.getEntityPlayer().getUniqueID().toString(); if(ThisisChristmas.instance.uuids.contains(uuid)) { ThisisChristmas.instance.uuids.remove(uuid); }
Voilà, je pense que ce sujet est résolu. Merci à tous :)</string>