Jump to content

[1.10.2] Blocks that Re-Texture when clicked depending on what the player is holding


15Cyndaquil

Recommended Posts

I'm recreating the mod Engineer's Toolbox for my personal use and in this mod you're able to configure a single block's sides for different ports or for the block to be used as different machines.

So for example I could choose what side power got inputed in by right clicking with a power input socket on the side I wanted.

Since this single block could have many different configurations depending on how many sockets I implement from the mod or if I create more I don't think I can create a massive list of blockstates.

 

So my question is what other options do I have for re-rendering a block's side through the block's onBlockActivated() method, AND are there any good tutorials for those methods that you know of.

Edited by 15Cyndaquil
Link to comment
Share on other sites

This would be covered by IBlockStates pretty well.

 

All you have to do is properly define your blockstate json.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

I've gotten my block to now change dynamically with 6 different properties, thank you for sugesting IBlockStates Draco, and while i am able to save each state to a TileEntity as well as able to change the state through the same TileEntity .

 

I have the new problem of when i try to load the states through the TileEntity using the Overriden method readFromNBT() in the TileEntity it loads the default values i set for the states in the TileEntity when I have a non-null world instead of the values saved from the previous session..

Link to comment
Share on other sites

Block code:

 

package com.cynda.cyndas_toolbox.block;

import com.cynda.cyndas_toolbox.CyndasToolbox;
import com.cynda.cyndas_toolbox.EnumHandler.SocketBlockSide;
import com.cynda.cyndas_toolbox.tiles.Test;
import net.minecraft.block.Block;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

import javax.annotation.Nullable;

public class BlockSocket extends Block implements ITileEntityProvider{

    final static PropertyEnum<SocketBlockSide> EAST = PropertyEnum.create("east", SocketBlockSide.class);
    final static PropertyEnum<SocketBlockSide> WEST = PropertyEnum.create("west", SocketBlockSide.class);
    final static PropertyEnum<SocketBlockSide> NORTH = PropertyEnum.create("north", SocketBlockSide.class);
    final static PropertyEnum<SocketBlockSide> SOUTH = PropertyEnum.create("south", SocketBlockSide.class);
    final static PropertyEnum<SocketBlockSide> UP = PropertyEnum.create("up", SocketBlockSide.class);
    final static PropertyEnum<SocketBlockSide> DOWN = PropertyEnum.create("down", SocketBlockSide.class);

    

    public BlockSocket(String unlocalizedName){
        super(Material.IRON);
        setUnlocalizedName(unlocalizedName);
        setCreativeTab(CyndasToolbox.tabBlocks);



        setDefaultState(getBlockState().getBaseState().withProperty(EAST, SocketBlockSide.BLANK));
        setDefaultState(getBlockState().getBaseState().withProperty(WEST, SocketBlockSide.BLANK));
        setDefaultState(getBlockState().getBaseState().withProperty(NORTH, SocketBlockSide.BLANK));
        setDefaultState(getBlockState().getBaseState().withProperty(SOUTH, SocketBlockSide.BLANK));
        setDefaultState(getBlockState().getBaseState().withProperty(UP, SocketBlockSide.BLANK));
        setDefaultState(getBlockState().getBaseState().withProperty(DOWN, SocketBlockSide.BLANK));
    }


    @SideOnly(Side.CLIENT)
    @Override
    public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, @Nullable ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {

        if(!worldIn.isRemote) {
//            worldIn.markBlocksDirtyVertical(pos.getX(), pos.getZ(), pos.getX(), pos.getZ());

            TileEntity te = worldIn.getTileEntity(pos);
            if (te != null && te instanceof Test) {
                Test tileTest = (Test) te;
                state = setFaceRandom(state, getSide(side), playerIn, tileTest, side);
                worldIn.setBlockState(pos, state);
                tileTest.markDirty();
                if (playerIn.isSneaking()) {
                    playerIn.addChatMessage(new TextComponentString("Clicks " + tileTest.getClicks()));
                } else {
                    tileTest.setClicks(tileTest.getClicks() + 1);
                    tileTest.markDirty();
                }
            }
        }
        return true;
    }

    private IBlockState setFaceRandom(IBlockState state, PropertyEnum side, EntityPlayer playerIn, Test tileTest, EnumFacing sideFace){
        if(playerIn.getHeldItemMainhand()==null){
            state = state.withProperty(side, SocketBlockSide.INPUT_POWER);
            tileTest.setSide(sideFace, "input_power");
            System.out.println("INPUT");
        }else {
            state = state.withProperty(side, SocketBlockSide.BLANK);
            tileTest.setSide(sideFace, "blank");
            System.out.println("BLANK");
        }
        return state;
    }

    private PropertyEnum getSide(EnumFacing side){
        PropertyEnum enumSide = EAST;
        switch (side){
            case EAST:
                enumSide = EAST;
                break;
            case WEST:
                enumSide = WEST;
                break;
            case NORTH:
                enumSide = NORTH;
                break;
            case SOUTH:
                enumSide = SOUTH;
                break;
            case UP:
                enumSide = UP;
                break;
            case DOWN:
                enumSide = DOWN;
                break;
        }
        return enumSide;
    }

    public void setEast(SocketBlockSide value){

        setDefaultState(getBlockState().getBaseState().withProperty(EAST, value));
    }
    @Override
    public IBlockState getStateFromMeta(int meta) {return this.getDefaultState();}
    @Override
    public int getMetaFromState(IBlockState state) {return 0;}

    //Methods for ITileEntityProvider
    @Override
    public TileEntity createNewTileEntity(World worldIn, int meta) { return new Test(); }

    @Override
    protected BlockStateContainer createBlockState() {
        return new BlockStateContainer(this, EAST, WEST, NORTH, SOUTH, UP, DOWN);
    }


    public PropertyEnum<SocketBlockSide> getEAST() {return EAST;}
    public PropertyEnum<SocketBlockSide> getWEST() {return WEST;}
    public PropertyEnum<SocketBlockSide> getNORTH() {return NORTH;}
    public PropertyEnum<SocketBlockSide> getSOUTH() {return SOUTH;}
    public PropertyEnum<SocketBlockSide> getUP() {return UP;}
    public PropertyEnum<SocketBlockSide> getDOWN() {return DOWN;}
}

 

TileEntity code:

 

package com.cynda.cyndas_toolbox.tiles;

import akka.io.Tcp;
import com.cynda.cyndas_toolbox.EnumHandler.SocketBlockSide;
import com.cynda.cyndas_toolbox.block.BlockSocket;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

public class Test extends TileEntity{

    private int clicks = 0;
    private int east = 0;

    private IntegerProperty eastProptery = new SimpleIntegerProperty(east);
//    private String west = "blank";
//    private String north = "blank";
//    private String south = "blank";
//    private String up = "blank";
//    private String down = "blank";

    private World world;


    final static PropertyEnum<SocketBlockSide> EAST = PropertyEnum.create("east", SocketBlockSide.class);
    final static PropertyEnum<SocketBlockSide> WEST = PropertyEnum.create("west", SocketBlockSide.class);
    final static PropertyEnum<SocketBlockSide> NORTH = PropertyEnum.create("north", SocketBlockSide.class);
    final static PropertyEnum<SocketBlockSide> SOUTH = PropertyEnum.create("south", SocketBlockSide.class);
    final static PropertyEnum<SocketBlockSide> UP = PropertyEnum.create("up", SocketBlockSide.class);
    final static PropertyEnum<SocketBlockSide> DOWN = PropertyEnum.create("down", SocketBlockSide.class);

    public Test(){
        eastProptery.addListener(new InvalidationListener() {
            @Override
            public void invalidated(Observable e) {
                boolean firstLoad = true;
                if(getWorld()==null){
                    System.out.println(e + " East + null");
//                        int x = Integer.valueOf(e.toString().substring(e.toString().length() - 2, e.toString().length() - 1)) - 1;
//                        System.out.println(x);
//                        eastProptery.setValue(x);
                }else {
                    System.out.println(e + " East");
                    final IBlockState state = getWorld().getBlockState(getPos());
//
////            EAST = ((BlockSocket) getBlockType()).getEAST();
////            WEST = ((BlockSocket) getBlockType()).getWEST();
////            NORTH = ((BlockSocket) getBlockType()).getNORTH();
////            SOUTH = ((BlockSocket) getBlockType()).getSOUTH();
////            UP = ((BlockSocket) getBlockType()).getUP();
////            DOWN = ((BlockSocket) getBlockType()).getDOWN();
//
                    setState(state);
                }
            }
        });
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        compound.setInteger("Clicks", clicks);
        compound.setInteger("East", east);
//        compound.setString("West", west);
//        compound.setString("North", north);
//        compound.setString("South", south);
//        compound.setString("Up", up);
//        compound.setString("Down", down);
        markDirty();
        super.writeToNBT(compound);

        return compound;
    }




    @Override
    public void readFromNBT(NBTTagCompound compound){
        System.out.println("Hello NBTReadNOW");
        super.readFromNBT(compound);
        if(getWorld()==null){
            clicks = compound.getInteger("Clicks");
            east = compound.getInteger("East");
            eastProptery.setValue(east);
            System.out.println(compound.getInteger("East")+" Read "+compound.getInteger("Clicks"));
        }
        System.out.println(getWorld());
        if(getWorld()!=null) {
            System.out.println(eastProptery.intValue() +" East Value");
            final IBlockState state = getWorld().getBlockState(getPos());
            setState(state);

        }
    }



    public int getClicks() {return clicks; }

    public void setClicks(int clicks) { this.clicks = clicks; markDirty();}
    public void setEast(int east){this.east = east; eastProptery.setValue(east);}

    public void setSide(EnumFacing side, String value) {
        switch (side){
            case EAST:
                east = SocketBlockSide.getName(value).getID();
                eastProptery.setValue(east);
//                System.out.println(eastProptery);
                markDirty();
                break;
            case WEST:
//                west = value;
                markDirty();
                break;
            case NORTH:
//                north = value;
                markDirty();
                break;
            case SOUTH:
//                south = value;
                markDirty();
                break;
            case UP:
//                up = value;
                markDirty();
                break;
            case DOWN:
//                down = value;
                markDirty();
                break;
        }

    }


    public void setState(IBlockState state){
        System.out.println(east+" Set State");
        state = state.withProperty(EAST, SocketBlockSide.values()[eastProptery.intValue()]);
//        state = state.withProperty(WEST, SocketBlockSide.getName(west));
//        state = state.withProperty(NORTH, SocketBlockSide.getName(north));
//        state = state.withProperty(SOUTH, SocketBlockSide.getName(south));
//        state = state.withProperty(UP, SocketBlockSide.getName(up));
//        state = state.withProperty(DOWN, SocketBlockSide.getName(down));
        getWorld().setBlockState(pos, state);
        System.out.println("set BlockState"+getPos().toString()+state.toString());
    }


    /**
     * This controls whether the tile entity gets replaced whenever the block state
     * is changed. Normally only want this when block actually is replaced.
     */
    @Override
    public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newState)
    {
        return (oldState.getBlock() != newState.getBlock());
    }


}
Link to comment
Share on other sites

So I think I know what the issue is. My theory is that there are two tileEntities. one on the server and one on the client. when the tileEntities are created the server side one doesn't initially have a world object so I cant set a block's state in the readFromNBT() method from the server side, and when the client creates its tileEntities it doesnt have the nbt Data the server has so it creates a default one.

 

I've tried to sync them by requesting the information from the server when the client loads it's tileEntities but from what i can see it doesnt get the data quick enough to be useful for when the game renders in.

 

Does anyone know either another way to save the blockstate that would be more reliable or a way to get the nbt data to sync before the game loads.

Link to comment
Share on other sites

You are essentially correct on all points.

 

Have you overridden these three methods? One of them is explicitly for the purpose of telling the client what the nbt data was when the TE was loaded from disk.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

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

    • This is a MacOs related issue: https://bugs.mojang.com/browse/MC-118506     Download this lib: https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar and put it into ~/Library/Application Support/minecraft/libraries/ca/weblite/java-objc-bridge/1.0.0  
    • I use Bisect-Hosting, and I host a relatively modded server.  There is a mod I desperately want to have in a server. https://www.curseforge.com/minecraft/mc-mods/minehoplite This is MineHop. It's a mod that replicates the movement capabilities seen in Source Engine games, such as Half-Life, and such.  https://youtu.be/SbtLo7VbOvk - A video explaining the mod, if anyone is interested.  It is a clientside mod, meaning whoever is using it can change anything about the mod that they want, with no restrictions, even when they join a server with the same mod. They can change it to where they can go infinitely fast, or do some other overpowered thing. I don't want that to happen. So I just want to know if there is some way to force the SERVER'S configuration file, onto whoever is joining.  I'm not very savvy with all this modding stuff. There are two config files: minehop-common.txt, and minehop.txt I don't really know much about how each are different. I just know what the commands relating to acceleration and stuff mean.    
    • My journey into crypto trading began tentatively, with me dipping my toes into the waters by purchasing my first Bitcoin through a seasoned trader. With an initial investment of $5,000, I watched as my investment grew, proving to be both fruitful and lucrative. Encouraged by this success, I decided to increase my investment to $150,000, eager to capitalize on the growing popularity of cryptocurrency, However, as cryptocurrency gained mainstream attention, so too did the number of self-proclaimed "experts" in the field. Suddenly, everyone seemed to be a crypto guru, and more and more people were eager to jump on the bandwagon without fully understanding the intricacies of this complex world. With promises of quick and easy profits, these con artists preyed on the uninformed, luring them into schemes that often ended in disappointment and financial loss. Unfortunately, I fell victim to one such scheme. Seduced by the allure of easy money, I entrusted my hard-earned funds to a dubious trading platform, granting them access to my accounts in the hopes of seeing my investment grow. For a brief period, everything seemed to be going according to plan, with regular withdrawals and promising returns on my investment. However, my hopes were soon dashed when, without warning, communication from the platform ceased, and my Bitcoin holdings vanished into thin air. Feeling helpless and betrayed, I confided in a family member about my predicament. They listened sympathetically and offered a glimmer of hope in the form of a recommendation for Wizard Web Recovery. Intrigued by the possibility of reclaiming what I had lost, I decided to explore this option further. From the moment I reached out to Wizard Web Recovery, I was met with professionalism and empathy. They took the time to understand my situation and reassured me that I was not alone in my plight. With their guidance, I embarked on a journey to reclaim what was rightfully mine. Wizard Web Recovery's expertise and dedication were evident from the start. They meticulously analyzed the details of my case, uncovering crucial evidence that would prove invaluable in our quest for justice. With each step forward, they kept me informed and empowered, instilling in me a newfound sense of hope and determination. Through their tireless efforts and unwavering support, Wizard Web Recovery succeeded in recovering my lost Bitcoin holdings. It was a moment of triumph and relief, knowing that justice had been served and that I could finally put this chapter behind me. In conclusion, My experience with Wizard Web Recovery  was nothing short of transformative. Their professionalism, expertise, and unwavering commitment to their clients set them apart as true leaders in the field of cryptocurrency recovery. I am forever grateful for their assistance and would highly recommend their services to anyone in need of help navigating the treacherous waters of cryptocurrency scams. 
    • Ok so: Two things to note: It got stuck due to my dimension type. It was previously the same as the overworld dimension tpye but after changing it , it didn't freeze during spawn generation. ALSO, APPARENTLY, the way I'm doing things, the game can't have two extremely-rich dimensions or it will make the new chunk generation be veeery VEEERY slow. I'm doing the dimension file genreation all in the data generation step now, so it's all good. Mostly. If anybody has any tips regarding how can i more efficently generate a biome-rich dimension, im all ears.
    • https://mclo.gs/qTo3bUE  
  • Topics

×
×
  • Create New...

Important Information

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