Posted March 31, 20196 yr 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.txt 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.
April 1, 20196 yr Have you synchronized your capability from server to client? Also, which line is line 33 in NenOverlay? 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.
April 1, 20196 yr 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
April 2, 20196 yr Author On 4/1/2019 at 4:33 AM, Draco18s said: Have you synchronized your capability from server to client? Also, which line is line 33 in NenOverlay? 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()); 15 hours ago, 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 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 ?
April 2, 20196 yr Author 46 minutes ago, 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. 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
April 2, 20196 yr Author 27 minutes ago, 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. 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 ?
April 2, 20196 yr Author 6 hours ago, diesieben07 said: Yes. 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 ?
April 2, 20196 yr Author I don't know the name in english, in java it is like : int tab [] = new int[10];
April 2, 20196 yr That's an array, and of course you can store that in a capability. 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.
April 2, 20196 yr Author 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 ?
April 3, 20196 yr Author 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); }
April 3, 20196 yr Author 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
April 3, 20196 yr Author 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 ?
April 4, 20196 yr Author 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); }
April 4, 20196 yr Author 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
April 4, 20196 yr Author 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
April 4, 20196 yr Author 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
April 4, 20196 yr Author 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 ?
April 4, 20196 yr Author 6 hours ago, 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. Yes I made this (not for the dimension but I will do it when the death works)
April 5, 20196 yr Author 12 hours ago, diesieben07 said: Show your code. The issue you described is probably because you left out some of the events I mentioned. 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); } } } }
April 5, 20196 yr Author 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, 20196 yr by Simontange
April 5, 20196 yr Author 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, 20196 yr by Simontange
April 5, 20196 yr Author 7 minutes ago, diesieben07 said: No. Why are you doing this? 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
April 8, 20196 yr Author On 4/6/2019 at 11:12 AM, diesieben07 said: All packets must be registered on both sides. 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.
April 9, 20196 yr Author 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; } }
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.