Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

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


15Cyndaquil
 Share

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.

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

 Share



  • Recently Browsing

    No registered users viewing this page.

  • Posts

    • thankyou for your input. I grab the GUI object on the GuiOpenEvent and the on the world tick event i keep checking it until the inventory loads. this successfully grabs the chest inventory from the client side. here is my final code. package com.example.examplemod; import java.util.ArrayList; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.NonNullList; import net.minecraft.network.chat.Component; import net.minecraft.network.protocol.game.ServerboundContainerClosePacket; import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket; import net.minecraft.network.protocol.game.ServerboundUseItemOnPacket; import net.minecraft.world.InteractionHand; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.entity.*; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import net.minecraftforge.client.event.GuiContainerEvent; import net.minecraftforge.client.event.GuiOpenEvent; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fmlclient.registry.ClientRegistry; @Mod.EventBusSubscriber public class ForgeEventHandler { private static ArrayList<BlockPos> homeBase = new ArrayList<BlockPos>(); private static Boolean pressed = false; public static final KeyMapping keyBinding = new KeyMapping("pam SETUP", 79, "PAM"); private static Screen GUI = null; @SubscribeEvent public static void setup(FMLClientSetupEvent event) { ClientRegistry.registerKeyBinding(keyBinding); } @SubscribeEvent public static void updatePlayer(TickEvent.PlayerTickEvent event) { /*if(event.player.canEat(false)){ for(ItemStack inventoryStack : event.player.getInventory().items){ if (inventoryStack.isEdible()) { ForgeEventFactory.onItemUseStart(event.player, inventoryStack, 0); ItemStack result = inventoryStack.getItem().finishUsingItem(inventoryStack, event.player.getCommandSenderWorld(), event.player); ForgeEventFactory.onItemUseFinish(event.player, inventoryStack, 0, result); if (!event.player.canEat(false)) { break; } } } }*/ if (keyBinding.isDown() && !pressed) { pressed = true; homeBase.add(((BlockHitResult) Minecraft.getInstance().player.pick(20.0D, 0.0F, false)).getBlockPos()); System.out.println("set postion"); if (homeBase.size()>=2) { System.out.println("opening container"); openBlock(detectContainers(homeBase).get(0)); homeBase.clear(); } if (!keyBinding.isDown()) { pressed=false; } } } @SubscribeEvent public static void updateWorld(TickEvent.WorldTickEvent event) { if (GUI != null) { if (GUI instanceof AbstractContainerScreen) { AbstractContainerScreen container = ((AbstractContainerScreen)GUI); NonNullList<Slot> slots = container.getMenu().slots; for (int i=0; i<slots.size();i++) { ItemStack temp = slots.get(i).getItem(); System.out.print(temp.getDisplayName().getString()+" | "); } System.out.println(""); GUI = null; } } } @SubscribeEvent public static void openChest(GuiOpenEvent event) { GUI = event.getGui(); } private static ArrayList<Vec3> detectContainers(ArrayList<BlockPos> homebase) { ArrayList<Vec3> chests = new ArrayList<Vec3>(); int x = homebase.get(1).getX()-homebase.get(0).getX(); int y = homebase.get(1).getY()-homebase.get(0).getY(); int z = homebase.get(1).getZ()-homebase.get(0).getZ(); for (int i=homebase.get(0).getX();i!=homebase.get(1).getX();i+=Math.signum(x)) { for (int j=homebase.get(0).getY();j!=homebase.get(1).getY();j+=Math.signum(y)) { for (int k=homebase.get(0).getZ();k!=homebase.get(1).getZ();k+=Math.signum(z)) { BlockEntity temp = Minecraft.getInstance().level.getBlockEntity(new BlockPos(i,j,k)); if (temp instanceof RandomizableContainerBlockEntity && !(temp instanceof HopperBlockEntity)) { chests.add(new Vec3(i,j,k)); } } } } return chests; } @SuppressWarnings("resource") private static void openBlock(Vec3 blockPos){ /*BlockHitResult hit = new BlockHitResult(blockPos, Direction.DOWN, new BlockPos(blockPos), false);*/ BlockHitResult hit = (BlockHitResult) Minecraft.getInstance().player.pick(20.0D, 0.0F, false); Minecraft.getInstance().getConnection().send(new ServerboundUseItemOnPacket(InteractionHand.MAIN_HAND,hit)); } }  
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.