Jump to content

MineMaarten

Members
  • Posts

    169
  • Joined

  • Last visited

Posts posted by MineMaarten

  1. GuiScreen#initGui() should only be called when you open a GUI or when you change the resolution of your screen. This is already done for you, don't call it every render tick...

     

    To maybe solve your problem: Try rendering the textbox after you've drawn your screen. It could be that the textbox is now rendered behind your screen.

    this.BackGround();
    this.username.drawTextBox();
    

  2. If I look back at how I've done it, it looks the same as how Xenocider described. The difference is that I'm using .ogg files instead of .wav which caused problems for me as well. So try converting the sound file to .ogg and retrying. There is a String only method, look for example at an older version of my Minesweeper Mod:

     

    https://github.com/MineMaarten/MinesweeperMod/blob/d9fddc885f6ae5cba9342fd37abe7bd35e35e6be/src/minesweeperMod/client/MinesweeperSoundHandler.java

    https://github.com/MineMaarten/MinesweeperMod/blob/d9fddc885f6ae5cba9342fd37abe7bd35e35e6be/src/minesweeperMod/common/ItemMineDetector.java

  3. You also might have a look at my code to display tutorial messages from my Minesweeper Mod:

     

    TutorialHandler.java, when called onUpdate(), it will send messages if a certain timer runs out:

    https://github.com/MineMaarten/MinesweeperMod/blob/master/src/minesweeperMod/common/TutorialHandler.java

     

    MinesweeperTickHandler.java, which manages the TutorialHandlers and calls the onUpdate() every world tick:

    https://github.com/MineMaarten/MinesweeperMod/blob/master/src/minesweeperMod/common/MinesweeperTickHandler.java

  4. The rotations of the blocks mentioned by you are all saved in a thing what's called block metadata (and with those many more blocks). Also the difference between top/bottom halfslabs and stairs being upside down is saved in metadata. So I suggest looking up metadata (there's much to find on this topic).

  5. Or you could create the entity and inject an altered NBT tag in the Entity. Something like:

    CustomEntity entity = new CustomEntity(worldObj);
    NBTTagCompound tag = new NBTTagCompound();
    entity.writeEntityToNBT(tag);//create the base tag
    tag.setShort("Health", (short)10);//alter the tag, for instance here the health is changed. Bit devious but it's an example.
    entity.readEntityFromNBT(tag);//inject the entity with the altered tag.
    worldObj.spawnEntityInWorld(entity);
    

  6. So apparently updateSides() is only called on the server side. And no you shouldn't have gotten an error or something because you're calling a @SideOnly(Side.CLIENT) annotated method because that only will be the case if you test it on a dedicated server instead of the internal SSP one. You'll then see that just the line

    @SideOnly(Side.CLIENT)
    public boolean connect[] = {false, false, false, false, false, false};
    

    will throw an exception as the SideOnly notation only applies to the field and not it's initializer.

  7. @Override
        public Packet getDescriptionPacket(){
            NBTTagCompound tag = new NBTTagCompound();
            writeToNBT(tag);
            return new Packet132TileEntityData(xCoord, yCoord, zCoord, 0, tag);
        }
    
    @Override
        public void onDataPacket(INetworkManager net, Packet132TileEntityData pkt){
            readFromNBT(pkt.data);
        }
    
    public void sendDescriptionPacket(){
            PacketDispatcher.sendPacketToAllAround(xCoord, yCoord, zCoord, 64D, worldObj.provider.dimensionId, getDescriptionPacket());
        }

    sendDescriptionPacket() is a 'homemade' method with which you can send the nbt packet to the client whenever you want. The fewer packets you send the better though. So the best that you can do is simulating the same behaviour on the client and on the server and only send a packet when you know the client will be desynched.

  8. I'm using many of these in GUI's of my mod (PneumaticCraft) as well. It isn't something Vanilla/Forge you can hook into. It's coded from ground up. I've written a class that has lots of behaviours in it. When the player clicks on the tab, it toggles between opening/closing. Every update tick it increases it's height and width until they have reached their maximum. If they've reached that, they are allowed to render the text stored in the instance of this class. The value of width and height directly affect how big the tab is drawn. In the tab, it looks if it has a parent tab (a tab which when it expands should push this tab away). If so, it takes this parent tab height in account.

     

    This is just to give you an idea how I've done it. If you come to the conclusion you don't want to put that much time in it or if you think you'll not be able to do it I can announce that in PneumaticCraft's API (coming out in ~1 week) there is a way to retrieve you're own tabs (for your own GUI's). Problem is then that you'll be a dependent on PneumaticCraft. As being dependant upon a mod isn't the best, I suggest implementing you're own version of tabs using the expanation I've just given.

  9. Although I know there are build-in methods to synch the server with the client, The following solution uses the TileEntity packet. It gets your NBT data of the server, TileEntity#writeToNBT() (assuming you have that implemented), wraps that in a packet, and sends that to the clients which will handle that via TileEntity#readFromNBT(). So any variable you want to have synched with the client you can put in your NBT methods (fortunately these are often the same as the variables you want to save to disk with NBT).

     

    Put this in your TileEntity class:

    @Override
        public Packet getDescriptionPacket(){
            NBTTagCompound tag = new NBTTagCompound();
            writeToNBT(tag);
            return new Packet132TileEntityData(xCoord, yCoord, zCoord, 0, tag);
        }
    
    @Override
        public void onDataPacket(INetworkManager net, Packet132TileEntityData pkt){
            readFromNBT(pkt.data);
        }
    
    public void sendDescriptionPacket(){
            PacketDispatcher.sendPacketToAllAround(xCoord, yCoord, zCoord, 64D, worldObj.provider.dimensionId, getDescriptionPacket());
        }

     

    Now every time you want to send the clients(!) an update, you can invoke sendDescriptionPacket(). Keypoint where you want to do this is when you burn up a new burnable item, i.e. you're setting the burn timer again.

     

    Remember that you should only do this when you're sure clients will be desynched, because if you invoke sendDescriptionPacket() unnecessarily often this will affect the network. Also this will send an update packet to every player within 64 blocks of this TE, which is great in this example but may not be in others.

  10. As the Hopper's TileEntity class is rather large, I'll point you even more in the right direction.

     

    The reason why insertion and extraction of Furnaces is side dependant is because the Furnace's TileEntity is implementing ISidedInventory and the Hopper respects this.

    In TileEntityFurnace.java there is a method that specifies which slots refer to which side:

    /**
         * Returns an array containing the indices of the slots that can be accessed by automation on the given side of this
         * block.
         */
        public int[] getAccessibleSlotsFromSide(int par1)
        {
            return par1 == 0 ? slots_bottom : (par1 == 1 ? slots_top : slots_sides);
        }
    

    par1 is the side, so if the side == 0, the bottom slot(s) are returned, when side == 1 the top slots are returned and for the sides the side slots are returned.

     

    As I said, the Hopper respects this and does that in the following way (TileEntityHopper.java, line 278 in the suckItemsIntoHopper method) :

    byte b0 = 0;//b0 is the side, which is always the bottom (where it extracts from).
    
    if(iinventory instanceof ISidedInventory && b0 > -1) {
    ISidedInventory isidedinventory = (ISidedInventory)iinventory;
    int[] aint = isidedinventory.getAccessibleSlotsFromSide(b0);
    
    for(int element : aint) {
        if(insertStackFromInventory(par0Hopper, iinventory, element, b0)) {
              return true;
          }
        }
    }
    (...)
    

     

×
×
  • Create New...

Important Information

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