I'd like someone to post the complete code (perhaps through Pastebin or GitHub in addition to here) for a simple Forge mod that does a specific simple task. I want to see all the classes and methods involved. Since this [incomplete] mod will do just one specific thing, there should not be too much involved.
All the mod needs to do is add a new block that lets you right-click the block and enter a string of text that gets saved to that block's tile entity. If you right-click it later, the text you previously entered will be displayed and you have the option of changing that text to something new at that time if you wish to do so. More importantly, if you exit the world or leave Minecraft completely and then reload the world again later, the last text you entered into that block will still be there.
Or you could not be as lazy as the people who use Mcreater or crappy other programs like that and learn java or at least look at the forges wiki. I am assuming that you don't know java or understand how to use google due to your request for other people to make you a mod, instead of you trying it out and then asking for help. Here are some links that will help you learn java.
Head developer for the CivilMagicks former developer for runix
Apparently I'm a horrible person for telling people the the truth. If telling people that MCreater and programs like it are crap and used by lazy people unwilling to learn java then I'm a horrible person and I'm ok with it
Or you could not be as lazy as the people who use Mcreater or crappy other programs like that and learn java or at least look at the forges wiki. I am assuming that you don't know java or understand how to use google due to your request for other people to make you a mod, instead of you trying it out and then asking for help. Here are some links that will help you learn java.
I have looked through the Forge tutorials extensively. Some of the specific information that I need is not clearly explained even though most of it works. Some of the tutorials are outdated in places or don't appear to match up well with other tutorials there or many other issues.
I have looked through many other tutorials here and other sites and have Googled for additional information. Yet, the same problems as above etc. Apparently, I keep missing something or something gets lost in translation on the specific portion I need.
I have not tried MCreator or similar "mod creator" programs.
I know Java but, again, apparently something is getting lost in translation with how to do a specific task with Forge coding.
I have actually tried this myself with all of the tutorials, etc, etc. I had even gotten it to work fine using ModLoader instead of Forge previous to Minecraft 1.4.2. After that point, with the "server/client" combination change to Minecraft, I could no longer get it to work with ModLoader either and I was wanting to switch over to Forge instead anyhow.
I tried to save everyone on an extensive detailed explanation on all of this because, if you're not complaining about not having enough information, you're complaining about having too much information.
This forum section is a place to ask for help and people give tutorials for specific items showing all of the different code segments. Unlike you, some people actually tend to try and be helpful instead.
Asking for the complete set of code for just this extremely simplified functionality is so no step is missed and nothing gets lost in translation. Plus, it's not enough to use as a mod on its own. I did not ask for a complete set of code for a truly functional mod but rather the complete set of code to accomplish a task.
Even if the complete code finally resolved the issue, credit would be given for the help.
So in other words, you want someone to code the whole mod for you and take their credit. No going to happen.
See my reply to the above. Especially items 8 and 9. Again, the whole set of code showing how to get the specific functionality to work is not enough for a mod on its own. Really, a block that does absolutely nothing but hold a string of text? And, again as also stated, credit would be given for the help.
I apologize for before. A lot of people on here ask for snippets and stuff and take all the credit.
In your TileEntity, you are going to need to simply add something like this into it. This will save the string to the TileEntity.
private String text = "";
public void writeToNBT(NBTTagCompound par1NBTTagCompound)
{
super.writeToNBT(par1NBTTagCompound);
par1NBTTagCompound.setString("Text", text);
}
public void readFromNBT(NBTTagCompound par1NBTTagCompound)
{
super.readFromNBT(par1NBTTagCompound);
this.text = par1NBTTagCompound.getString("Text");
}
You are also going to need to sync the string with the server. This is quite complicated if you are new to packets.
Add these two methods into your TileEntity. They will be called when you send a packet to it.
@Override
public Packet getDescriptionPacket()
{
NBTTagCompound var1 = new NBTTagCompound();
this.writeToNBT(var1);
return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 2, var1);
}
@Override
public void onDataPacket(INetworkManager netManager, Packet132TileEntityData packet)
{
readFromNBT(packet.data);
}
To sync the TileEntity with the Client and Server, you will first need to create a packet handler. Simply create a new class called PacketManager and make it implement IPacketHandler.
You should now be required to add a method called onPacketData as IPacketHandler is an interface.
Inside the method, we need to create an input stream. This will read the packet data.
Where it says, insert_channel_name, insert a unique name that no other mod would use. Preferable your mod's name in acronym form (e.g. Example Mod becomes EM) then add the type of data the channel is sending (e.g. EMString).
So if packet.channel equals insert_channel_name, it will run the code inside of it. We need 3 important variables to actually sync the TileEntity. The x, y and z coords. These will be defined when sending the packet to the server. Then the last variable is the text itself. Basically the code checks if the TileEntity at x, y, z is TileEntityExample, if it is then it will set the text to the one you sent in the packet.
The last bit in the code will send the updates to players all around so the text will change for them. If you didn't add this, it would be different for all players.
@Override
public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player)
{
DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(packet.data));
EntityPlayer entityPlayer = (EntityPlayer) player;
EntityPlayerMP entityPlayerMP = (EntityPlayerMP) entityPlayer;
if (packet.channel.equals("insert_channel_name"))
{
int x = inputStream.readInt();
int y = inputStream.readInt();
int z = inputStream.readInt();
String text = inputStream.readUTF();
TileEntity tile_entity = entityPlayerMP.getBlockTileEntity(x, y, z);
if(tile_entity instanceof TileEntityExample)
{
TileEntityExample tee = (TileEntityExample) tile_entity;
tee.text = text;
PacketDispatcher.sendPacketToAllAround(x, y, z, 100, entityPlayerMP.dimension, tee.getDescriptionPacket());
}
}
}
Now we need to register the packet handler. This requires adding a @NetworkMod annotation in the mod class. Again, replace insert_channel_name with your unique name from above.
You will need to get an instance of your TileEntity in this bit. That can be done in your GUI handler. You will only need to do this on the client side as its not a container GUI.
@Override
public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z)
{
TileEntity tile_entity = world.getBlockTileEntity(x, y, z);
if(tile_entity instanceof TileEntityExample)
{
return new GuiExample((TileEntityExample) tile_entity);
}
}
This is the method which the actionPeformed calls above. Again, replace insert_channel_name with your unique name. This will write the coordinates of the tile entity and the text from the text field into a output stream which then will be sent to the server for processing.
I believe that is really it. That should save the text and sync it with the server and other players. Then you can simple add something like this in your block class to display the text.
public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
{
TileEntity tile_entity = par1World.getBlockTileEntity(par2, par3, par4);
if (tile_entity instanceof TileEntityExample)
{
TileEntityExample tee = (TileEntityExample) tile_entity;
if(!par1World.isRemote) par5EntityPlayer.addChatMessage(tee.text);
}
}
I apologize for before. A lot of people on here ask for snippets and stuff and take all the credit. In your TileEntity, you are going to need to simply add something like this into it. This will save the string to the TileEntity.
private String text = ""; public void writeToNBT(NBTTagCompound par1NBTTagCompound) { super.writeToNBT(par1NBTTagCompound); par1NBTTagCompound.setString("Text", text); } public void readFromNBT(NBTTagCompound par1NBTTagCompound) { super.readFromNBT(par1NBTTagCompound); this.text = par1NBTTagCompound.getString("Text"); }
You are also going to need to sync the string with the server. This is quite complicated if you are new to packets. Add these two methods into your TileEntity. They will be called when you send a packet to it.
@Override public Packet getDescriptionPacket() { NBTTagCompound var1 = new NBTTagCompound(); this.writeToNBT(var1); return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 2, var1); } @Override public void onDataPacket(INetworkManager netManager, Packet132TileEntityData packet) { readFromNBT(packet.data); }
To be continued...
Been there, tried that. Those sections of the code appear to be the easy part. That's one of the reasons why I was wanting to see the full set of code to see it all working in action together and to also know that someone did actually get it working. I have seen parts like this and can get the block to save text until I exit the world and reload it. So, it appears I'm doing something wrong with trying to send packet information to get it to sync with the server side of things. So, once again, I need all the code not just snippets. People often think I may need only one part because they may assume I'm having the problem in a specific area of the code when it may be another section of the code. And, with people giving different snippets that don't necessarily match up, that also makes it harder to find where the problem actually is.
But, thank you for understanding and trying to help now.
In the meantime, I have apparently found someone that is willing to actually write a quick FULL set of code to fully illustrate the functionality and show it all working together so nothing is missed. I may just have to wait a couple of days but he appears to be willing to work with me to try and figure this out.
1) Create a block
2) Create a GuiScreen
3) Create a GuiTextField Obj
4) Initalise it, render it and all that jazz, really not that difficult, almost like regular buttons.
5) Save the text of the text field to the nbt in the tile entity.
6) Set the GuiTextField text to the saved text located in the TileEntity Done.
Of course you're not going to find a tutorial on this, because its so specific. However, if you break it up, like I just did, you could probably find tutorials, for example, there is tile entity tutorials which include saving variables. There is PROBABLY a GuiTextField tutorial, if not, then ask for help on that specific thing The rest is mostly simple
That's another one of my points about finding a complete tutorial on it. And, as I stated previously, I have found snippets and tutorials for different parts of it. And, most of it I don't really need. However, I finally decided that I need to see a complete set of code together so it all matches and the person posting it knows it works rather than just particular snippets that "should" work etc.
Everyone, please remember to stay on topic. Although it's not against the forum rules to ask for exact code snipets in this section it is not recommended and as seen no the best way to go about doing it. Please stay on topic and avoid insulting other forum members. This is a blanket warning for everyone, any further arguments or off topic posts will warrant further action from the forum staff.
While I'm waiting for the complete set of code that is in the process of being made for me, it would still be appreciated if anyone else also wants to take a stab at making a complete tutorial for doing this functionality from beginning to end. Those partial tutorials suck and always leave something out and getting separate tutorials to work together is not ideal. And, no one seems to have made a complete tutorial on this subject like they have for many other processes.
I updated my post above. It should cover saving the text and syncing the tile entity with the server with packets.
Thanks! I took a quick peek and I'm looking forward to going over it in more detail. I've been a bit busy so, unfortunately, I probably won't be getting to it until Sunday at the soonest. So, in the meantime, I wanted to let you know I saw you updated it.
@Override
public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player)
{
DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(packet.data));
EntityPlayer entityPlayer = (EntityPlayer) player;
EntityPlayerMP entityPlayerMP = (EntityPlayerMP) entityPlayer;
if (packet.channel.equals("insert_channel_name"))
{
int x = inputStream.readInt();
int y = inputStream.readInt();
int z = inputStream.readInt();
String text = inputStream.readUTF();
TileEntity tile_entity = entityPlayerMP.getBlockTileEntity(x, y, z);
if(tile_entity instanceof TileEntityExample)
{
TileEntityExample tee = (TileEntityExample) tile_entity;
tee.text = text;
PacketDispatcher.sendPacketToAllAround(x, y, z, 100, entityPlayerMP.dimension, tee.getDescriptionPacket());
}
}
}
... as you pointed out.
For some reason, I had been trying to do that from within the TileEntity's "getDescriptionPacket" routine instead.
I am still doing some testing and additional experiments because it appears to not always update a change right away and might still have the old value if I exit the game immediately after changing it. I am also going to experiment with just sending it to the server or to "All In Dimension" rather than "All Around."
I also had to change a couple of minor things like adding "worldObj" for getting the block's tile entity from entityPlayerMP based on the version of the code I'm messing with at the moment. A few other odd things like that here and there. I'm also sending the update on the GUI being closed at the moment as opposed to the button being clicked. But, all I have the button doing at the moment is basically closing the GUI. So, the final block update doesn't need to take place until then. I also had to add an IOException Try-Catch in the Packet Handler.
Your instructions also cleared up some confusion I was having about the code apparently needing to use BOTH Packet250CustomPayload AND Packet132TileEntityData in different spots.
Again, THANK YOU!!!
I'll let you know if I run into any other problems!
Now, I just need to get back to work on finally updating my Circuit Cubes mod once again. This issue, that has plagued me for a LONG time, is what was preventing me from updating the mod.
When I finally do, I will definitely be giving you the very much deserved credit in the OP there!
Unfortunately, after I finally got this working despite it not syncing immediately, I checked an old bookmark I had to one of the Forge tutorials on their website since I had remembered something about the problem of it not syncing right away and I found that there is a HUGE change for 1.7.2 on how packets are handled:
All the mod needs to do is add a new block that lets you right-click the block and enter a string of text that gets saved to that block's tile entity. If you right-click it later, the text you previously entered will be displayed and you have the option of changing that text to something new at that time if you wish to do so. More importantly, if you exit the world or leave Minecraft completely and then reload the world again later, the last text you entered into that block will still be there.
http://docs.oracle.c...avase/tutorial/
http://www.youtube.c...LZ-JTdjogDKas8N
Apparently I'm a horrible person for telling people the the truth. If telling people that MCreater and programs like it are crap and used by lazy people unwilling to learn java then I'm a horrible person and I'm ok with it
Stop making stupid assumptions.
See my reply to the above. Especially items 8 and 9. Again, the whole set of code showing how to get the specific functionality to work is not enough for a mod on its own. Really, a block that does absolutely nothing but hold a string of text? And, again as also stated, credit would be given for the help.
In your TileEntity, you are going to need to simply add something like this into it. This will save the string to the TileEntity.
You are also going to need to sync the string with the server. This is quite complicated if you are new to packets.
Add these two methods into your TileEntity. They will be called when you send a packet to it.
To sync the TileEntity with the Client and Server, you will first need to create a packet handler. Simply create a new class called PacketManager and make it implement IPacketHandler.
You should now be required to add a method called onPacketData as IPacketHandler is an interface.
Inside the method, we need to create an input stream. This will read the packet data.
Where it says, insert_channel_name, insert a unique name that no other mod would use. Preferable your mod's name in acronym form (e.g. Example Mod becomes EM) then add the type of data the channel is sending (e.g. EMString).
So if packet.channel equals insert_channel_name, it will run the code inside of it. We need 3 important variables to actually sync the TileEntity. The x, y and z coords. These will be defined when sending the packet to the server. Then the last variable is the text itself. Basically the code checks if the TileEntity at x, y, z is TileEntityExample, if it is then it will set the text to the one you sent in the packet.
The last bit in the code will send the updates to players all around so the text will change for them. If you didn't add this, it would be different for all players.
Now we need to register the packet handler. This requires adding a @NetworkMod annotation in the mod class. Again, replace insert_channel_name with your unique name from above.
In your GUI class, you need to handle the action of the button to send a packet to the server. We will add the method sendStringToServer() later on.
You will need to get an instance of your TileEntity in this bit. That can be done in your GUI handler. You will only need to do this on the client side as its not a container GUI.
This is the method which the actionPeformed calls above. Again, replace insert_channel_name with your unique name. This will write the coordinates of the tile entity and the text from the text field into a output stream which then will be sent to the server for processing.
I believe that is really it. That should save the text and sync it with the server and other players. Then you can simple add something like this in your block class to display the text.
Been there, tried that. Those sections of the code appear to be the easy part. That's one of the reasons why I was wanting to see the full set of code to see it all working in action together and to also know that someone did actually get it working. I have seen parts like this and can get the block to save text until I exit the world and reload it. So, it appears I'm doing something wrong with trying to send packet information to get it to sync with the server side of things. So, once again, I need all the code not just snippets. People often think I may need only one part because they may assume I'm having the problem in a specific area of the code when it may be another section of the code. And, with people giving different snippets that don't necessarily match up, that also makes it harder to find where the problem actually is.
But, thank you for understanding and trying to help now.
In the meantime, I have apparently found someone that is willing to actually write a quick FULL set of code to fully illustrate the functionality and show it all working together so nothing is missed. I may just have to wait a couple of days but he appears to be willing to work with me to try and figure this out.
Did all that. Didn't work.
That's another one of my points about finding a complete tutorial on it. And, as I stated previously, I have found snippets and tutorials for different parts of it. And, most of it I don't really need. However, I finally decided that I need to see a complete set of code together so it all matches and the person posting it knows it works rather than just particular snippets that "should" work etc.
Thanks.
Farewell everyone o/
Thanks! I took a quick peek and I'm looking forward to going over it in more detail. I've been a bit busy so, unfortunately, I probably won't be getting to it until Sunday at the soonest. So, in the meantime, I wanted to let you know I saw you updated it.
Mr_Crayfish,
First off, ...
THANK YOU!!!
I believe I have FINALLY found the problem thanks to you!!!
I was extremely close and basically had most everything correct but it currently looks like my problem was here ...
It was apparently the line:
in:
... as you pointed out.
For some reason, I had been trying to do that from within the TileEntity's "getDescriptionPacket" routine instead.
I am still doing some testing and additional experiments because it appears to not always update a change right away and might still have the old value if I exit the game immediately after changing it. I am also going to experiment with just sending it to the server or to "All In Dimension" rather than "All Around."
I also had to change a couple of minor things like adding "worldObj" for getting the block's tile entity from entityPlayerMP based on the version of the code I'm messing with at the moment. A few other odd things like that here and there. I'm also sending the update on the GUI being closed at the moment as opposed to the button being clicked. But, all I have the button doing at the moment is basically closing the GUI. So, the final block update doesn't need to take place until then. I also had to add an IOException Try-Catch in the Packet Handler.
Your instructions also cleared up some confusion I was having about the code apparently needing to use BOTH Packet250CustomPayload AND Packet132TileEntityData in different spots.
Again, THANK YOU!!!
I'll let you know if I run into any other problems!
Now, I just need to get back to work on finally updating my Circuit Cubes mod once again. This issue, that has plagued me for a LONG time, is what was preventing me from updating the mod.
When I finally do, I will definitely be giving you the very much deserved credit in the OP there!
Me too.
Unfortunately, after I finally got this working despite it not syncing immediately, I checked an old bookmark I had to one of the Forge tutorials on their website since I had remembered something about the problem of it not syncing right away and I found that there is a HUGE change for 1.7.2 on how packets are handled:
http://www.minecraftforge.net/wiki/Tutorials/Packet_Handling
With a bunch of code examples there.
It looks like I may have to be starting from scratch again all over with this.