Résolu [Débutant] Problème avec les Extended Entity Properties
-
Bonjour à tous,
J’écris que ce post car depuis quelques jours j’essaie de résoudre un problème sur mon mod concernant les Extended Entity Properties.
Pour vous replacer dans le contexte j’essaie de créer un Mod sur le jeu php en temps réel Hordes. Pour ceux qui ne connaissent pas vous devez effectuer certaines actions qui coutent un nombre de point d’action définis pour lutter contre des zombies. Et c’est justement sur cette utilisation de points d’action que j’ai quelques problèmes :- Le joueur commence avec 6 point d’action (PA).
- Lorsque le joueur commence à casser un block, un message s’affiche dans la console indiquant le nombre de PA du joueur (6 en l’occurence).
- Lorsqu’il casse un block avec une tile entity que j’ai crée, l’event se lance et le joueur perd 1 PA.
- Probleme : Lorsque le joueur se met à casser un autre block la console indique qu’il a toujours 6 PA.
Je vous mets en spoil les différentes classes :
Classe Principale :
:::package com.myrilandel.hordemod; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraftforge.common.MinecraftForge; import com.myrilandel.hordemod.blocks.CubeDebrisMetallique; import com.myrilandel.hordemod.blocks.CubeFerraille; import com.myrilandel.hordemod.blocks.CubePlanche; import com.myrilandel.hordemod.blocks.CubeSableSol; import com.myrilandel.hordemod.blocks.CubeSouche; import com.myrilandel.hordemod.blocks.CubeTestAlpha; import com.myrilandel.hordemod.blocks.PlancheTestAlpha; import com.myrilandel.hordemod.events.EventHandlerCommun; import com.myrilandel.hordemod.gen.StructureGenerator; import com.myrilandel.hordemod.items.DebrisMetallique; import com.myrilandel.hordemod.items.Ferraille; import com.myrilandel.hordemod.items.Planche; import com.myrilandel.hordemod.items.Poutres; import com.myrilandel.hordemod.items.RationEau; import com.myrilandel.hordemod.items.Souche; import com.myrilandel.hordemod.items.StructureMetallique; import com.myrilandel.hordemod.lib.ProxyCommon; import com.myrilandel.hordemod.lib.References; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.Mod.Instance; import cpw.mods.fml.common.SidedProxy; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.registry.GameRegistry; import fr.minecraftforgefrance.ffmtlibs.network.PacketManager; @Mod(modid = References.MODID, version = References.VERSION) public class HordeMod { @Instance(References.MODID) public static HordeMod instance; public static final String MODID = References.MODID; @SidedProxy(clientSide = References.Client, serverSide = References.Common) public static ProxyCommon proxy; public static Block cubeTestAlpha; public static Block plancheTestAlpha; public static Block cubeSouche; public static Item souche; public static Block cubePlanche; public static Item planche; public static Item poutres; public static Block cubeDebrisMetallique; public static Item debrisMetallique; public static Block cubeFerraille; public static Item ferraille; public static Item structureMetallique; public static Block cubeSableSol; public static Item rationEau; public static final PacketManager hordeModPacketHandler = new PacketManager("com.myrilandel.hordemod.packets", MODID, MODID); @EventHandler public void preInit(FMLPreInitializationEvent event){ cubeTestAlpha= new CubeTestAlpha(Material.wood); GameRegistry.registerBlock(cubeTestAlpha, "item_CubeTestAlpha"); plancheTestAlpha= new PlancheTestAlpha(Material.wood); GameRegistry.registerBlock(plancheTestAlpha, "item_PlancheTestAlpha"); StructureGenerator structureGenerator = new StructureGenerator(); GameRegistry.registerWorldGenerator(structureGenerator, 0); cubeSouche = new CubeSouche(Material.wood); GameRegistry.registerBlock(cubeSouche, "item_CubeSouche"); souche = new Souche(); GameRegistry.registerItem(souche, "item_Souche"); cubePlanche = new CubePlanche(Material.wood); GameRegistry.registerBlock(cubePlanche, "item_CubePlanche"); planche = new Planche(); GameRegistry.registerItem(planche, "item_Planche"); poutres = new Poutres(); GameRegistry.registerItem(poutres, "item_Poutres"); cubeDebrisMetallique = new CubeDebrisMetallique(Material.iron); GameRegistry.registerBlock(cubeDebrisMetallique, "item_CubeDebrisMetallique"); debrisMetallique = new DebrisMetallique(); GameRegistry.registerItem(debrisMetallique, "item_DebrisMetallique"); cubeFerraille = new CubeFerraille(Material.iron); GameRegistry.registerBlock(cubeFerraille, "item_CubeFerraille"); ferraille = new Ferraille(); GameRegistry.registerItem(ferraille, "item_Ferraille"); structureMetallique = new StructureMetallique(); GameRegistry.registerItem(structureMetallique, "item_StructureMetallique"); rationEau = new RationEau(); GameRegistry.registerItem(rationEau, "item_RationEau"); cubeSableSol = new CubeSableSol(Material.sand); GameRegistry.registerBlock(cubeSableSol, "item_CubeSableSol"); } @EventHandler public void init(FMLInitializationEvent event) { FMLCommonHandler.instance().bus().register(new EventHandlerCommun()); MinecraftForge.EVENT_BUS.register(new EventHandlerCommun()) } @EventHandler public void postInit(FMLPostInitializationEvent event) { } }
:::
Classe EventHandlerCommun :
:::package com.myrilandel.hordemod.events; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.event.world.BlockEvent; import com.myrilandel.hordemod.blocks.TileEntityRetrait; import com.myrilandel.hordemod.lib.ProxyCommon; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class EventHandlerCommun { @SubscribeEvent @SideOnly(Side.CLIENT) public void onBlockDestroyed(BlockEvent.BreakEvent event) { TileEntity te = event.world.getTileEntity(event.x, event.y, event.z); if(te != null && te instanceof TileEntityRetrait) { EntityPlayerSP player = Minecraft.getMinecraft().thePlayer; ExtendedEntityPropPA prop = new ExtendedEntityPropPA(player); prop.PertePA(1); int PA = prop.getPA(); int PAMax = prop.getPAMax(); System.out.println("Vous avez"+PA+" PA."); } } }
:::
Classe ExtendedEntityPropPA :
:::package com.myrilandel.hordemod.events; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraftforge.common.IExtendedEntityProperties; import com.myrilandel.hordemod.HordeMod; import com.myrilandel.hordemod.packets.PacketPA; public class ExtendedEntityPropPA implements IExtendedEntityProperties { public final static String EXT_PROP_NAME = "ExtPropPA"; private final EntityPlayer player; public int PA; public int PAMax; public ExtendedEntityPropPA(EntityPlayer player) { this.player = player; this.PA = this.PAMax = 6; } public static final void register(EntityPlayer player) { player.registerExtendedProperties(ExtendedEntityPropPA.EXT_PROP_NAME,new ExtendedEntityPropPA(player)); } public static final ExtendedEntityPropPA get(EntityPlayer player) { return (ExtendedEntityPropPA) player.getExtendedProperties(EXT_PROP_NAME); } @Override public void saveNBTData(NBTTagCompound compound) { NBTTagCompound properties = new NBTTagCompound(); properties.setInteger("PA", this.PA); properties.setInteger("PAMax", this.PAMax); compound.setTag(EXT_PROP_NAME, properties); } @Override public void loadNBTData(NBTTagCompound compound) { NBTTagCompound properties = (NBTTagCompound) compound .getTag(EXT_PROP_NAME); this.PA = properties.getInteger("PA"); this.PAMax = properties.getInteger("PAMax"); } public final void sync() { PacketPA packetPA = new PacketPA(this.PAMax, this.PA); HordeMod.hordeModPacketHandler.sendToServer(packetPA); if (!player.worldObj.isRemote) { EntityPlayerMP player1 = (EntityPlayerMP) player; HordeMod.hordeModPacketHandler.sendTo(packetPA, player1); } } @Override public void init(Entity entity, World world) { } public boolean PertePA(int amount) { boolean PASuff = amount <= this.PA; if (PASuff) { this.PA -= amount; this.sync(); } else { return false; } return PASuff; } public void AjoutPA(int amount) { this.PA += amount; this.sync(); } public int getPA() { return this.PA; } public int getPAMax() { return this.PAMax; } public void setPA(int newPA) { this.PA = newPA; this.sync(); } }
:::
Classe d’un block (ici CubeSouche)
:::package com.myrilandel.hordemod.blocks; import java.util.Random; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.Minecraft; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import com.myrilandel.hordemod.HordeMod; import com.myrilandel.hordemod.events.ExtendedEntityPropPA; import com.myrilandel.hordemod.lib.References; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class CubeSouche extends Block { public CubeSouche(Material material) { super(material); this.setCreativeTab(CreativeTabs.tabBlock); this.setHarvestLevel("axe", 1); this.setStepSound(soundTypeWood); this.setHardness(5.0F); this.setBlockUnbreakable(); this.setResistance(5.0F); this.setLightLevel(0.0F); this.setBlockName("CubeSouche"); this.setBlockTextureName(References.MODID + ":CubeSouche"); } @Override public boolean isOpaqueCube() { return true; } @Override public TileEntity createTileEntity(World world, int metadata) { if(metadata == 0) { return new TileEntityRetrait(); } else if(metadata == 1) { return new TileEntityAjout(); } return null; } @Override public boolean hasTileEntity(int metadata) { if(metadata >= 0 && metadata <= 1) return true; return false; } @SubscribeEvent @SideOnly(Side.CLIENT) public void onBlockClicked(World world, int i, int j, int k, EntityPlayer player) { ExtendedEntityPropPA prop = new ExtendedEntityPropPA(player); int PA = prop.getPA(); if (PA > 0){ setHardness(5.0F); System.out.println("Vous avez"+PA+" PA."); } else { setBlockUnbreakable(); System.out.println("Pas assez de PA : Block incassable"); } } public int quantityDropped(Random par1Random) { return 1; } public Item getItemDropped(int par1, Random par2Random, int par3) { return HordeMod.souche; } }
:::
Classe PacketPA
:::package com.myrilandel.hordemod.packets; import io.netty.buffer.ByteBuf; import java.io.IOException; import net.minecraft.entity.player.EntityPlayer; import com.myrilandel.hordemod.events.ExtendedEntityPropPA; import fr.minecraftforgefrance.ffmtlibs.network.FFMTPacket; public class PacketPA extends FFMTPacket{ private int PAMax, PA; public PacketPA(){} public PacketPA(int PAMax, int PA){ this.PAMax = PAMax; this.PA = PA; } @Override public void writeData(ByteBuf buffer) throws IOException { buffer.writeInt(PAMax); buffer.writeInt(PA); } @Override public void readData(ByteBuf buffer) { this.PAMax = buffer.readInt(); this.PA = buffer.readInt(); } @Override public void handleClientSide(EntityPlayer player) { ExtendedEntityPropPA props = ExtendedEntityPropPA.get(player); props.PAMax = this.PAMax; props.PA = this.PA; } @Override public void handleServerSide(EntityPlayer player) { } @Override public int getDiscriminator() { // TODO Auto-generated method stub return 0; } }
:::
Voilà, je pense que vous avez tous les éléments, je vous remercie d’avance pour l’intérêt que vous porterez à mon post.
Je précise que j’utilise la version 10.13.0.1180 de forge et la version 1.5.0.113 de FFMT-libs.
Comme je l’ai indiqué dans le titre du post, je suis encore débutant, et je m’excuse d’avance car mon code est un peu (…beaucoup) “brouillon” ^^’ Du coup si vous avez des conseils sur mon code en général, n’hésitez pas, je suis preneur !Je me tiens à votre disposition si vous avez besoin d’éléments supplémentaires.
Encore merci d’avance,
Myrilandel -
EventHandlerCommun :
EntityPlayerSP player = Minecraft.getMinecraft().thePlayer;
Ou comment casser la compatibilité serveur …
Tu as event.getPlayer() pour avoir le joueur.Et je vois pas d’autre problème, mais c’est surement lui le problème puisque la tu modifie côté client ce que doit être modifié côté serveur. Après l’autre problème peut être une histoire de synchronisation client / serveur.
-
Bonjour Robin4002,
Merci d’avoir pris de ton temps pour regarder tout ça.
J’ai modifié la ligne en
EntityPlayer player = event.getPlayer();
Mais maintenant le jeu crash et le rapport d’erreur pointe la classe PacketPA. J’y ai rajouté une ligne de code :
System.out.println("Enregistrement de "+props+" .");
Et la console retourne “enregistrement de null”
Ci joint les logs en spoiler :
:::Vous avez6 PA. Vous avez5 PA. Enregistrement de null . [12:06:09] [Client thread/ERROR] [FML]: There was a critical exception handling a packet on channel hordemod java.lang.NullPointerException at com.myrilandel.hordemod.packets.PacketPA.handleClientSide(PacketPA.java:41) ~[PacketPA.class:?] at fr.minecraftforgefrance.ffmtlibs.network.PacketHandler.channelRead0(PacketHandler.java:26) ~[PacketHandler.class:?] at fr.minecraftforgefrance.ffmtlibs.network.PacketHandler.channelRead0(PacketHandler.java:15) ~[PacketHandler.class:?] at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:98) ~[SimpleChannelInboundHandler.class:?] at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337) ~[DefaultChannelHandlerContext.class:?] at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323) ~[DefaultChannelHandlerContext.class:?] at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) ~[MessageToMessageDecoder.class:?] at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) ~[MessageToMessageCodec.class:?] at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337) ~[DefaultChannelHandlerContext.class:?] at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323) ~[DefaultChannelHandlerContext.class:?] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) ~[DefaultChannelPipeline.class:?] at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169) ~[EmbeddedChannel.class:?] at cpw.mods.fml.common.network.internal.FMLProxyPacket.processPacket(FMLProxyPacket.java:86) [FMLProxyPacket.class:?] at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:241) [NetworkManager.class:?] at net.minecraft.client.multiplayer.PlayerControllerMP.updateController(PlayerControllerMP.java:317) [PlayerControllerMP.class:?] at net.minecraft.client.Minecraft.runTick(Minecraft.java:1682) [Minecraft.class:?] at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1028) [Minecraft.class:?] at net.minecraft.client.Minecraft.run(Minecraft.java:951) [Minecraft.class:?] at net.minecraft.client.main.Main.main(Main.java:164) [Main.class:?] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_67] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_67] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_67] at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_67] at net.minecraft.launchwrapper.Launch.launch(Launch.java:134) [launchwrapper-1.9.jar:?] at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.9.jar:?] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_67] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_67] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_67] at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_67] at GradleStart.bounce(GradleStart.java:107) [start/:?] at GradleStart.startClient(GradleStart.java:100) [start/:?] at GradleStart.main(GradleStart.java:55) [start/:?] [12:06:09] [Server thread/INFO]: Stopping server [12:06:09] [Server thread/INFO]: Saving players [12:06:09] [Server thread/INFO]: Saving worlds [12:06:09] [Server thread/INFO]: Saving chunks for level 'New World'/Overworld [12:06:09] [Server thread/INFO]: Saving chunks for level 'New World'/Nether [12:06:09] [Server thread/INFO]: Saving chunks for level 'New World'/The End [12:06:09] [Server thread/INFO] [FML]: Unloading dimension 0 [12:06:09] [Server thread/INFO] [FML]: Unloading dimension -1 [12:06:09] [Server thread/INFO] [FML]: Unloading dimension 1 [12:06:09] [Server thread/INFO] [FML]: Applying holder lookups [12:06:09] [Server thread/INFO] [FML]: Holder lookups applied [12:08:01] [Client thread/INFO]: Stopping!
:::
Encore merci de ton aide
Myrilandel -
Tu enregistre où ton ExtendedEntityPropPA ?
-
Le problème viens du fait que tu n’initialise pas la variable pour le player de base. Regarde la partie Event Handler du tutoriel, tu devrais voir le soucis.
En gros, tu sauvegarde un props qui est nul, car le joueur ne l’a pas.
-
Je ne suis pas sûr d’avoir bien compris ta question Robin, est-ce que tu pourrais m’en dire un peu plus s’il te plait ? :s
Salut Gugu42, merci à toi aussi de bien vouloir m’aider.
J’ai repris ton tutoriel et effectivement j’avais zappé la partie
@SubscribeEvent public void onEntityConstructing(EntityConstructing event) { if (event.entity instanceof EntityPlayer && ExtendedEntityPropPA.get((EntityPlayer) event.entity) == null) ExtendedEntityPropPA.register((EntityPlayer) event.entity); }
A présent le jeu ne crash plus et la console affiche bien :
Enregistrement de com.myrilandel.hordemod.events.ExtendedEntityPropPA@64ab7aeb .
Mais je retombe sur mon problème initial où le joueur retombe à son nombre de PA initial (6) lorsqu’il se met à casser un autre block
-
Quand je disais enregistrer, c’est justement le code que tu as mit et qu’il te manquait, donc ça c’est bon.
Je vois où est le problème.
Toujours dans l’event :
ExtendedEntityPropPA prop = new ExtendedEntityPropPA(player);
Devrait être :
ExtendedEntityPropPA prop = ExtendedEntityPropPA.get(player);
Car sinon tu réinitialise le prop. -
Punaise je me sens bête pourquoi j’ai pas vu ça plus tôt >.<
Tout marche à merveille ! Merci beaucoup à tout les deux pour m’avoir accordé de votre temps !
J’édit mon post en résolu.
Encore merci pour votre aide et pour tout le boulot que vous faites,
Myrilandel