Jump to content

oldcheese

Members
  • Posts

    108
  • Joined

  • Last visited

Everything posted by oldcheese

  1. Alright. Thanks. My english isn't that great, So you're saying that NBTTagCompound is like a List and TagList is a map. So the sollution here is to save my TagList to the NBTTagCompound for efficiency. However, Looking at the NBTTagCompound class it looks like NBTTagCompound is actually a HashMap, while NBTTagList is an ArrayList. So I should save my Array to the NBTTagList, then add the NBTTagList to the NBTTagCompound. And you're saying there's a clear difference between saving my NBTTaglist and saving individual values for my array to NBTTagCompound. That makes perfect sense. Thanks. Now my next question is: In the code above I've tried to add my Int[] and Boolean[] to TagLists and save them, yet they don't seem to save. What could I do to improve the code, or what class should I look at to try and figure it out? I've tried basing it on the IItemHandler storage but it doesn't seem to properly retrieve the storage afterwards. Saving shows up in my console, reading doesn't.
  2. I'm wondering what the exact benefit would be over using a taglist? Also, my taglist doesn't seem to work. Right now I'm using the following code to try and Write to the NBT: @Override public NBTBase writeNBT(Capability<IAdventurerHandler> capability, IAdventurerHandler instance, EnumFacing side) { final NBTTagCompound tag = new NBTTagCompound(); boolean[] list = instance.getAllLevels(); int[] intlist = instance.getAllHotkeys(); NBTTagCompound tagappendbool = new NBTTagCompound(); NBTTagList taglist = new NBTTagList(); NBTTagList tagHot = new NBTTagList(); for(int i = 0; i < list.length; i++){ Boolean s = list[i]; System.out.println(list[i]); tag.setBoolean("Boolean", s); taglist.appendTag(tagappendbool); } tag.setTag("BooleanList", taglist); for(int i = 0; i < intlist.length; i++) { int k = intlist[i]; System.out.println(intlist[i]); NBTTagCompound tag3 = new NBTTagCompound(); tag3.setInteger("Int", k); tagHot.appendTag(tag3); } tag.setTag("hotlist", tagHot); tag.setInteger("level", instance.getLevel()); tag.setInteger("xp", instance.getXP()); tag.setInteger("power", instance.getPower()); return tag; but it seems to me I could just have my for loop run tag.setInteger("Int" + i, k); instead of first adding them to a taglist and then appending said taglist. Is there any benefit to adding arrays to taglists over just looping through the array? Also. I'm not managing to retrieve my taglist. For some reason when I retrieve it using this following code: public void readNBT(Capability<IAdventurerHandler> capability, IAdventurerHandler instance, EnumFacing side, NBTBase nbt) { final NBTTagCompound tag = (NBTTagCompound) nbt; boolean[] list = new boolean[10]; int[] intlist = new int[5]; NBTTagList taglist = tag.getTagList("BooleanList", Constants.NBT.TAG_LIST); NBTTagCompound tag2; for(int i = 0; i < taglist.tagCount(); i++){ tag2 = taglist.getCompoundTagAt(i); boolean s = tag2.getBoolean("Boolean"); System.out.println("read: " + tag2.getBoolean("Boolean")); list[i] = s; } NBTTagList tagHot = tag.getTagList("hotlist", Constants.NBT.TAG_LIST); for(int k = 0; k < tagHot.tagCount(); k++){ tag2 = taglist.getCompoundTagAt(k); int s = tag2.getInteger("Int"); intlist[k] = s; } instance.setAll(list); instance.setAllHotkey(intlist); instance.setLevel(tag.getInteger("level")); instance.setXP(tag.getInteger("xp")); instance.setPower(tag.getInteger("power")); } it doesn't actually load the attributes. I'm checking the server side, so it's not like I'm failing to send a packet to the client side to sync stuff up. I'm managing to save all other attributes just fine. For some reason this just seems not to work. When I run the code it shows true for my first boolean, so at least at that part of the saving it's working. Yet when I relog the variable is set back to boolean. Anyway. I can solve this by just looping individual parts of my array. But I'm wondering if that'd impact performance any, and how I'd implement an ArrayList, or where I can find an example. I've based my current code largely on the IItemHandler code.
  3. Edit: For some reason the alpha channels on all of my boxes were set to 0.0F. I was trying to use Qubble which for some reason sets it like this by default. I guess I'll switch to a different helper for making models. Unless someone has some recommendations for what to use. I guess I could also try to manually change models, but that'd take a lot longer. Marking as solved.
  4. java.lang.RuntimeException: An error occurred trying to configure the Minecraft home at C:\Users\Selena\AppData\Roaming\.minecraft for Forge Mod Loader Apparantly there's trouble here. Have you tried deleting the %appdata% minecraft folder or re-installing minecraft and forge?
  5. Alright. I'll attempt to make another model and debug some stuff. Lets hope for the best.
  6. Have you thought about possibly making this part of the block rather than the player sending updates to the server? If you want a specific block to move out of the way when a player runs into it you could make the tile Entity search for players within an X radius of it. Then when the player gets near it could look at average speed and react to it. Depending on what block behaviour you want this wouldn't even have to be incredibly precise. that way blocks could react to entities being within X meters of the block rather than players sending a continuous signal to the server. Ofcourse both of those ideas have their merit
  7. I bind my texture in the doRender in my EntityRenderThrowTiny class as such. @Override public void doRender(Entity entity, double x, double y, double z, float entityYaw, float partialTicks){ bindTexture(getEntityTexture(entity)); GL11.glPushMatrix(); GL11.glTranslated(x, y, z); customModel.render(entity, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0675F); GL11.glPopMatrix(); } unless bindTexture is not what I'm supposed to be using? Should I somehow bind my texture in the Renderfactory? I guess I could open up the Render class and have a look how that'd work.
  8. Are you trying to make some sort of anti-cheat? What are you looking to do with the player's speed? I'm just wondering, because if it's not for something like an anti-cheat or a live speed meter I'd imagine there might be more elegant sollutions than sending a packet to the server every tick for every online player. Have you considered measuring the average speed client side by calculating the position every X ticks and then sending that average speed to the server? as said above the client has more accurate 'live' information on position. If you don't need something to happen the exact tick your movement speed drops below 4.3m/s that could very well work.
  9. So I've made a custom entity extending Entitythrowable which works just fine. I've added a custom model to it. Code in my ClientProxy: @Override public void preInit(FMLPreInitializationEvent e) { ItemRenderRegister.registerItemRenderer(); RenderingRegistry.registerEntityRenderingHandler(EntityThrow.class, ThrowTinyFactory.INSTANCE); super.preInit(e); } Code in my ThrowTinyFactory: public class ThrowTinyFactory implements IRenderFactory<EntityThrow>{ public static final ThrowTinyFactory INSTANCE = new ThrowTinyFactory(); @Override public Render<? super EntityThrow> createRenderFor(RenderManager manager) { return new EntityRenderThrowTiny(); } } Code in EntityRenderThrowTiny public class EntityRenderThrowTiny extends Render { private ModelBase customModel; public EntityRenderThrowTiny(){ super(Minecraft.getMinecraft().getRenderManager()); customModel = new ThrowItemModel(); } private final ResourceLocation EntityThrowTiny = new ResourceLocation( Main.MODID + ":" + "textures/modeltex/throwitem.png"); @Override protected ResourceLocation getEntityTexture(Entity entity) { return getThrowTexture((EntityThrow)entity); } private ResourceLocation getThrowTexture(EntityThrow entity) { return EntityThrowTiny; } @Override public void doRender(Entity entity, double x, double y, double z, float entityYaw, float partialTicks){ bindTexture(getEntityTexture(entity)); GL11.glPushMatrix(); GL11.glTranslated(x, y, z); customModel.render(entity, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0675F); GL11.glPopMatrix(); } } The reason I've put super(Minecraft.getMinecraft.getRenderManager) in my Render is because I've made that class before I realized that I'd need a IRenderFactory. I realize this might be a mistake, but I'll elaborate on that later. For now the error this gives me is: Time: 9/12/17 2:17 AM Description: Rendering entity in world java.lang.NullPointerException: Rendering entity in world at net.minecraft.client.renderer.entity.Render.bindTexture(Render.java:128) at com.cheese.rpvp.render.EntityRenderThrowTiny.doRender(EntityRenderThrowTiny.java:40) at net.minecraft.client.renderer.entity.RenderManager.doRenderEntity(RenderManager.java:372) at net.minecraft.client.renderer.entity.RenderManager.renderEntityStatic(RenderManager.java:356) at net.minecraft.client.renderer.RenderGlobal.renderEntities(RenderGlobal.java:651) at net.minecraft.client.renderer.EntityRenderer.renderWorldPass(EntityRenderer.java:1368) at net.minecraft.client.renderer.EntityRenderer.renderWorld(EntityRenderer.java:1282) at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1091) at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1139) at net.minecraft.client.Minecraft.run(Minecraft.java:406) at net.minecraft.client.main.Main.main(Main.java:118) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) 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(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) at GradleStart.main(GradleStart.java:26) A detailed walkthrough of the error, its code path and all known details is as follows: --------------------------------------------------------------------------------------- -- Head -- Thread: Client thread Stacktrace: at net.minecraft.client.renderer.entity.Render.bindTexture(Render.java:128) at com.cheese.rpvp.render.EntityRenderThrowTiny.doRender(EntityRenderThrowTiny.java:40) -- Entity being rendered -- Details: Entity Type: rpvp.tiny trident (com.cheese.rpvp.entities.throwables.EntityThrow) Entity ID: 444 Entity Name: entity.rpvp.tiny trident.name Entity's Exact location: 122.40, 79.35, 103.48 Entity's Block location: World: (122,79,103), Chunk: (at 10,4,7 in 7,6; contains blocks 112,0,96 to 127,255,111), Region: (0,0; contains chunks 0,0 to 31,31, blocks 0,0,0 to 511,255,511) Entity's Momentum: 0.45, 0.19, 1.92 Entity's Passengers: [] Entity's Vehicle: ~~ERROR~~ NullPointerException: null -- Renderer details -- Details: Assigned renderer: com.cheese.rpvp.render.EntityRenderThrowTiny@3716bea4 Location: 0.11,1.35,0.48 - World: (0,1,0), Chunk: (at 0,0,0 in 0,0; contains blocks 0,0,0 to 15,255,15), Region: (0,0; contains chunks 0,0 to 31,31, blocks 0,0,0 to 511,255,511) Rotation: 13.353905 Delta: 0.9459794 Stacktrace: at net.minecraft.client.renderer.entity.RenderManager.doRenderEntity(RenderManager.java:372) at net.minecraft.client.renderer.entity.RenderManager.renderEntityStatic(RenderManager.java:356) at net.minecraft.client.renderer.RenderGlobal.renderEntities(RenderGlobal.java:651) at net.minecraft.client.renderer.EntityRenderer.renderWorldPass(EntityRenderer.java:1368) at net.minecraft.client.renderer.EntityRenderer.renderWorld(EntityRenderer.java:1282) The game just stops rendering and crashes the second I spawn the entity. which means there's some kind of nullpointerexception going on. Now the relative path of my texture is: assets/rpvp/textures/modeltex/throwitem.png which means that my ResourceLocation should be fully working, even if it crashes on the BindTexture. Something is obviously wrong. Now when I remove the Minecraft.getMinecraft.getRenderManager and instead allow the IRenderFactory to pass on the manager like so: @Override public Render<? super Entity> createRenderFor(RenderManager manager) { return new EntityRenderThrowTiny(manager); public EntityRenderThrowTiny(RenderManager manager){ super(manager); customModel = new ThrowItemModel(); } the code actually does work properly, as in the model is actually loaded. When I add a Println to my Model file it will actually show, meaning that the model is somehow getting loaded by passing on the RenderManager provided by the interface. However, when I do that my texture doesn't show up at all. I've already tried to switch around my resourcelocation just to make sure, but no matter how I've tried to access it it just didn't want to work properly. Model file: package com.cheese.rpvp.entities.throwables; import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelRenderer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.Entity; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import org.lwjgl.opengl.GL11; /** * throwitem by Unknown */ @SideOnly(Side.CLIENT) public class ThrowItemModel extends ModelBase { public ModelRenderer shaft; public ModelRenderer axis1; public ModelRenderer leftprong; public ModelRenderer rightprong; public ThrowItemModel() { this.textureWidth = 64; this.textureHeight = 32; this.shaft = new ModelRenderer(this, 0, 0); this.shaft.setRotationPoint(0.0F, -1.0F, 0.0F); this.shaft.addBox(0.0F, 0.0F, 0.0F, 1, 6, 1); this.axis1 = new ModelRenderer(this, 0, 0); this.axis1.setRotationPoint(-1.0F, 1.0F, 0.0F); this.axis1.addBox(0.0F, 0.0F, 0.0F, 3, 1, 1); this.leftprong = new ModelRenderer(this, 0, 0); this.leftprong.setRotationPoint(-1.3F, -0.5F, 0.0F); this.leftprong.addBox(0.0F, 0.0F, 0.0F, 1, 2, 1); this.setRotationAngles(this.leftprong, 0.0F, 0.0F, -0.13962634015954636F); this.rightprong = new ModelRenderer(this, 0, 0); this.rightprong.setRotationPoint(1.3F, -0.6F, 0.0F); this.rightprong.addBox(0.0F, 0.0F, 0.0F, 1, 2, 1); this.setRotationAngles(this.rightprong, 0.0F, 0.0F, 0.13962634015954636F); } @Override public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float rotationYaw, float rotationPitch, float scale) { GlStateManager.enableBlend(); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GlStateManager.color(1.0F, 1.0F, 1.0F, 0.0F); this.shaft.render(scale); GlStateManager.disableBlend(); GlStateManager.enableBlend(); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GlStateManager.color(1.0F, 1.0F, 1.0F, 0.0F); this.axis1.render(scale); GlStateManager.disableBlend(); GlStateManager.pushMatrix(); GlStateManager.translate(this.leftprong.offsetX, this.leftprong.offsetY, this.leftprong.offsetZ); GlStateManager.translate(this.leftprong.rotationPointX * scale, this.leftprong.rotationPointY * scale, this.leftprong.rotationPointZ * scale); GlStateManager.scale(1.0F, 1.0F, 1.0F); GlStateManager.translate(-this.leftprong.offsetX, -this.leftprong.offsetY, -this.leftprong.offsetZ); GlStateManager.translate(-this.leftprong.rotationPointX * scale, -this.leftprong.rotationPointY * scale, -this.leftprong.rotationPointZ * scale); GlStateManager.enableBlend(); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GlStateManager.color(1.0F, 1.0F, 1.0F, 0.0F); this.leftprong.render(scale); GlStateManager.disableBlend(); GlStateManager.popMatrix(); GlStateManager.pushMatrix(); GlStateManager.translate(this.rightprong.offsetX, this.rightprong.offsetY, this.rightprong.offsetZ); GlStateManager.translate(this.rightprong.rotationPointX * scale, this.rightprong.rotationPointY * scale, this.rightprong.rotationPointZ * scale); GlStateManager.scale(1.0F, 1.0F, 1.0F); GlStateManager.translate(-this.rightprong.offsetX, -this.rightprong.offsetY, -this.rightprong.offsetZ); GlStateManager.translate(-this.rightprong.rotationPointX * scale, -this.rightprong.rotationPointY * scale, -this.rightprong.rotationPointZ * scale); GlStateManager.enableBlend(); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GlStateManager.color(1.0F, 1.0F, 1.0F, 0.0F); this.rightprong.render(scale); GlStateManager.disableBlend(); GlStateManager.popMatrix(); } public void setRotationAngles(ModelRenderer modelRenderer, float x, float y, float z) { modelRenderer.rotateAngleX = x; modelRenderer.rotateAngleY = y; modelRenderer.rotateAngleZ = z; } } Summary: When using the RenderManager that IRenderFactory provides the model will load but it'll be invisible. When I try to pass on Minecraft.getMinecraft.getRenderManager() to my custom render class it just gives me a nullpointerexception.
  10. What are you trying now? I know that in 1.10 you can use PlayerList to get a specific player. So first you'd get the server from your world with something akin to PlayerList list = world.getMinecraftServer().getPlayerList(); then simply list.getPlayerByUsername("cookie"); as far as I can tell this shouldn't have changed too much, considering we just switched from ServerConfigurationManager to PlayerList. PlayerList can also be used to find a player by UUID, which might be more reliable for people who change their name. Note: I've checked this in 1.10, but since nobody else responded yet I thought I'd try and push you along the right direction. If this doesn't work you could always try to google for the PlayerList class and what happened to it in 1.12
  11. Could you link to us the specific log file for the crash? Have you changed anything lately? This could very well be a java version issue somehow. You should consider uninstalling and re-installing Java. That's what I can think of off the top of my head without a log file. The log files are usually located in the %appdata% folder, but you probably already know where to find those. You can use pastebin.com or the <> icon for code to paste it here. If you open a command screen and type Java -v it'll tell you what Java version you have, alternatively this site can help you figure out your version. Ofcourse your java version will also show in the logs that you (hopefully) will provide. Also, are you sure you downloaded minecraftforge from the official page? What version are you trying to use. Is it the recommended version or the latest? The latest version might sometimes have a few issues that aren't yet ironed out. Edit: Also, are you sure you're comitting enough RAM and such to minecraft? If it's crashing on load it could very well be that it's overloading the program if you've alloted an particularly small amount of ram like 512 MB.
  12. Well, my EntityJoinWorldEvent fires BEFORE the Attach capability event. That's where it fails. I want to update my client by sending them a packet. But if the packet attempts to update before the capability is attached to the client, there's not much use. I can try to use the gather capabilities event. But if you have an implementation of a packet where it successfully updates the client side after logging in using EntityJoinWorldEvent I'd love to see how you did it. Fixing something I did wrong would be easier than trying to workaround using tick handlers Sorry if the spelling sucks. I'm typing from my phone still. Update: I created a playerTickHandler with a few booleans. One boolean from my GuiHandler that draws the actual element that turns to true when things aren't properly loaded on the client side. Then a boolean near the Eventhandler to make sure that the load isn't called a second time. This ensures that whenever my capabilities DO exist (Or my GUI couldn't access them) the tickhandler updates the player once, giving them the proper resources. Edit: This only works in single player now that I test it. Back into the fray I go. Edit: Made a variable in my GuiHandler using a ClientConnectedToServerEvent to make sure that the client would request an update every time it connected. Then I created a simple packet from the client to the server to ask for an update, on which the server send back a packet with the relevant, updated information. No tickhandler required, no funky workaround. I'm quite frankly not sure why I didn't try this in the first place.
  13. Would players be able to inherit information from eachother if I delayed it too much and another player joined? I'd assumed that when I get an entity from a joinworldevent it'd be a specific player, not an object redirecting me to the latest player. Maybe I'm misreading this. But your sollution is to register a new tickhandler for playerTickEvent and not send the update packet untill the Capability is attached? That seems like as good as a workaround as any, though I've been a bit reluctant to use too many tickhandlers myself. Thanks for the help. When I get back from college I'll start rewriting my code and post updates if I solve it. For future readers.
  14. Well, the error is definitely caused by "MWAB" which I guess is your Mod. I'm guessing you're trying to use an object somewhere that isn't registered. Or maybe you're trying to read something off a block that isn't instantiated yet, or something that's supposed to be there but isn't. It's hard to really debug without knowing the code. If you want to debug yourself, you can always add System.out.println's at certain points in your code, which should help you with seeing exactly what point of your code is throwing errors. Or you can try to post the code you're trying to execute in here, using the <> Symbol at the top of your editor which allows you to neatly paste code.
  15. I've made my custom Capability, everything is working pretty well. I have an error though where when I enter a world, my custom Mana bar will just be set to the default value for mana on the client side. Which means that the Mana bar that I've made shows 0 mana untill I use an mana consuming item and force an update. I've written a Packet to update my client with the server information and this packet works marvelous. Whenever the game launches my client needs to have the Capability attached again while the server retrieves the information from the NBT file, that's why I'm sending a packet that updates the client with all the server information. The problem I'm running in to is that I'm trying to run an PlayerLoggedInEvent to update my client with all the information needed. But this PlayerLoggedInEvent fires BEFORE Capabilities are added. [23:40:15] [Server thread/INFO]: [com.cheese.rpvp.capabilities.handlers.CustomDataHandlerBar:loggedIn:68]: Message sent login, mana = 90 maxmana 100 [23:40:16] [Client thread/INFO]: [com.cheese.rpvp.capabilities.handlers.CustomDataHandlerBar:attachCapabilities:37]: Custom ability Bar added [23:40:16] [Client thread/INFO]: [com.cheese.rpvp.capabilities.handlers.CustomAdventurerHandler:attachCapabilities:31]: Custom ability Adv added [23:40:16] [Client thread/INFO]: [com.cheese.rpvp.capabilities.handlers.CustomItemBar:attachCapabilities:34]: Capability added Now I've already tried setting my playerLoggedInEvent to the lowest priority: @SubscribeEvent(priority = EventPriority.LOWEST) public void loggedIn(PlayerLoggedInEvent event){ if(!event.player.worldObj.isRemote) { if (event.player.hasCapability(CAPABILITY_BAR, EnumFacing.DOWN)) { final IBarHandler instance = getHandler(event.player); final NBTTagCompound tag = new NBTTagCompound(); tag.setInteger("maxmana", instance.getMaxMana()); tag.setInteger("maxhealth", instance.getMaxHealth()); tag.setInteger("mana", instance.getMana()); tag.setInteger("health", instance.getHealth()); tag.setInteger("fatigue", instance.getFatigue()); tag.setInteger("job", instance.getJob()); Main.packetHandler.barWrapper.sendTo(new BarMessage(tag), (EntityPlayerMP)event.player); System.out.println("Message sent login, mana = " + instance.getMana() + " maxmana " + instance.getMaxMana()); } } } while setting my AttachCapabilities to the highest. @SubscribeEvent(priority = EventPriority.HIGH) public void attachCapabilities(AttachCapabilitiesEvent<Entity> event){ if(event.getObject() instanceof EntityPlayer) { System.out.println("Custom ability Bar added"); event.addCapability(new ResourceLocation(Main.MODID, "BARS"), new BarProvider()); } } to no Avail. The order keeps the same and when my player logs in his manabar looks completely empty, even if on the server side he has plenty of mana. What I'm wondering now is: Is there any Event that I can call that will fire AFTER my capability is added. I need an EntityPlayer to attach to the message so I can properly update my Capabilities. If there's a way to make my Capability fire first that'll work too. Problem description: My Messagehandler OnPlayerLoggedInEvent which updates my client capability is sent BEFORE the capability is attached to the client. I'm looking for a different event to call when my client joins the server that will pop AFTER capabilities are added, but preferably within a second of joining a world. EntityJoinWorldEvent with instanceof EntityPlayer also doesn't work. The events all work seperately, and I can call the method that updates the info after the capability is added and it works fine, so that's not the problem. I just can't get them to operate in the wanted order. SOLLUTION:
  16. You might want to check eventhandlers and in particular the PlayerInteractEvent event which returns the player, the world and the location of the block. From there you can get the block at X location (Which should be your sign) consider using something like BlockPos blockPos = new BlockPos(x,y,z); String text = ((TileEntitySign)world.getTileEntity(blockPos)).signText[0].toString(); to get the text. I believe that only returns the first line. for next lines you want to increase the signText number. I believe the text is able to be null, so make sure you check for that when you use java to decipher the lines. if your sign contains a specific text you should be able to decipher it and parse it to do whatever you want. Since you have a world and an Entity you can either give something directly to the entity, or you can spawn an item right on your player by doing something like this: ItemStack stack = new ItemStack(your items); World.spawnEntityInWorld(new EntityItem(world, player.posX, player.posY, player.posZ, stack)); that way the item will spawn on the player, it'll go in his intentory or remain on the ground if his inventory is full. remember to run that code on the server, not the client. Otherwise you'll end up with a 'ghost' item.
  17. Edit: Disclaimer. I'm new to Forge modding, so I'm sure someone will come along and prove that what I said didn't quite work. I'm just offering my vision on this. It's worth a shot. It should be possible to call an event from your item class, as long as you register said event in the proper place. So if you don't want to duplicate the code elsewhere that's your sollution. Though it's not a bad practice to have all your eventhandlers in one place. you could always create a method that's accesible outside of your Item for specific tasks. An alternative sollution would be to have your item deplete X amount of it's 'energy' so to speak every X ticks. This would make sure that it would just drain whenever it was on, rather than when it's 'opened' and 'closed'. That way you wouldn't have to go out of your way to create a special event when the player logs on or off, because it wouldn't drain when the player was offline. For this you could implement an eventhandler with one of the subclasses of the TickEvent class. You could create a tickhandler that counts ticks, then executes your code after X ticks (like 200 for dropping charge every 10 seconds). If you are worried about performance, you could use a PlayerTickHandler which should only run on the client, then send a Packet to the server telling how much charge you have. The final thing I can imagine is adding a simple If statement to your Item file to check how long a player has been logged in. I've tried this in my Single player world and EntityPlayer.ticksExisted returns a low amount on playerlogin. So you could add a clause that doesn't deplete your item when ticksExisted is low. That seems like the easiest sollution. However I believe ticksExisted is also low after a player dies. so keep that in mind.
  18. Ah. My bad. I hadn't thought about that, the other Capability I made used this, but on a server I see why that'd be horrid. So basically ITEM_HANDLER_CAPABILITY is already registered to the player. Does this mean that the player's inventory is stored in CapabilityItemHandler? Would using ItemHandlerSlot yield the same results in this case as using regular slots? I don't see a reason to use that, I'm just curious. Basically this entire thread revolves around me thinking I can expose the already existing IItemhandler again. For future people who're googling sollutions: Like Choonster helpfully pointed out, I've created a new Interface extending IItemHandler, then I've created a new implementation of this interface extending ItemStackHandler and implementing my new IItemHandler copy. I've injected it and registered it using conventional methods and added it to my EntityPlayer on login. For this to work I've had to create an additional Storage class, but that wasn't much of a problem. The code works perfectly fine now and my player has a custom Inventory of the slots I've dictated in my AbilityProvider.
  19. I've been trying to figure out how to add a Capability to the player. I've used the Forge documentation so far. I'm trying to register the IItemhandler capability to the player. I've created a custom class called CustomItemBar with that registers an Event in my PreInit with an attachCapabilitiesEvent that checks if the entity is a player, then adds the capability. I've created the following class to call events and contain a basic wrapper to call my capability from other locations: public class CustomItemBar { public static void register(){ MinecraftForge.EVENT_BUS.register(new CustomItemBar()); } @SubscribeEvent public void attachCapabilities(AttachCapabilitiesEvent<Entity> event){ if(event.getObject() instanceof EntityPlayer) { event.addCapability(new ResourceLocation("InventoryCapability"), new AbilityProvider()); System.out.println("Capability added"); } } public static IItemHandler getHandler(Entity entity){ if(entity.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null)){ return entity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); } return null; } } I add the capability through AbilityProvider which is as follows: public class AbilityProvider implements ICapabilitySerializable<NBTTagCompound>,ICapabilityProvider { public static ItemStackHandler handler = new ItemStackHandler(5); @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { if (capability == ITEM_HANDLER_CAPABILITY) { System.out.println("has item handler capability"); return true; } return false; } @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) { if(capability == ITEM_HANDLER_CAPABILITY){ System.out.println("We returned the handler"); return (T)this.handler; } System.out.println("We returned null"); return null; } @Override public NBTTagCompound serializeNBT() { return handler.serializeNBT(); } @Override public void deserializeNBT(NBTTagCompound nbt) { handler.deserializeNBT(nbt); } } As you can see I'm using ItemStackHandler with a size of 5, When I launch the client everything works fine. When I log in to my world I get the proper System.out.println("Custom ability added"); line returned to me in the logs. However, this is where it goes wrong: When I try to use public static IItemHandler getHandler(Entity entity){ if(entity.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null)){ return entity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); } return null; } in my items. I don't get the @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) { if(capability == ITEM_HANDLER_CAPABILITY){ System.out.println("We returned the handler"); return (T)this.handler; } System.out.println("We returned null"); return null; } Message that pops up here. Neither of them. My implementation is as such: final IItemHandler handler2 = CustomItemBar.getHandler(player); handler2.insertItem(4, new ItemStack(RPVPItems.testitem, 5), false); //and then for the item to tell me what's going on: final IItemHandler handlerAbility = CustomItemBar.getHandler(player); if(handlerAbility.extractItem(4, 1, true) != null) { ItemStack information = handlerAbility.getStackInSlot(4); ItemStack stack = handlerAbility.extractItem(4, 1, false); System.out.println("slot 2 has " + information.getItem() + " and amount:" + information.stackSize); world.spawnEntityInWorld(new EntityItem(world, player.posX, player.posY, player.posZ, stack)); } The big issue I'm having here is that instead of adding and substracting items from my new Capability storage, the items get added to my hotbar in slot 5 (which makes sense, since slot 1 is id 0) The commandlines will tell me that there's 4 items in slot 4, but this is obviously an issue since it's reading from my hotbar slot on my actual inventory, not from my Capability. TL:DR: - The Capability seems to register just fine, no errors are thrown up. - I try to add the pre-existing IItemhandler to my player, so I don't need to create another Interface. - When I call the entity.getCapabilities it DOES detect the capability ITEM_HANDLER_CAPABILITY but it doesn't call the code in my overwritten getCapability in my provider. - When I attempt to use the capability I instead interact with the items from my regular inventory in the same slot that I gave to the code. For future people who're googling sollutions: Like Choonster helpfully pointed out, I've created a new Interface extending IItemHandler, then I've created a new implementation of this interface extending ItemStackHandler and implementing my new IItemHandler copy. I've injected it and registered it using conventional methods and added it to my EntityPlayer on login. For this to work I've had to create an additional Storage class, but that wasn't much of a problem. The code works perfectly fine now and my player has a custom Inventory of the slots I've dictated in my AbilityProvider.
  20. Proxies are very important because they allow you to distinguish between the sides of your program. There are parts that you might want to implement only on the client, like GUI Drawing, Rendering of items, keybindings etc. Then there's things that you ONLY want to do on the server. Like sending a message to the player. It wouldn't make sense to have the client send a message to itself. Then there's finally some stuff you might want to send to both, like when the player picks up an item. That way the client and server are perfectly in synch. I'm not sure what version you might be on. But in general you want to make a package with a ClientProxy, a ServerProxy class and a commonproxy class. Your proxy classes simply define where stuff goes. they have the same pre-init, postinit and init your main class should have: public class CommonProxy { public void preInit(FMLPreInitializationEvent e) { } public void init(FMLInitializationEvent e) { } public void postInit(FMLPostInitializationEvent e) { } } public class ServerProxy extends CommonProxy{ @Override public void preInit(FMLPreInitializationEvent e) { super.preInit(e); } @Override public void init(FMLInitializationEvent e) { super.init(e); } @Override public void postInit(FMLPostInitializationEvent e) { super.postInit(e); } } (ClientProxy is the same but called Clientproxy) Register these classes as proxies in your main class (Where your preinit, init etc. are registered) like so: @SidedProxy(clientSide="package.clientproxy", serverSide="package.serverproxy") public static CommonProxy proxy; Since you already registered a static reference to your commonproxy and a bridge to your client and serverproxies by calling sidedproxy you can now call your commonproxy in the main methods. Add Main.proxy.preInit(e); to your Main preInit method like such: @EventHandler public void preInit(FMLPreInitializationEvent e) { Main.proxy.preInit(e); } public static BarPacketHandler packetHandler; @EventHandler public void init(FMLInitializationEvent e) { Main.proxy.init(e); } @EventHandler public void postInit(FMLPostInitializationEvent e) { Main.proxy.postInit(e); } Obviously these are all just basic, rough drafts that you'd have to adapt to your class. But if you know Java to any degree you should be able to figure out what I said (hopefully. English isn't my first language). Now when you want a method in your client only, you add the registry/call to ClientProxy under the right place. CommonProxy will call everything that runs on both and ServerProxy runs on the server.
  21. Welp. That's it. I've tried to change it to a similar code. But I was using ctx instead of Minecraft.GetMinecraft to initiate my IthreadListener. It seems like every time I get stuck on something for multiple hours it turns out to be a big oversight I should've noticed. For future readers who run into my topic. The final code for my onMessage ended up being @Override public IMessage onMessage(final BarMessage content,final MessageContext ctx) { IThreadListener myThread = Minecraft.getMinecraft(); myThread.addScheduledTask(new Runnable(){ @Override public void run(){ System.out.println("messagehandler called"); final IBarHandler handler = Minecraft.getMinecraft().thePlayer.getCapability(CAPABILITY_BAR, EnumFacing.DOWN); NBTTagCompound tag = content.toSend; handler.setMana(tag.getInteger("mana")); handler.setMaxMana(tag.getInteger("maxmana")); handler.setHealth(tag.getInteger("health")); handler.setMaxHealth(tag.getInteger("maxhealth")); handler.setFatigue(tag.getInteger("fatigue")); } }); return null; } Thanks for the help everyone.
  22. The Nullpointer exception only occurs when I try to register an entity from Minecraft.GetMinecraft.theplayer.getCapability instead of PlayerEntityMP player = ctx.getServer etc. etc. java.lang.NullPointerException at com.cheese.rpvp.capabilities.synchers.BarMessage$MessageHandler.onMessage(BarMessage.java:47) ~[BarMessage$MessageHandler.class:?] at com.cheese.rpvp.capabilities.synchers.BarMessage$MessageHandler.onMessage(BarMessage.java:40) ~[BarMessage$MessageHandler.class:?] at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(SimpleChannelHandlerWrapper.java:56) ~[SimpleChannelHandlerWrapper.class:?] at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(SimpleChannelHandlerWrapper.java:36) ~[SimpleChannelHandlerWrapper.class:?] at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) ~[SimpleChannelInboundHandler.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) ~[AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) ~[AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) ~[MessageToMessageDecoder.class:4.0.23.Final] at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) ~[MessageToMessageCodec.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) ~[AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) ~[AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) ~[DefaultChannelPipeline.class:4.0.23.Final] at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169) ~[EmbeddedChannel.class:4.0.23.Final] at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.processPacket(FMLProxyPacket.java:109) [FMLProxyPacket.class:?] at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:157) [NetworkManager.class:?] at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:51) [NetworkManager.class:?] at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [SimpleChannelInboundHandler.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final] at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.handleClientSideCustomPacket(NetworkDispatcher.java:410) [NetworkDispatcher.class:?] at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:276) [NetworkDispatcher.class:?] at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:73) [NetworkDispatcher.class:?] at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [SimpleChannelInboundHandler.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) [DefaultChannelPipeline.class:4.0.23.Final] at io.netty.channel.local.LocalChannel.finishPeerRead(LocalChannel.java:326) [LocalChannel.class:4.0.23.Final] at io.netty.channel.local.LocalChannel.access$400(LocalChannel.java:45) [LocalChannel.class:4.0.23.Final] at io.netty.channel.local.LocalChannel$5.run(LocalChannel.java:312) [LocalChannel$5.class:4.0.23.Final] at io.netty.channel.local.LocalEventLoop.run(LocalEventLoop.java:33) [LocalEventLoop.class:4.0.23.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116) [SingleThreadEventExecutor$2.class:4.0.23.Final] at java.lang.Thread.run(Thread.java:748) [?:1.8.0_144] My Capability is registered in my main class in the preInit as such: CustomDataHandlerBar.register(); which obviously tells you nothing. the Barhandler is public class CustomDataHandlerBar { @CapabilityInject(IBarHandler.class) public static final Capability<IBarHandler> CAPABILITY_BAR = null; public static void register(){ CapabilityManager.INSTANCE.register(IBarHandler.class, new Storage(), DefaultBarHandler.class); MinecraftForge.EVENT_BUS.register(new CustomDataHandlerBar()); } @SubscribeEvent public void attachCapabilities(AttachCapabilitiesEvent<Entity> event){ if(event.getObject() instanceof EntityPlayer) event.addCapability(new ResourceLocation(Main.MODID, "BARS"), new BarProvider()); } @SubscribeEvent public void clonePlayer(PlayerEvent.Clone event){ final IBarHandler original = getHandler(event.getOriginal()); final IBarHandler clone = getHandler(event.getEntity()); clone.setMana(original.getMana()); clone.setMaxMana(original.getMaxMana()); clone.setHealth(original.getHealth()); clone.setMaxHealth(original.getMaxHealth()); clone.setFatigue(original.getFatigue()); } @SubscribeEvent public void loggedIn(PlayerLoggedInEvent event){ if(!event.player.worldObj.isRemote) { if (event.player.hasCapability(CAPABILITY_BAR, EnumFacing.DOWN)) { final IBarHandler instance = getHandler(event.player); final NBTTagCompound tag = new NBTTagCompound(); tag.setInteger("mana", instance.getMana()); tag.setInteger("health", instance.getHealth()); tag.setInteger("fatigue", instance.getFatigue()); tag.setInteger("maxhealth", instance.getMaxHealth()); tag.setInteger("maxmana", instance.getMaxMana()); Main.packetHandler.barWrapper.sendTo(new BarMessage(tag), (EntityPlayerMP)event.player); System.out.println("Message sent"); } } } public static IBarHandler getHandler(Entity entity){ if(entity.hasCapability(CAPABILITY_BAR, EnumFacing.DOWN)){ System.out.println("Player has capability"); return entity.getCapability(CAPABILITY_BAR, EnumFacing.DOWN); } return null; } } I'm able to interact with the Capability and I'm able to set different values using items and equipment and such. I'm not sure if the problem lies with the Capability system. Though I'm not entirely sure why the server end saves my information properly yet the Client doesn't synchronise with it. The Forge classes are pretty complex for someone with only a year of Java experience and there's not a lot of online knowledge to find on the current version and what to use, I'm mostly just going by feel and the official docs, which also don't cover much. That's why I'm creating the packet, to keep the client synchronized and to learn how to create packets for the future. Also, when I comment out the Capabilities stuff in the original entityplayerMP = method I'm still getting the same Can't cast error.
  23. Hey again. I've managed to succesfully implement a few different capabilities. However when I open a world the Server gets the correct values while my client doesn't. To solve this I thought I'd implement a packet that sends NBT data to the client and uses my Capabilities wrapper to set the correct values. The error I get is the following: java.lang.ClassCastException: net.minecraft.client.network.NetHandlerPlayClient cannot be cast to net.minecraft.network.NetHandlerPlayServer at net.minecraftforge.fml.common.network.simpleimpl.MessageContext.getServerHandler(MessageContext.java:55) ~[MessageContext.class:?] at com.cheese.rpvp.capabilities.synchers.BarMessage$MessageHandler.onMessage(BarMessage.java:46) ~[BarMessage$MessageHandler.class:?] at com.cheese.rpvp.capabilities.synchers.BarMessage$MessageHandler.onMessage(BarMessage.java:38) ~[BarMessage$MessageHandler.class:?] at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(SimpleChannelHandlerWrapper.java:56) ~[SimpleChannelHandlerWrapper.class:?] at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(SimpleChannelHandlerWrapper.java:36) ~[SimpleChannelHandlerWrapper.class:?] at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) ~[SimpleChannelInboundHandler.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) ~[AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) ~[AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) ~[MessageToMessageDecoder.class:4.0.23.Final] at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) ~[MessageToMessageCodec.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) ~[AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) ~[AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) ~[DefaultChannelPipeline.class:4.0.23.Final] at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169) ~[EmbeddedChannel.class:4.0.23.Final] at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.processPacket(FMLProxyPacket.java:109) [FMLProxyPacket.class:?] at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:157) [NetworkManager.class:?] at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:51) [NetworkManager.class:?] at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [SimpleChannelInboundHandler.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final] at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.handleClientSideCustomPacket(NetworkDispatcher.java:410) [NetworkDispatcher.class:?] at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:276) [NetworkDispatcher.class:?] at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:73) [NetworkDispatcher.class:?] at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [SimpleChannelInboundHandler.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) [DefaultChannelPipeline.class:4.0.23.Final] at io.netty.channel.local.LocalChannel.finishPeerRead(LocalChannel.java:326) [LocalChannel.class:4.0.23.Final] at io.netty.channel.local.LocalChannel.access$400(LocalChannel.java:45) [LocalChannel.class:4.0.23.Final] at io.netty.channel.local.LocalChannel$5.run(LocalChannel.java:312) [LocalChannel$5.class:4.0.23.Final] at io.netty.channel.local.LocalEventLoop.run(LocalEventLoop.java:33) [LocalEventLoop.class:4.0.23.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116) [SingleThreadEventExecutor$2.class:4.0.23.Final] at java.lang.Thread.run(Thread.java:748) [?:1.8.0_144] My classes are as follows: package com.cheese.rpvp.capabilities.synchers; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; public class BarPacketHandler { public static final SimpleNetworkWrapper barWrapper = NetworkRegistry.INSTANCE.newSimpleChannel("rpvp"); } This package defines my simpleChannel named rpvp after my client info. I create an instance of this class in my Main class with public static BarPacketHandler packetHandler; and then register it in my commonProxy like so: BarPacketHandler.barWrapper.registerMessage(BarMessage.MessageHandler.class, BarMessage.class, 1, Side.CLIENT); My goal here is to send a packet from the server (Since the server has the correct values) and pass them on to the client. Since the client needs to be updated. I subscribed an Event for PlayerLoggedInEvent that will get my Capability and save all relevant info to be updated to an NBTTagCompound and then calls the sendTo method from my Message class. @SubscribeEvent public void loggedIn(PlayerLoggedInEvent event){ if(!event.player.worldObj.isRemote) { if (event.player.hasCapability(CAPABILITY_BAR, EnumFacing.DOWN)) { final IBarHandler instance = getHandler(event.player); final NBTTagCompound tag = new NBTTagCompound(); tag.setInteger("mana", instance.getMana()); tag.setInteger("health", instance.getHealth()); tag.setInteger("fatigue", instance.getFatigue()); tag.setInteger("maxhealth", instance.getMaxHealth()); tag.setInteger("maxmana", instance.getMaxMana()); Main.packetHandler.barWrapper.sendTo(new BarMessage(tag), (EntityPlayerMP)event.player); System.out.println("Message sent"); } } } Then finally we have the actual BarMessage class with an inner class "MessageHandler". Both have the default method, so that can't be the error. public class BarMessage implements IMessage { public BarMessage(){} private NBTTagCompound toSend; public BarMessage(NBTTagCompound tag){ this.toSend = tag; } @Override public void toBytes(ByteBuf buf) { System.out.println("toBytes called"); ByteBufUtils.writeTag(buf, this.toSend); } @Override public void fromBytes(ByteBuf buf) { System.out.println("frombytes called"); this.toSend = ByteBufUtils.readTag(buf); } public NBTTagCompound getTag(){ return toSend; } public static class MessageHandler implements IMessageHandler<BarMessage, IMessage> { public MessageHandler(){} @Override public IMessage onMessage(BarMessage content, MessageContext ctx) { System.out.println("messagehandler called"); EntityPlayerMP serverPlayer = ctx.getServerHandler().playerEntity; final IBarHandler handler = getHandler(serverPlayer); NBTTagCompound tag = content.toSend; handler.setMana(tag.getInteger("mana")); handler.setMaxMana(tag.getInteger("maxmana")); handler.setHealth(tag.getInteger("health")); handler.setMaxHealth(tag.getInteger("maxhealth")); handler.setFatigue(tag.getInteger("fatigue")); return null; } } } I have also tried a Variant of the onMessage where I've set content and ctx to final and tried to make an inner class that uses a scheduled task to set these things, but I assumed that since I'm not influencing the world directly it shouldn't be a problem. Now the main Issue I examined the MessageContext class, which returns the nethandler. Somewhere in my code I've somehow set my nethandler to NetHandlerPlayClient, and when I try to cast it using the getServerHandler it crashes since I only have the NetHandlerPlayClient. I know I must be making some simple mistake that I overlooked, I've googled for a few hours now and It's driving me crazy. I've tried to find a way to access playerEntity outside of the ctx, but that didn't work. I need playerEntity to pass to my getHandler(playerEntity) so I can call the methods for setting my Capabilities, the server sends the Target player with the message. so the Packet gets executed on the Client. I assumed that since I was running the handler on the client I could somehow use final IBarHandler handler = Minecraft.getMinecraft().thePlayer().GetCapability(CAPABILITY_BAR); But that returned a nullpointer exception. I've followed the documentation at https://mcforge.readthedocs.io/en/latest/networking/simpleimpl/ to the T, I don't quite understand what I'm doing wrong here, or what I could do to improve. Some hints would be appreciated.
  24. My bad. I'm a bigger idiot than I thought, I'm sorry for misunderstanding. English isn't my main language. I thought you meant the new ModelLoaderResource that you'd use in the original long string, I get what you mean now. Thanks for the help!
×
×
  • Create New...

Important Information

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