Jump to content

[1.14.2] TileEntity rendering + data syncing (+ TileEntity tick function every other tick)


Simon_kungen

Recommended Posts

Hi

 

I got my TileEntity working good now, now I want to add a type of render to it, and looking through the wiki the optimal way of doing it would be to use a TileEntityRendererFast. I would not say my TileEntity would be hard to render as it would only have to render a cuboid with varying alpha and texture depending on the TileEntity variables.

The issue I'm facing is that I have no idea how to do that, and better yet how to send the data to the client efficiently. I have it do stuff every tick, which is only changing one variable out of the three variables it stores, so I'm pretty sure using a custom message protocol is needed. The other two is what texture to use and whenever it should do a particle effect at the block (same texture). But I'm a bit lost about all this, going to write a summary and what little code I have on the TileEntityRendererFast and the actul TileEntity below:

 

A Tree Tap you place on a tree, I got the bucket and actual Tree Tap model working fine. The TileEntity stores what type of liquid it is (resin, water or none), whenever it can make the "bucket" start filling up with a particle effect and what volume there is in the bucket.

Something I was wondering is if there is a way to have a if statement that would only pass like every other tick or less, to simulate viscosity of different fluids and have the "drip" animation only happen that tick or something. That would also free up some of the network if I only need to send new information that particular tick.

 

2019-08-10_20_06_06_2.png.6f6fb37711f747f0939b7eb04939938d.png

 

 

TreeTapTileEntityRenderer.java

Spoiler

public class TreeTapTileEntityRenderer extends TileEntityRendererFast<TreeTapTileEntity>
{


    @Override
    public void renderTileEntityFast(TreeTapTileEntity te, double x, double y, double z, float partialTicks, int destroyStage, BufferBuilder buffer)
    {


    }
}

 

 

 

TreeTapTileEntity.java

Spoiler

public class TreeTapTileEntity extends TileEntity implements ITickableTileEntity
{

    private int volume = 0;
    private boolean canFill = false;
    private FluidType fluidType = FluidType.NONE;

    public TreeTapTileEntity()
    {
        super(IntercraftTileEntities.TREETAP);
    }


    @Override
    public void tick()
    {
        if (canFill) {
            if (volume < 1000) {
                setVolume(volume+1);

                


            }
        }
    }


    @Override
    public CompoundNBT write(CompoundNBT compound)
    {
        compound.putInt("volume", volume);
        compound.putBoolean("can_fill",canFill);
        compound.putString("fluid_type",fluidType.toString());

        return super.write(compound);
    }

    @Override
    public void read(CompoundNBT compound)
    {
        super.read(compound);
        volume = compound.getInt("volume");
        canFill = compound.getBoolean("can_fill");
        fluidType = FluidType.valueOf(compound.getString("fluid_type").toUpperCase());

    }


    public int getVolume()
    {
        return volume;
    }

    public boolean getCanFill()
    {
        return canFill;
    }

    public FluidType getFluidType()
    {
        return this.fluidType;
    }

    public void setVolume(int value)
    {
        volume = value;
        markDirty();
    }

    public void setCanFill(boolean bool)
    {
        canFill = bool;
        markDirty();
    }

    public void setFluidType(FluidType type)
    {
        fluidType = type;
        markDirty();
    }
}

 

 

 

  • Like 1
Link to comment
Share on other sites

7 hours ago, Simon_kungen said:

if there is a way to have a if statement that would only pass like every other tick

World#getTotalWorldTime (or something similar; can’t remember the spelling) returns the current world time. Modulo the total world time by 2 (or more if you would like the delay between triggers to be longer) and check if the result is equal to 0.

 

Use packets to send data from server to client.

Some tips:

Spoiler

Modder Support:

Spoiler

1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code.

2. Always post your code.

3. Never copy and paste code. You won't learn anything from doing that.

4. 

Quote

Programming via Eclipse's hotfixes will get you nowhere

5. Learn to use your IDE, especially the debugger.

6.

Quote

The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it.

Support & Bug Reports:

Spoiler

1. Read the EAQ before asking for help. Remember to provide the appropriate log(s).

2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.

 

 

Link to comment
Share on other sites

11 hours ago, DavidM said:

World#getTotalWorldTime (or something similar; can’t remember the spelling) returns the current world time. Modulo the total world time by 2 (or more if you would like the delay between triggers to be longer) and check if the result is equal to 0.

 

Use packets to send data from server to client.

Alright, that worked pretty well. I added this to my TileEntity;

Spoiler

@Override
public CompoundNBT getUpdateTag()
{
    CompoundNBT compound = super.getUpdateTag();
    compound.putInt("volume", volume);
    compound.putBoolean("can_fill",canFill);
    compound.putString("fluid_type",fluidType.getName());
    return compound;
}

@Override
public void handleUpdateTag(CompoundNBT compound)
{
    volume = compound.getInt("volume");
    canFill = compound.getBoolean("can_fill");
    fluidType = FluidType.valueOf(compound.getString("fluid_type").toUpperCase());
    super.handleUpdateTag(compound);
}

 

 

but when I tried to add a block update mechanic to it it wouldn't update:

Spoiler

@Override
public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt)
{
    CompoundNBT compound = pkt.getNbtCompound();
    volume = compound.getInt("volume");
    canFill = compound.getBoolean("can_fill");
    fluidType = FluidType.valueOf(compound.getString("fluid_type").toUpperCase());
    world.notifyBlockUpdate(pos,world.getBlockState(pos),world.getBlockState(pos),2);
}

@Nullable
@Override
public SUpdateTileEntityPacket getUpdatePacket()
{
    CompoundNBT compound = super.getUpdateTag();
    compound.putInt("volume", volume);
    compound.putBoolean("can_fill",canFill);
    compound.putString("fluid_type",fluidType.getName());

    return new SUpdateTileEntityPacket(pos, 1, compound);
}

 

 

 

I would like to add my own packet message to only send the data needed for that particular moment, but for now, a quick and dirty method would probably suffice for the time being.

 

Something I do wonder more is how I'm supposed to do the TileEntityRendererFast.

I registered this to the client, but the problem is that I have no idea how to work with this.

@Override
public void renderTileEntityFast(TreeTapTileEntity te, double x, double y, double z, float partialTicks, int destroyStage, BufferBuilder buffer)
{
    // *Confusion sound*

    //buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);



}

 

A 3D cuboid with varying texture and height and of course what axis it should align to (in my blockstate). I tried to search for some example online how to work with this, but none of the uses was sufficient to me.

https://github.com/search?l=&q=TileEntityRendererFast+language%3AJava&type=Code

Link to comment
Share on other sites

If anyone could tell me what I'm doing wrong, I would gladly accept any answer:

@Override
public void renderTileEntityFast(TreeTapTileEntity te, double x, double y, double z, float partialTicks, int destroyStage, BufferBuilder buffer)
{
    // *Confusion sound*


    BlockPos pos = te.getPos();

    net.minecraft.world.IEnviromentBlockReader world = MinecraftForgeClient.getRegionRenderCache(te.getWorld(), pos);
    BlockState state = world.getBlockState(pos);


    if (state.get(BlockProperties.BUCKET) != BucketType.NONE) {
        buffer.setTranslation(x - pos.getX(), y - pos.getY(), z - pos.getZ());


        buffer.pos(1,1,1).color(1,1,1,1);


    }


}

 

Here I don't really expect much except for absolutely anything to happen.

Link to comment
Share on other sites

Alright, I got some help getting something to render, but as they said you have to keep in mind what direction it is supposed to render it from, which I have no idea how to do.

buffer.pos(0,0,0).color(0,0,1,1).endVertex();
buffer.pos(4,0,0).color(0,0,1,1).endVertex();
buffer.pos(0,0,4).color(0,0,1,1).endVertex();
buffer.pos(4,0,4).color(0,0,1,1).endVertex();

 

Something I realized was that the fluid level is only going to be seen from the top, which would mean I only need to render a single side (top) and then change the y value to represent the fluid level.

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • There are a few Forge specific mods that I would dearly love to use on my new server, but my friend whom I'm setting up the new server with has expressed concerns that Forge may break or change some core mechanics that might make some farms/contraptions/Redstone devices that work in Vanilla or Fabric not work in Forge. They have sent me a few links to some Twitch minecrafters that have commented that "Forge changes Redstone behavior" or "Certain farms are broken on Forge but not Vanilla", however, I've never experienced this myself, and haven't found or seen any actual examples of this being the case.  I've scoured Youtube and can't find anyone saying "This contraption doesn't work on Forge Ole777".  I spoke to a mod developer who mentioned that there may have been small bugs where this might have been the case in extremely complicated builds, but he is not of aware of this still being an issue or concern. And he mentioned that any instance where something might break would definitely be considered a bug and should be reported and it would/could be fixed, as Forge explicitly doesn't intend to change any vanilla behavior. It just seems much more rumor than fact that Forge might break things, and just wanted to see if anyone had any input. Thank you!
    • This is a costume block whit the shape of a zombie is not a full block its flamable when ignited  the flames just burn on top or by a aside  that dint seems right  // ########## ########## ########## ########## @Override public int getFlammability(BlockState state, BlockGetter level, BlockPos pos, Direction direction) {     return 300;//((FireBlock)Blocks.FIRE).getBurnOdds(state); //300 } it just seems like check to know if a fire block could despawn mi block    ########### i want mi block to look more like this      what could i use  i was thinking on something like onNeigbourgChange() check for nearby fire or lava blocks   then using the falling block entity spawn a fire block in the same position than mi dead body block  thanks for your readings             
    • LINK DAFTAR AKUN GACOR VVIP BAMBUHOKI88 LINK LOGIN RESMI BAMBUHOKI88 LINK KLAIM BONUS 100% BAMBUHOKI88 Bambuhoki88 Merupakan kumpulan pilihan link situs rekomendasi slot bank bri di tahun 2024 di rekomendasi oleh para slotter deposit bank bri di indonesia dengan tingkat peluang kemenangan tinggi untuk setiap bet mudah menang maxwin.
    • LINK DAFTAR AKUN GACOR VVIP BAMBUHOKI88 LINK LOGIN RESMI BAMBUHOKI88   LINK KLAIM BONUS 100% BAMBUHOKI88 BAMBUHOKI88 Merupakan Pilihan Terbaik Situs Slot Bank Bca Yang Gampang Menang Maxwin Dan Jackpot Besar Dengan Deposit Bank Bca Yang Online 24Jam Auto Dapat Wd Gede.  
    • So I've been trying to make an mob that can have multiple textures, and the mob has the Witch model, and I can put a texture on it but I don't know how to make it spawn with a random texture. I tried searching through mobs that have multiple textures like the fox, rabbit, and stuff but I wasn't able to find out how to do it and I kept getting errors when i tried compiling: error: method createKey in class net.minecraft.network.datasync.EntityDataManager cannot be applied to given types; private static final DataParameter<Integer> ALCHEMIST_TYPE = EntityDataManager.createKey(AlchemistEntity.class, DataSerializers.VARINT); ^ required: java.lang.Class<? extends net.minecraft.entity.Entity>,net.minecraft.network.datasync.IDataSerializer<T> found: java.lang.Class<net.newblocks.entity.AlchemistEntity>,net.minecraft.network.datasync.IDataSerializer<java.lang.Integer> reason: cannot infer type-variable(s) T (argument mismatch; java.lang.Class<net.newblocks.entity.AlchemistEntity> cannot be converted to java.lang.Class<? extends net.minecraft.entity.Entity>) 1 error   And sorry there isn't much info, this was the only error that appears when I tried to copy the same thing from one of those mobs with multiple textures (plus imports). I already tried searching on the site and didn't find much. I can provide more info if needed
  • Topics

×
×
  • Create New...

Important Information

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