Simontange Posted March 31, 2019 Posted March 31, 2019 Hello i am a new moddeur and i am doing a mod based on Hxh so i would like to attach to the players a quantity of Nen (mana) and a max amount of Nen. So I used the system of capabilities I followed many tutorials to do it but every time I have a error null point exeption so I come here to ask your help, thank you in advance and sorry for my bad English . here my crash report : crash-2019-03-30_00.16.20-client.txtFetching info... my classes : public class PlayerNen { private double Nen = 0.0; public PlayerNen() { } public double getNen() { return Nen; } public void setNen(double nen) { Nen = nen; } public void copyNen(PlayerNen Pnen) { Nen = Pnen.Nen; } public void saveNBTData (NBTTagCompound compound) {compound.setDouble("nen",Nen);} public void loadNBTData (NBTTagCompound compound){Nen=compound.getDouble("nen");} } public class PlayerProp { @CapabilityInject(PlayerNen.class) public static Capability<PlayerNen> Player_Nen; public static PlayerNen getPlayerNen(EntityPlayer player){ return player.getCapability(Player_Nen,null);} public class PropDispatcher implements ICapabilitySerializable<NBTTagCompound> { private PlayerNen playerNen = new PlayerNen(); @Override public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) { return capability == PlayerProp.Player_Nen; } @Nullable @Override public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing) { if (capability == PlayerProp.Player_Nen){ return (T) playerNen; } return null; } @Override public NBTTagCompound serializeNBT() { NBTTagCompound nbt = new NBTTagCompound(); playerNen.saveNBTData(nbt); return nbt; } @Override public void deserializeNBT(NBTTagCompound nbt) { playerNen.loadNBTData(nbt); } } public class PlayerPropEvent { public static PlayerPropEvent instance = new PlayerPropEvent(); @SubscribeEvent public void onEntityContstructing (AttachCapabilitiesEvent<net.minecraft.entity.Entity> event){ Entity test = (net.minecraft.entity.Entity) event.getObject(); if (test instanceof EntityPlayer){ if (!event.getObject().hasCapability(PlayerProp.Player_Nen,null)){ event.addCapability(new ResourceLocation(MainHunterXHunter.modId,"nen"),new PropDispatcher()); } } } @SubscribeEvent public void onPlayerCloned(PlayerEvent.Clone event){ if(event.isWasDeath()){ if(event.getOriginal().hasCapability(PlayerProp.Player_Nen,null)){ PlayerNen old = event.getOriginal().getCapability(PlayerProp.Player_Nen,null); PlayerNen newstore = PlayerProp.getPlayerNen(event.getEntityPlayer()); newstore.copyNen(old); } } } } And here the class to setup a Nen bar, this works fine whithout capabilities public class NenOverlay extends Gui { private final ResourceLocation bar = new ResourceLocation(MainHunterXHunter.modId, "textures/barre.png"); @SubscribeEvent public void renderOverlay (RenderGameOverlayEvent event ){ Minecraft mc = Minecraft.getMinecraft(); EntityPlayer player = mc.player ; PlayerNen nen = PlayerProp.getPlayerNen(player); final int externalBarH = 20, externalBarL = 108, internalBarH = 14, internalBarL = 102; float tmp=0; int lenthBar =0; if (event.getType()==RenderGameOverlayEvent.ElementType.TEXT){ mc.renderEngine.bindTexture(bar); tmp = internalBarL/250; lenthBar = (int)(tmp*nen.getNen()); drawTexturedModalRect(5,5,0,0,externalBarL,externalBarH); drawTexturedModalRect(8,8,3,20,lenthBar,internalBarH); } } } Thank you for reading this. Quote
Draco18s Posted April 1, 2019 Posted April 1, 2019 Have you synchronized your capability from server to client? Also, which line is line 33 in NenOverlay? Quote Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
LTNightshade Posted April 1, 2019 Posted April 1, 2019 Where is your Interface for the capability ? Where is your storage for the capability ? Where is your registration of the capability ? Read: https://mcforge.readthedocs.io/en/latest/datastorage/capabilities/#creating-your-own-capability Quote
Simontange Posted April 2, 2019 Author Posted April 2, 2019 On 4/1/2019 at 2:33 AM, Draco18s said: Have you synchronized your capability from server to client? Also, which line is line 33 in NenOverlay? Expand No I don't know how to do this and why do this, it is to make some packages ? It is the line where I get the Nen value lenthBar = (int)(tmp*nen.getNen()); On 4/1/2019 at 3:30 PM, LTNightshade said: Where is your Interface for the capability ? Where is your storage for the capability ? Where is your registration of the capability ? Read: https://mcforge.readthedocs.io/en/latest/datastorage/capabilities/#creating-your-own-capability Expand I watched like 3-4 tutorials on internet and moste of time they made an interface but the last guy don't made one and it works fine Now your saying it I d'ont find the methode read and write for the NBTTag I will restart my classes i think I register it in the CommonProxy in the PreInit it is good or not ? Quote
Simontange Posted April 2, 2019 Author Posted April 2, 2019 On 4/2/2019 at 8:32 AM, diesieben07 said: You don't need an interface indeed. The only reason to make an interface is if you want to make your capability an API for other mods. If you just want to store data just use a class. Do not subscribe to the blank RenderGameOverlayEvent. Choose Pre or Post. Show where you register your event handler. Preferably just make a git repository of your mod. Expand What is the event Pre ? and why it is better, my class Overlay works fine when i test it with the life bar and it works fine. public class CommonProxy { @Mod.EventHandler public void preInit (FMLPreInitializationEvent event ){ MinecraftForge.EVENT_BUS.register(PlayerPropEvent.instance); CapabilityManager.INSTANCE.register(PlayerNen.class, new Capability.IStorage<PlayerNen>(){ @Nullable @Override public NBTBase writeNBT(Capability<PlayerNen> capability, PlayerNen instance, EnumFacing side) { throw new UnsupportedOperationException(); } @Override public void readNBT(Capability<PlayerNen> capability, PlayerNen instance, EnumFacing side, NBTBase nbt) { throw new UnsupportedOperationException(); } }, ()-> null); } this is my preInit on commonproxy I don't have git and it seems complicaded to use I never used it sorry Quote
Simontange Posted April 2, 2019 Author Posted April 2, 2019 On 4/2/2019 at 9:38 AM, diesieben07 said: RenderGameOverlayEvent has two sub events, Pre and Post. Both fire for many types of HUD elements, one before rendering (can be cancelled), one after. If you just use the blank event, your code will run for both. This is inefficient and can cause problems. @Mod.EventHandler only works in your @Mod class. The concept of a common proxy does not make sense, see Code Style, issue 1. Expand Okay thank you this will optimise my code. So if I understand your thread I sould delete my common proxy and make a serverproxy and put my code inside my mod class ? Quote
Simontange Posted April 2, 2019 Author Posted April 2, 2019 On 4/2/2019 at 10:25 AM, diesieben07 said: Yes. Expand thank you so much it works fine now, I have another question if I want to store a table of variables can I do like this ? Quote
Simontange Posted April 2, 2019 Author Posted April 2, 2019 I don't know the name in english, in java it is like : int tab [] = new int[10]; Quote
Draco18s Posted April 2, 2019 Posted April 2, 2019 That's an array, and of course you can store that in a capability. Quote Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
Simontange Posted April 2, 2019 Author Posted April 2, 2019 Okay thank you. now I have an other issue I want it to save it when i log out and load it when i log in i think i must use the NBT write and read in a PlayerLoggedInEvent but I can't use the method without NBTtagCompound where can I get it ? Quote
Simontange Posted April 3, 2019 Author Posted April 3, 2019 There is a lot of subClasses but I was thinking NBTTags are juste like keys to find the value forge is seeking at is'nt that ? And where should I these functions ? @Override public NBTTagCompound serializeNBT() { NBTTagCompound nbt = new NBTTagCompound(); playerNen.saveNBTData(nbt); return nbt; } @Override public void deserializeNBT(NBTTagCompound nbt) { playerNen.loadNBTData(nbt); } Quote
Simontange Posted April 3, 2019 Author Posted April 3, 2019 Yeah so I need Compound because I store A value withe a key to call it Oh yes I forgot a word ^^ where should I call these funcions Quote
Simontange Posted April 3, 2019 Author Posted April 3, 2019 Because when I go back to title screen and after in the world it don't save my data, on the death I now I must use the event clone player but It is the same for logging ? Quote
Simontange Posted April 4, 2019 Author Posted April 4, 2019 Or am I getting the value the wrong way In my NenOverlay class ? public class NenOverlay extends Gui { private final ResourceLocation bar = new ResourceLocation(MainHunterXHunter.modId, "textures/barre.png"); @SubscribeEvent public void renderOverlay (RenderGameOverlayEvent.Pre event ){ Minecraft mc = Minecraft.getMinecraft(); EntityPlayer player = mc.player ; PlayerNen nen = PlayerProp.getPlayerNen(player); final int externalBarH = 20, externalBarL = 108, internalBarH = 14, internalBarL = 102; double tmp=0; int lenthBar =0; if (event.getType()== RenderGameOverlayEvent.ElementType.TEXT){ mc.renderEngine.bindTexture(bar); tmp = internalBarL/250.0; lenthBar = (int)(tmp*nen.getNen()); drawTexturedModalRect(5,5,0,0,externalBarL,externalBarH); drawTexturedModalRect(8,8,3,20,lenthBar,internalBarH); } Quote
Simontange Posted April 4, 2019 Author Posted April 4, 2019 So I made a buch of println to see when forge use what and the issue is that on logging in in the world serializeNBT set the Nen at 20 back even when the game savec my nen the session before Quote
Simontange Posted April 4, 2019 Author Posted April 4, 2019 I works I don't know why but now it works fine the problem is in the NenOverlay because I looked the value saved and loaded from NBTload and save and it is good it keeps it trouth the sessions Quote
Simontange Posted April 4, 2019 Author Posted April 4, 2019 Soooo I think it is beacause in my overlay it takes the client side of the player and the capability is on the server side I go try to make an custom packet handler Quote
Simontange Posted April 4, 2019 Author Posted April 4, 2019 I get it to work the only issue is that when the player dyes the overlay say it has 0 nen but I know in the capability is is 25 and when I quit minecraft and restart the world it goes back to 25 I think it is a problem with the registering beacause I must restart the game what can I do ? Quote
Simontange Posted April 4, 2019 Author Posted April 4, 2019 On 4/4/2019 at 8:55 AM, diesieben07 said: Yes, you need custom packets. See the documentation. You need to send the packet as follows: In PlayerLoggedInEvent In PlayerRespawnEvent In PlayerChangedDimensionEvent Whenever the data changes server side Note also that if you want the data to persist through deaths you need to copy the data in PlayerEvent.Clone. Expand Yes I made this (not for the dimension but I will do it when the death works) Quote
Simontange Posted April 5, 2019 Author Posted April 5, 2019 On 4/5/2019 at 7:56 AM, diesieben07 said: Show your code. The issue you described is probably because you left out some of the events I mentioned. Expand Yeah It was fixed by the respawn event here are my events : public class PlayerPropEvent { public static PlayerPropEvent instance = new PlayerPropEvent(); @SubscribeEvent public void onEntityContstructing (AttachCapabilitiesEvent<net.minecraft.entity.Entity> event){ if (event.getObject() instanceof EntityPlayer){ if (!event.getObject().hasCapability(PlayerProp.Player_Nen,null)){ System.out.println("verify attatch "); event.addCapability(new ResourceLocation(MainHunterXHunter.modId,"nen"),new PropDispatcher()); } } } @SubscribeEvent public void onPlayerCloned(PlayerEvent.Clone event){ System.out.println("clone"); if(event.isWasDeath()){ if(event.getOriginal().hasCapability(PlayerProp.Player_Nen,null)){ PlayerNen old = event.getOriginal().getCapability(PlayerProp.Player_Nen,null); PlayerNen newstore = PlayerProp.getPlayerNen(event.getEntityPlayer()); newstore.copyNen(old); System.out.println("clone done"); System.out.println("old :"+old); System.out.println("new :"+newstore); } } } @SubscribeEvent public void onPlayerRespawn(net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerRespawnEvent event){ EntityPlayer player = event.player; if(player!=null) { PlayerNen nen = player.getCapability(PlayerProp.Player_Nen, null); if (nen != null) { ImessageNen mess =new ImessageNen(nen); if(mess!=null) { NETWORK.sendTo(mess, (EntityPlayerMP) player); System.out.println("respawn message et nen = "+ nen); } } } } public int tick=0; @SubscribeEvent public void onPlayerTick(TickEvent.PlayerTickEvent event){ EntityPlayer player = event.player ; PlayerNen nen = PlayerProp.getPlayerNen(player); if (event.phase == TickEvent.Phase.START){ tick +=1; if(tick ==20) { if (nen.getNen()[0] < nen.getNen()[1]) { System.out.println("incrementation"); int tmp []={0,0}; tmp[0]=nen.getNen()[0]+1; tmp[1]=nen.getNen()[1]; nen.setNen(tmp); tick=0; } } } } @SubscribeEvent public void onPlayerLoggIn (net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent event){ EntityPlayer player = event.player; if(player!=null) { PlayerNen nen = player.getCapability(PlayerProp.Player_Nen, null); System.out.println("debug"); if (nen != null) { ImessageNen mess =new ImessageNen(nen); if(mess!=null) { NETWORK.sendTo(mess, (EntityPlayerMP) player); } } } } Quote
Simontange Posted April 5, 2019 Author Posted April 5, 2019 (edited) Now I want to change my nen by pressing a key but the keypressed event is a client side event so I must send a custom packet to the server, I use the same class as the one I use to send packets from the server to the client but it don't work what I am doing wrong ? public class ImessageNen implements IMessage { private PlayerNen value ; public ImessageNen() { value = new PlayerNen(); } public ImessageNen(PlayerNen value) { this.value = value; } @Override public void fromBytes(ByteBuf buf) { int [] tmp ={buf.readInt(),buf.readInt()}; this.value.setNen(tmp); } @Override public void toBytes(ByteBuf buf) { buf.writeInt(this.value.getNen()[0]); buf.writeInt(this.value.getNen()[1]); } public PlayerNen getValue() { return value; } public void setValue(PlayerNen value) { this.value = value; } } public class ImessageNenHandler implements IMessageHandler<ImessageNen, IMessage> { @Override public IMessage onMessage(ImessageNen message, MessageContext ctx) { IThreadListener thread = MainHunterXHunter.proxy.getListener(ctx); final EntityPlayer player = MainHunterXHunter.proxy.getPlayerEntityFromContext(ctx); PlayerNen capa = message.getValue(); thread.addScheduledTask(new Runnable() { @Override public void run() { if(player!=null){ PlayerNen capNenClient = player.getCapability(PlayerProp.Player_Nen,null); if(capa!=null && capNenClient!=null){ System.out.println("on message verif"); capNenClient.setNen(capa.getNen()); } } } }); return null; } } this is the method I call when the key is pressed(by the way I changes the double nen by an int array and nen is [0] and nenMax[1]) : public static boolean changePerCentNen (PlayerNen playerNen, EntityPlayer player, int perCent){ int[]tmp={0,playerNen.getNen()[1]}; boolean hasEnough = true; if(playerNen!=null&&perCent>=0){ if(perCent<=100) { tmp[0] = (playerNen.getNen()[0] - (int) (playerNen.getNen()[1] * (perCent / 100))); }else{ tmp[0] = (playerNen.getNen()[0] + (int) (playerNen.getNen()[1] * (perCent / 100))); } if(tmp[0]>playerNen.getNen()[1]){ tmp[0]=playerNen.getNen()[1]; }else if(tmp[0]<0){ tmp[0]=0; hasEnough = false; } playerNen.setNen(tmp); } if(player!=null) { PlayerNen nen = player.getCapability(PlayerProp.Player_Nen, null); if (nen != null) { ImessageNen mess =new ImessageNen(nen); if(mess!=null) { NETWORKSERVER.sendToServer(mess); System.out.println("set percent nen message "); } } } return hasEnough; } Edited April 5, 2019 by Simontange Quote
Simontange Posted April 5, 2019 Author Posted April 5, 2019 (edited) And here my ServerProxy class public class implements public static NETWORKSERVER; @Override public void preInitout"register network server =====================================================88888888"; NETWORKSERVER INSTANCEmodId+"server"; NETWORKSERVERclass, class, , SERVER; Edited April 5, 2019 by Simontange Quote
Simontange Posted April 5, 2019 Author Posted April 5, 2019 On 4/5/2019 at 10:03 PM, diesieben07 said: No. Why are you doing this? Expand Oh yeah I forgot to delete this, I had a NullPointerExeption error and was looking if It was the empty contructor the problem but it wasen't. So I must create a new message and in the messageHandler do What I want to the capability ? And I must register the message and the SimpleNetworkWrapper on serverSide beacause I am sending from client to server but Forge Don't fire the preInit On the serverside Quote
Simontange Posted April 8, 2019 Author Posted April 8, 2019 On 4/6/2019 at 9:12 AM, diesieben07 said: All packets must be registered on both sides. Expand Oh I missunderstood the simplelmpl tutorial on forgedocs It is juste the last parametre on the registering line that we must change but I must register it on both, thank you. Quote
Simontange Posted April 9, 2019 Author Posted April 9, 2019 I have an null point exeption I don't understand why I think it is a registering thing but I made like the explained in ForgeDocds here my code : message handler for sending from server to client the error points capNenClient.setNen(capa.getNen()); it worked before but now not... public class ImessageNenHandler implements IMessageHandler<ImessageNen, IMessage> { @Override public IMessage onMessage(ImessageNen message, MessageContext ctx) { IThreadListener thread = MainHunterXHunter.proxy.getListener(ctx); final EntityPlayer player = MainHunterXHunter.proxy.getPlayerEntityFromContext(ctx); PlayerNen capa = message.getValue(); thread.addScheduledTask(new Runnable() { @Override public void run() { if(player!=null){ PlayerNen capNenClient = player.getCapability(PlayerProp.Player_Nen,null); if(capa!=null && capNenClient!=null){ System.out.println("on message verif"); capNenClient.setNen(capa.getNen()); } } } }); return null; } } message class : public class ImessageNen implements IMessage { private PlayerNen value ; public ImessageNen() {} public ImessageNen(PlayerNen value) { this.value = value; } @Override public void fromBytes(ByteBuf buf) { int [] tmp ={buf.readInt(),buf.readInt()}; this.value.setNen(tmp); } @Override public void toBytes(ByteBuf buf) { buf.writeInt(this.value.getNen()[0]); buf.writeInt(this.value.getNen()[1]); } public PlayerNen getValue() { return value; } public void setValue(PlayerNen value) { this.value = value; } } the main class : @Mod(modid = MainHunterXHunter.modId,name = MainHunterXHunter.name, version = MainHunterXHunter.version, acceptedMinecraftVersions = "1.12.2") public class MainHunterXHunter { @SidedProxy(serverSide = "com.hunterxhunter.proxy.ServerProxy", clientSide = "com.hunterxhunter.proxy.ClientProxy") public static IProxy proxy; public static SimpleNetworkWrapper NETWORK =NetworkRegistry.INSTANCE.newSimpleChannel(MainHunterXHunter.modId); public static final String modId = "hunterxhuntermod"; public static final String name = "Hunter X Hunter Mod"; public static final String version = "1.0"; public static final HxhTab maTab = new HxhTab(); @Mod.Instance(modId) public static MainHunterXHunter instance; @Mod.EventHandler public void preInit(FMLPreInitializationEvent event) { proxy.preInit(event); System.out.println(name + " is loading!"); MinecraftForge.EVENT_BUS.register(PlayerPropEvent.instance); CapabilityManager.INSTANCE.register(PlayerNen.class, new NenStorage() /*Capability.IStorage<PlayerNen>()*/{ @Nullable @Override public NBTBase writeNBT(Capability<PlayerNen> capability, PlayerNen instance, EnumFacing side) { throw new UnsupportedOperationException(); } @Override public void readNBT(Capability<PlayerNen> capability, PlayerNen instance, EnumFacing side, NBTBase nbt) { throw new UnsupportedOperationException(); } }, ()-> null); //NETWORKSERVER = NetworkRegistry.INSTANCE.newSimpleChannel(MainHunterXHunter.modId+"server"); NETWORK.registerMessage(ImessageNenHandler.class, ImessageNen.class, 0, Side.CLIENT); //NETWORK.registerMessage(ImessHandleChanges.class, ImessageNenChanges.class, 2, Side.SERVER); } @Mod.EventHandler public void init(FMLInitializationEvent event) { proxy.init(event); } @Mod.EventHandler public void postInit(FMLPostInitializationEvent event) { MinecraftForge.EVENT_BUS.register(new NenOverlay()); MinecraftForge.EVENT_BUS.register(new NenOverlayString()); proxy.postInit(event); } @Mod.EventBusSubscriber public static class RegistrationHandler { @SubscribeEvent public static void registerItems(RegistryEvent.Register<Item> event) { ModItems.register(event.getRegistry()); } @SubscribeEvent public static void registerItems(ModelRegistryEvent event) { ModItems.registerModels(); } } } the message to send from client to server public class ImessageNenChanges implements IMessage { private int value ; public ImessageNenChanges(int value) { this.value = value; } public ImessageNenChanges() {} @Override public void fromBytes(ByteBuf buf) { this.value=buf.readInt(); } public int getValue() { return value; } public void setValue(int value) { this.value = value; } @Override public void toBytes(ByteBuf buf) { buf.writeInt(this.value); } } handler for message from client to server public class ImessHandleChanges implements IMessageHandler <ImessageNenChanges, IMessage> { @Override public IMessage onMessage(ImessageNenChanges message, MessageContext ctx) { IThreadListener thread = MainHunterXHunter.proxy.getListener(ctx); final EntityPlayer player = MainHunterXHunter.proxy.getPlayerEntityFromContext(ctx); PlayerNen playerNen = PlayerProp.getPlayerNen(player); int perCent = message.getValue(); thread.addScheduledTask(new Runnable() { @Override public void run() { int[]tmp={0,playerNen.getNen()[1]}; if(playerNen!=null&&perCent>=0){ if(perCent<=100) { tmp[0] = (playerNen.getNen()[0] - (int) (playerNen.getNen()[1] * (perCent / 100))); }else{ tmp[0] = (playerNen.getNen()[0] + (int) (playerNen.getNen()[1] * (perCent / 100))); } if(tmp[0]>playerNen.getNen()[1]){ tmp[0]=playerNen.getNen()[1]; }else if(tmp[0]<0){ tmp[0]=0; } playerNen.setNen(tmp); } } }); return null; } } Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.