Stjubit Posted July 18, 2015 Posted July 18, 2015 Hello, Is there any way you can place a few Blocks of the same class, which send out different Redstone signals? Example: I have a block-class "Redstone Sender" and i place a few of them into my world. Now i want to make one block to provide redstone power and the other blocks don't. The problem is, if I change the isProvidingWeakPower-method of a block i get out of "world.getBlock(x,y,z)", every Block in the world changes. I hope you understand my problem. With best regards, Julian Quote
Stjubit Posted July 18, 2015 Author Posted July 18, 2015 Thank you, helped a lot Another question: I need to have all Blocks at every time. Is it better to store the coordinates of them in an external file or should i get all of them in the InitializationEvent with "Minecraft.getMinecraft().theWorld.loadedTileEntityList" and filter the BlockTileEntities out of the List? I would prefer the second way, but I would just like to know your opinion. PS: diesieben07 i saw that you're from Germany. I'm from Austria Thanks, Julian Quote
coolAlias Posted July 18, 2015 Posted July 18, 2015 What do you mean by "all Blocks", the instance of the Block class, or every single block in the world? What are you trying to accomplish by storing this information? Quote http://i.imgur.com/NdrFdld.png[/img]
larsgerrits Posted July 18, 2015 Posted July 18, 2015 Option 2 is not possible. You have to use WorldSavedData to save and load your data from the world. Quote Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support. 1.12 -> 1.13 primer by williewillus. 1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support. http://www.howoldisminecraft1710.today/
Stjubit Posted July 18, 2015 Author Posted July 18, 2015 I have a Block which controls the Redstone output of other blocks. This other blocks are Wireless Receiver. They have a frequency with which you can control the block from the Redstone Controller. Example: The Wireless Receiver has the frequency 123 and you define 123 to output a redstone signal in the Wireless Controller. When you restart Minecraft or the Server, all this Wireless Receivers have to be located to control them in the Wireless Controller. So i got the idea to get all TileEntities when Minecraft/the Server starts, but the problem is, that the frequency is ever 0 in the TileEntity. Has anyone got a clue, how i should accomplish this? Quote
coolAlias Posted July 18, 2015 Posted July 18, 2015 Are you modding for 1.8? If so, modded TileEntity data is destroyed by default, rather than preserved, unless you override #shouldRefresh in your TileEntity class to return a sane value (i.e. return the same condition that causes vanilla TileEntities to refresh, rather than always true). See here for more information. If the TileEntities are not your own and you are trying to 'tack on' information, then it would probably be easiest to store a list of controlled block coordinates / positions in YOUR TileEntity and let your TE save / load that data. So if your TE controls a block at 1/1/1 and 3/3/3, it saves those coordinates and when the game loads back up, it knows to check those blocks. Be warned that this kind of system does not scale well - if you plan on having your TE control thousands of blocks at once, well, good luck. Quote http://i.imgur.com/NdrFdld.png[/img]
Stjubit Posted July 18, 2015 Author Posted July 18, 2015 I'm modding for Minecraft 1.7.10. Well, the controller doesn't control only one frequency. In the controller-gui is a TextField, where you can enter the frequency, and two GuiButtons which control the Redstone-signal (on/off). So this isn't possible in my case. My WirelessReceiverTileEntitiy just saves the frequency it has and it's current redstone signal. If the frequency of the WirelessReceiver matches with the frequency I got from the TextField, the Redstone-signal should change. So i need to iterate through all of my WirelessReceiverTileEntities and check, if the frequency matches. I need to have a List of the TileEntities before i can iterate through them and that's the problem. I hope anybody can understand this, Julian Quote
coolAlias Posted July 18, 2015 Posted July 18, 2015 Is this not sufficient? World#loadedTileEntityList Quote http://i.imgur.com/NdrFdld.png[/img]
Stjubit Posted July 18, 2015 Author Posted July 18, 2015 Maybe! The problem is, that the frequency in this TileEntities loaded by "world.loadedTileEntityList" is always 0. Maybe it's 0 because the readFromNBT()-method won't be executed at the time. So this method is not a option I think. I really don't know how I could do this. Quote
coolAlias Posted July 18, 2015 Posted July 18, 2015 Maybe! The problem is, that the frequency in this TileEntities loaded by "world.loadedTileEntityList" is always 0. Maybe it's 0 because the readFromNBT()-method won't be executed at the time. So this method is not a option I think. I really don't know how I could do this. How are you setting the frequency in these TileEntities? You mentioned a GUI - are you sending packets to the server? If not, that's why you always get 0... Quote http://i.imgur.com/NdrFdld.png[/img]
Stjubit Posted July 18, 2015 Author Posted July 18, 2015 Yes, i have a GUI where i can set the frequency and yes, i'm sending packets to the server and to the client. Everything works perfect, there. So, is it the only way to do it with the loadedTileEntities-List? I can show you my project, if you want to. Do you have Skype or something like that? Quote
coolAlias Posted July 18, 2015 Posted July 18, 2015 I'm pretty sure that all of the TileEntities in loadedTileEntitiesList should have their correct data as loaded from NBT, but I've never actually used it. Perhaps you are not saving / loading your TileEntity properly? Are you using the exact same string to load as you do to save? It would be simpler if you had a Github repository or something that I could look at online, or post your TileEntity, Gui, and IMessage classes on pastebin. Quote http://i.imgur.com/NdrFdld.png[/img]
Stjubit Posted July 18, 2015 Author Posted July 18, 2015 I'm 100% sure that i've saved all correctly. Otherwise it wouldn't be there after i restarted everything. Here is my code for the initialization of my TileEntity-List: public static List<WirelessReceiverTileEntity> wirelessReceiverTileEntities = null; public void initWirelessReceiverTileEntities() { wirelessReceiverTileEntities = new ArrayList<WirelessReceiverTileEntity>(); List tiles = Minecraft.getMinecraft().theWorld.loadedTileEntityList; for(int i=0;i<tiles.size();i++) { if(tiles.get(i) instanceof WirelessReceiverTileEntity) { WirelessReceiverTileEntity wrte = (WirelessReceiverTileEntity) tiles.get(i); wirelessReceiverTileEntities.add(wrte); } } } When i need the List (wirelessReceiverTileEntities), i check if the List is null. If it's null, I call the initWirelessReceiverTileEntities()-method and it will be initialized, but every WirelessReceiverTileEntity's frequency is 0. Here is my WirelessReceiverTileEntity-class: public class WirelessReceiverTileEntity extends TileEntity { int frequency; boolean redstonesignal; public WirelessReceiverTileEntity() { } public void setFrequency(int frequency) { this.frequency = frequency; this.markForUpdate(); } public int getFrequency() { return frequency; } public boolean isRedstonesignal() { return redstonesignal; } public void setRedstonesignal(boolean redstonesignal) { this.redstonesignal = redstonesignal; this.markForUpdate(); } public void markForUpdate() { this.worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); this.markDirty(); } @Override public void writeToNBT(NBTTagCompound nbtTagCompound) { super.writeToNBT(nbtTagCompound); nbtTagCompound.setInteger("Frequency", frequency); nbtTagCompound.setBoolean("Redstonesignal", redstonesignal); } @Override public void readFromNBT(NBTTagCompound nbtTagCompound) { super.readFromNBT(nbtTagCompound); frequency = nbtTagCompound.getInteger("Frequency"); redstonesignal = nbtTagCompound.getBoolean("Redstonesignal"); } } The reason why i don't initialize the TileEntity-List at the startup of the mod is, because the loadedTileEntitiesList is null at the time. Quote
coolAlias Posted July 18, 2015 Posted July 18, 2015 Here's your problem right here: Minecraft.getMinecraft().theWorld Minecraft is CLIENT side only. Also, you shouldn't try to store the loaded TileEntities in your class; instead, whenever you need them, get the list from the current world object (every TE has a worldObj, btw). Quote http://i.imgur.com/NdrFdld.png[/img]
Stjubit Posted July 18, 2015 Author Posted July 18, 2015 Okay, thanks. I will try it out. I just thought putting the List into a class and every time when something changes, updating the list, would be much better in performances. I will try it out and i will write back, soon. Quote
Stjubit Posted July 18, 2015 Author Posted July 18, 2015 It's not working. The frequency is always 0 Here's my code for changing the Redstone-signal in my WirelessController: public void changeWirelessReceiverRedstoneSignal(boolean redstoneSignal, int frequency) { World world = ccte.getWorldObj(); List<TileEntity> tiles = world.loadedTileEntityList; for(TileEntity tileEntity:tiles) { if(tileEntity !=null && tileEntity instanceof WirelessReceiverTileEntity) { WirelessReceiverTileEntity wrte = (WirelessReceiverTileEntity) tileEntity; if(wrte.getFrequency() == frequency) { wrte.setRedstonesignal(redstoneSignal); } } } } Quote
coolAlias Posted July 18, 2015 Posted July 18, 2015 And where is that method called from? How do you know the frequency is always 0, are you printing it out? Quote http://i.imgur.com/NdrFdld.png[/img]
Stjubit Posted July 18, 2015 Author Posted July 18, 2015 I made a few Screenshots from what i've been doing here: Here is the WirelessReceiver: ...and here is the WirelessController: The method is called when i click on the "On"-Button of the WirelessController (see image above). I'm not printing the frequency out, but i've set a Breakpoint and debugged the Mod. Quote
coolAlias Posted July 18, 2015 Posted July 18, 2015 That's what I've been trying to tell you - you GUI is CLIENT side, and the CLIENT side does NOT know about the values in your TileEntity by default. You need to send a packet from your Gui to the server saying "the player pressed button X, now what?" and let the server process everything, since TileEntity data should only ever be set on the server side (setting it client side does nothing, in other words). If the player can set the frequency as well, you need to send that data in the packet. Quote http://i.imgur.com/NdrFdld.png[/img]
Stjubit Posted July 18, 2015 Author Posted July 18, 2015 Thank you very much. Is there any way to send the redstonesignal and the frequency to the server at the same time? Or should i make two packets (one for turning redstone signal on and one for off) which only sends the frequency? EDIT: I chose the way with two packets and everything works perfect! Thank you soooo much coolAlias, you helped a lot Quote
Stjubit Posted July 18, 2015 Author Posted July 18, 2015 I don't know if this is the right place to ask for it, but here we go: My Block's isProvidingWeakPower()-method looks in it's TileEntity, if the redstonesignal is true. If it's true, the method will return 20 (to emit redstone). If it's false, the method will return 0 (to not emit redstone). Anyway, this method is only called, when a neighbor changed or something like that. So i ever need to break anything near the block, which should emit redstone. When i did that, the Block updates and the isProvidingWeakPower()-method is called. Now, the block emits the right redstonesignal. Is there any way to update the Block immediatly after I changed the TileEntity's redstonesignal? I looked at a few Minecraft-classes like the Redstone-Torch, but I haven't figured anything out. Julian Quote
coolAlias Posted July 18, 2015 Posted July 18, 2015 You can send as much information as you want (within reason) in a packet, and it is better to send one with 2 fields than 2 with 1 field if both pieces of information are always sent at the same time. You can force a block to update at any time by marking it: worldObj.markBlockForUpdate(pos); Quote http://i.imgur.com/NdrFdld.png[/img]
Stjubit Posted July 18, 2015 Author Posted July 18, 2015 You can send as much information as you want (within reason) in a packet, and it is better to send one with 2 fields than 2 with 1 field if both pieces of information are always sent at the same time. You can force a block to update at any time by marking it: worldObj.markBlockForUpdate(pos); So, i can just read/write like this? redstonesignal = ByteBufUtils.readVarInt(buf,1); frequency = ByteBufUtils.readVarInt(buf, 4); I tried the "worldObj.markBlockForUpdate(pos)"-operation before, but the redstone signal still only changed when I "changed" a neighbor-block. Can i call this method in my TileEntity (Server) or should i send a Packet to the client to update the Block with the "markBlockForUpdate()"-method? Quote
coolAlias Posted July 18, 2015 Posted July 18, 2015 markBlockForUpdate scheduleUpdate causes Block#updateTick to be called some number of ticks in the future, and from there you can perform the same logic or even call the neighbor method with whatever block you want. EDIT: markBlockForUpdate results in the TileEntity sending its description packet to all nearby client players. Although now that I think about it, you can just call whatever method you want on your block directly from your TileEntity. And saying that, if your Block/TileEntity are implemented properly, it should already be giving off the correct redstone signal without you having to do anything... can you show where you set and return the redstone power? As for the packet, you don't have to use ByteBufUtils for everything: ByteBuf can read and write most values directly. read(ByteBuf buffer) { int i = buffer.readInt(); float f = buffer.readFloat(); // etc. } Quote http://i.imgur.com/NdrFdld.png[/img]
coolAlias Posted July 18, 2015 Posted July 18, 2015 markBlockForUpdate causes Block#updateTick to be called the next tickAhem... no. Er, I meant scheduleUpdate (which can schedule a number of ticks in the future, not just the next one)... Quote http://i.imgur.com/NdrFdld.png[/img]
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.