Jump to content

Same Blocks - Different Redstone Signals


Stjubit

Recommended Posts

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

Option 2 is not possible. You have to use WorldSavedData to save and load your data from the world.

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/

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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...

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

I made a few Screenshots from what i've been doing here:

 

 

 

Here is the WirelessReceiver:

67n0BNu.png

 

...and here is the WirelessController:

7i1vkcl.png

 

 

 

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.
}

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

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

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

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

×   Your previous content has been restored.   Clear editor

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

Announcements



×
×
  • Create New...

Important Information

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