Jump to content

Capability not working Null point exeption


Simontange

Recommended Posts

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 :
 
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.
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 ?

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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 ?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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);
    }
Link to comment
Share on other sites

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);


    }
Link to comment
Share on other sites

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 ?

Link to comment
Share on other sites

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)

Link to comment
Share on other sites

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);
                    }
                }
            }


    }
Link to comment
Share on other sites

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 by Simontange
Link to comment
Share on other sites

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 by Simontange
Link to comment
Share on other sites

 

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 

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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;
    }
}
Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.