Jump to content

Recommended Posts

Posted

I started working on a project about a year ago now that I just started to actually complete. I spent about four hours creating the tile entity to create a pipe that teleports you to a location based on the information stored. However, when I close the world and reload it, the client side does not seem to be able to load up the information stored in the nbt while the server side can. I'm not the greatest at tile entities so I was wondering if anyone could help me fix this problem.

 

This is my tile entity:

package com.championash5357.supermariobrothers.tileentity;

import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;

public class TileEntityWarpPipe extends TileEntity {
	
	private double xCoord, yCoord, zCoord;

	@Override
	public void readFromNBT(NBTTagCompound compound) {
		super.readFromNBT(compound);
		this.xCoord = compound.getDouble("XCoordinate");
		this.yCoord = compound.getDouble("YCoordinate");
		this.zCoord = compound.getDouble("ZCoordinate");
		System.out.println("NBT X: "+ compound.getInteger("XCoordinate"));
		System.out.println("NBT Y: "+ compound.getInteger("YCoordinate"));
		System.out.println("NBT Z: "+ compound.getInteger("ZCoordinate"));
	}
	
	@Override
	public NBTTagCompound writeToNBT(NBTTagCompound compound) {
		super.writeToNBT(compound);
		compound.setDouble("XCoordinate", this.xCoord);
		compound.setDouble("YCoordinate", this.yCoord);
		compound.setDouble("ZCoordinate", this.zCoord);
		return compound;
	}
	
	public void setCoordinates(ItemStack wrench) {
		NBTTagCompound nbt = (NBTTagCompound)wrench.getTagCompound().getTag("coordinates");
		this.xCoord = nbt.getDouble("XCoord");
		this.yCoord = nbt.getDouble("YCoord");
		this.zCoord = nbt.getDouble("ZCoord");
	}
	
	public double getX() {
		return this.xCoord;
	}
	
	public double getY() {
		return this.yCoord;
	}
	
	public double getZ() {
		return this.zCoord;
	}
}

 

This is my block code:

package com.championash5357.supermariobrothers.blocks;

import java.util.List;

import org.lwjgl.input.Keyboard;

import com.championash5357.supermariobrothers.client.Reference.SuperMario;
import com.championash5357.supermariobrothers.init.MarioBlocks;
import com.championash5357.supermariobrothers.items.ItemWrench;
import com.championash5357.supermariobrothers.tileentity.TileEntityWarpPipe;

import net.minecraft.block.BlockHorizontal;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;

public class BlockWarpPipeBase extends BlockSuperMarioBros implements ITileEntityProvider{
	
	protected static final AxisAlignedBB PIPE_NF = new AxisAlignedBB(0.8125D, 0D, 0D, 0.875D, 1D, 0.8125D);
	protected static final AxisAlignedBB PIPE_NR = new AxisAlignedBB(0D, 0D, 0.8125D, 0.8125D, 1D, 0.875D);
	protected static final AxisAlignedBB PIPE_ND = new AxisAlignedBB(0D, 0D, 0D, 0.8125D, 0.0625D, 0.8125D);
	protected static final AxisAlignedBB PIPE_WF = new AxisAlignedBB(0.8125D, 0D, 0.1875D, 0.875D, 1D, 1D);
	protected static final AxisAlignedBB PIPE_WL = new AxisAlignedBB(0D, 0D, 0.125D, 0.8125D, 1D, 0.1875D);
	protected static final AxisAlignedBB PIPE_WD = new AxisAlignedBB(0D, 0D, 0.1875D, 0.8125D, 0.0625D, 1D);
	protected static final AxisAlignedBB PIPE_SB = new AxisAlignedBB(0.125D, 0D, 0.1875D, 0.1875D, 1D, 1D);
	protected static final AxisAlignedBB PIPE_SL = new AxisAlignedBB(0.1875D, 0D, 0.125D, 1D, 1D, 0.1875D);
	protected static final AxisAlignedBB PIPE_SD = new AxisAlignedBB(0.1875D, 0D, 0.1875D, 1D, 0.0625D, 1D);
	protected static final AxisAlignedBB PIPE_EB = new AxisAlignedBB(0.125D, 0D, 0D, 0.1875D, 1D, 0.8125D);
	protected static final AxisAlignedBB PIPE_ER = new AxisAlignedBB(0.1875D, 0D, 0.8125D, 1D, 1D, 0.875D);
	protected static final AxisAlignedBB PIPE_ED = new AxisAlignedBB(0.1875D, 0D, 0D, 1D, 0.0625D, 0.8125D);
	public static final PropertyDirection FACING = BlockHorizontal.FACING;
	
	public BlockWarpPipeBase() { 
		super(Material.ROCK);
		setUnlocalizedName(SuperMario.WARP_PIPE_BASE.getUnlocalizedName());
		setRegistryName(SuperMario.WARP_PIPE_BASE.getRegistryName());
		setWikiName(SuperMario.WARP_PIPE_BASE.getWikiName());
		this.setDefaultState(this.blockState.getBaseState().withProperty(FACING, EnumFacing.NORTH));
	}
	
	@Override
	public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) {
		ItemStack stack = playerIn.getHeldItem(hand);
		if(stack != null) {
			if(stack.getItem() instanceof ItemWrench) {
				if(stack.getItem().hasEffect(stack)) {
					TileEntityWarpPipe pipe = (TileEntityWarpPipe)worldIn.getTileEntity(pos);
					pipe.setCoordinates(stack);
					NBTTagCompound nbt = (NBTTagCompound)stack.getTagCompound().getTag("coordinates");
					double x = nbt.getDouble("XCoord");
					double y = nbt.getDouble("YCoord");
					double z = nbt.getDouble("ZCoord");
					stack.func_190918_g(1);
					if(!worldIn.isRemote) playerIn.addChatMessage(new TextComponentString("This warp pipe at " + TextFormatting.GOLD + pos.getX() + ", " + pos.getY() + ", " + pos.getZ() + TextFormatting.WHITE + " will now teleport the player to " + TextFormatting.GOLD + x + ", " + y + ", " + z + TextFormatting.WHITE + "."));
				}
			}
		}
		return true;
	}
	
	@Override
	public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, IBlockAccess worldIn, BlockPos pos) {
		return FULL_BLOCK_AABB.offset(pos);
	}
	
	@Override
	public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, IBlockState state, Entity entityIn) {
		if(entityIn instanceof EntityPlayer) teleport((EntityPlayer)entityIn, pos, worldIn);
		super.onEntityCollidedWithBlock(worldIn, pos, state, entityIn);
	}
	
	private void teleport(EntityPlayer player, BlockPos pos, World world) {
		TileEntityWarpPipe pipe = (TileEntityWarpPipe)world.getTileEntity(pos);
		if(player.isSneaking()) {
			player.setLocationAndAngles(pipe.getX(), pipe.getY(), pipe.getZ(), player.rotationYaw, player.rotationPitch);
		}
	}
	
	@Override
	public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
        EnumFacing enumfacing = (EnumFacing)state.getValue(FACING);
        switch(enumfacing) {
			case EAST:
				return PIPE_ED;
			case SOUTH:
				return PIPE_SD;
			case WEST:
				return PIPE_WD;
			case NORTH:
			default:
				return PIPE_ND;
        }
    }
	
	@Override
	public void addCollisionBoxToList(IBlockState state, World worldIn, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, Entity entityIn) {
		addCollisionBoxToList(pos, entityBox, collidingBoxes, state.getBoundingBox(worldIn, pos));
		addCollisionBoxToList(pos, entityBox, collidingBoxes, this.getFrontShape(state));
		addCollisionBoxToList(pos, entityBox, collidingBoxes, this.getSideShape(state));
	}
	
	private AxisAlignedBB getFrontShape(IBlockState state) {
		switch((EnumFacing)state.getValue(FACING)) {
			case EAST:
				return PIPE_EB;
			case SOUTH:
				return PIPE_SB;
			case WEST:
				return PIPE_WF;
			case NORTH:
			default:
				return PIPE_NF;
		}
	}
	
	private AxisAlignedBB getSideShape(IBlockState state) {
		switch ((EnumFacing)state.getValue(FACING))
        {
            case EAST:
                return PIPE_ER;
            case SOUTH:
                return PIPE_SL;
            case WEST:
                return PIPE_WL;
            case NORTH:
            default:
                return PIPE_NR;
        }
	}
	
	public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state)
    {
        this.setDefaultFacing(worldIn, pos, state);
    }

    private void setDefaultFacing(World worldIn, BlockPos pos, IBlockState state)
    {
        if (!worldIn.isRemote)
        {
            IBlockState iblockstate = worldIn.getBlockState(pos.north());
            IBlockState iblockstate1 = worldIn.getBlockState(pos.south());
            IBlockState iblockstate2 = worldIn.getBlockState(pos.west());
            IBlockState iblockstate3 = worldIn.getBlockState(pos.east());
            EnumFacing enumfacing = (EnumFacing)state.getValue(FACING);

            if (enumfacing == EnumFacing.NORTH && iblockstate.isFullBlock() && !iblockstate1.isFullBlock())
            {
                enumfacing = EnumFacing.SOUTH;
            }
            else if (enumfacing == EnumFacing.SOUTH && iblockstate1.isFullBlock() && !iblockstate.isFullBlock())
            {
                enumfacing = EnumFacing.NORTH;
            }
            else if (enumfacing == EnumFacing.WEST && iblockstate2.isFullBlock() && !iblockstate3.isFullBlock())
            {
                enumfacing = EnumFacing.EAST;
            }
            else if (enumfacing == EnumFacing.EAST && iblockstate3.isFullBlock() && !iblockstate2.isFullBlock())
            {
                enumfacing = EnumFacing.WEST;
            }

            worldIn.setBlockState(pos, state.withProperty(FACING, enumfacing), 2);
        }
    }
    
    public static void setState(boolean active, World worldIn, BlockPos pos)
    {
    	IBlockState iblockstate = worldIn.getBlockState(pos);
    	worldIn.setBlockState(pos, MarioBlocks.warp_pipe_base.getDefaultState().withProperty(FACING, iblockstate.getValue(FACING)), 3);
    	worldIn.setBlockState(pos, MarioBlocks.warp_pipe_base.getDefaultState().withProperty(FACING, iblockstate.getValue(FACING)), 3);
    }
	
    public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
    {
        return this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite());
    }
    
    public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack)
    {
        worldIn.setBlockState(pos, state.withProperty(FACING, placer.getHorizontalFacing().getOpposite()), 2);
    }
    
    public IBlockState getStateFromMeta(int meta)
    {
        EnumFacing enumfacing = EnumFacing.getFront(meta);

        if (enumfacing.getAxis() == EnumFacing.Axis.Y)
        {
            enumfacing = EnumFacing.NORTH;
        }

        return this.getDefaultState().withProperty(FACING, enumfacing);
    }
    
    public int getMetaFromState(IBlockState state)
    {
        return ((EnumFacing)state.getValue(FACING)).getIndex();
    }
    
    public IBlockState withRotation(IBlockState state, Rotation rot)
    {
        return state.withProperty(FACING, rot.rotate((EnumFacing)state.getValue(FACING)));
    }
    
    public IBlockState withMirror(IBlockState state, Mirror mirrorIn)
    {
        return state.withRotation(mirrorIn.toRotation((EnumFacing)state.getValue(FACING)));
    }

    protected BlockStateContainer createBlockState()
    {
        return new BlockStateContainer(this, new IProperty[] {FACING});
    }
	
	@Override
	public boolean isOpaqueCube(IBlockState state) {
        return false;
    }

	@Override
	public boolean isFullCube(IBlockState state) {
        return false;
    }
	
	@Override
	public void func_190948_a(ItemStack stack, EntityPlayer player, List<String> tooltip, boolean advanced) {
		tooltip.add(""  + TextFormatting.DARK_RED + "Super Mario Bros.");
		tooltip.add("");
		if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) {
			tooltip.add("" + TextFormatting.GOLD + "One of the main modes of transportation that transports the traveler to the other end.");
		}
		else {
			tooltip.add("" + TextFormatting.WHITE + "Hold " + TextFormatting.AQUA + TextFormatting.UNDERLINE + "LShift" + TextFormatting.RESET + " for more information.");
		}
    }

	@Override
	public TileEntity createNewTileEntity(World worldIn, int meta) {
		return new TileEntityWarpPipe();
	}
}

 

Thank you for your time.

  • 2 weeks later...
Posted

Your problem is, that all the Data reading is performed Server side (because it is the Server providing the World data and such things). To solve this you have to send Packets when needed to the client to sync the data or provide a possibility for the client to request an data sync. it might be possible to achieve, what you want using standard tile entity update packets, I'm not sure about that... 

 

Further reference can be found in the Forge's docs under the Networking section (you should have read the Sides section before that). 

Posted

One more thing, when you add tooltips, you should not rely on hardcoded Strings, but rather use localized ones... 

(e. g. use I18n. format(String key, Object...  args), where key is a key defined in your lang files and args are arguments which are used in the resulting String like String.format does (this is generally prefered to String concatisation because it is far more flexible)) 

Posted
36 minutes ago, Major Tuvok said:

His class implicitly uses an empty constructor... 

(If none is specified java generates an empty public constructor...) 

My fault, I was looking at the Block class and not at the TileEntity. Anyways, don't use ITileEntityProvider, override

Block::hasTileEntity and Block::createTileEntity .

 

Posted
57 minutes ago, ArmamentHaki said:

My fault, I was looking at the Block class and not at the TileEntity. Anyways, don't use ITileEntityProvider, override

Block::hasTileEntity and Block::createTileEntity .

 

The reason I use ITileEntityProvider is because I'm overriding a custom class for blocks. ITileEntityProvider does the same as extending BlockContainer.

 

1 hour ago, Major Tuvok said:

Your problem is, that all the Data reading is performed Server side (because it is the Server providing the World data and such things). To solve this you have to send Packets when needed to the client to sync the data or provide a possibility for the client to request an data sync. it might be possible to achieve, what you want using standard tile entity update packets, I'm not sure about that... 

 

Further reference can be found in the Forge's docs under the Networking section (you should have read the Sides section before that). 

Thanks, I'll look into it.

Posted (edited)
8 minutes ago, ChampionAsh5357 said:

The reason I use ITileEntityProvider is because I'm overriding a custom class for blocks. ITileEntityProvider does the same as extending BlockContainer.

 

That doesn't change anything, it still shouldn't be used.

Edited by Choonster

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

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

    • New users at Temu receive a $100 discount on orders over $100 Use the code [aci789589] during checkout to get Temu Coupon Code $100 off For New Users. Yes, Temu offers $100 off coupon code “aci789589” for first-time users. Temu 100% Off coupon code "aci789589" will save you $100 on your order. To get a discount, click on the item to purchase and enter the code. Yes, Temu offers $100 off coupon code “aci789589” for first-time users. You can get a$100 bonus plus 30% off any purchase at Temu with the$100 Coupon Bundle at Temu if you sign up with the referral code [aci789589] and make a first purchase of$50 or more. The Temu $100 Off coupon code (aci789589) will save you $100 on your order. To get a discount, click on the item to purchase and enter the code. Yes Temu offers $100 Off Coupon Code “aci789589” for First Time Users. Yes, Temu offers $100 off coupon code {aci789589} for first-time users. You can get a $100 bonus plus 100% off any purchase at Temu with the $100 Coupon Bundle if you sign up with the referral code [aci789589] and make a first purchase of $100 or more. If you are who wish to join Temu, then you should use this exclusive Temu coupon code $100 off (aci789589) and get $100 off on your purchase with Temu. You can get a $100 discount with Temu coupon code {aci789589}. This exclusive offer is for existing customers and can be used for a $100 reduction on your total purchase. Enter coupon code {aci789589} at checkout to avail of the discount. You can use the code {aci789589} to get a $100 off Temu coupon as a new customer. Apply this Temu coupon code $100 off (aci789589) to get a $100 discount on your shopping with Temu. If you’re a first-time user and looking for a Temu coupon code $100 first time user(aci789589) then using this code will give you a flat $100 Off and a 90% discount on your Temu shopping. Temu $100% Off Coupon Code "aci789589" will save you $100 on your order. To get a discount, click on the item to purchase and enter the code. Temu coupon code$100off-{aci789589} Temu coupon code -{aci789589} Temu coupon code$50 off-{aci789589} Temu Coupon code [aci789589] for existing users can get up to 50% discount on product during checkout. Temu Coupon Codes for Existing Customers-aci789589 Temu values its loyal customers and offers various promo codes, including the Legit Temu Coupon Code (aci789589]) or (aci789589), which existing users can use. This ensures that repeat shoppers can also benefit from significant discounts on their purchases. Keep an eye out for special promotions and offers that are periodically available to enhance your shopping experience.
    • Try other builds: https://www.curseforge.com/minecraft/mc-mods/geckolib/files/all?page=1&pageSize=20&version=1.16.5&gameVersionTypeId=1 Currently, you are using build 96 - the latest one that I linked is build 106 So try 97 to 105  
    • New users at Temu receive a $100 discount on orders over $100 Use the code [aci789589] during checkout to get Temu Coupon Code $100 off For New Users. Yes, Temu offers $100 off coupon code “aci789589” for first-time users. Temu 100% Off coupon code "aci789589" will save you $100 on your order. To get a discount, click on the item to purchase and enter the code. Yes, Temu offers $100 off coupon code “aci789589” for first-time users. You can get a$100 bonus plus 30% off any purchase at Temu with the$100 Coupon Bundle at Temu if you sign up with the referral code [aci789589] and make a first purchase of$50 or more. The Temu $100 Off coupon code (aci789589) will save you $100 on your order. To get a discount, click on the item to purchase and enter the code. Yes Temu offers $100 Off Coupon Code “aci789589” for First Time Users. Yes, Temu offers $100 off coupon code {aci789589} for first-time users. You can get a $100 bonus plus 100% off any purchase at Temu with the $100 Coupon Bundle if you sign up with the referral code [aci789589] and make a first purchase of $100 or more. If you are who wish to join Temu, then you should use this exclusive Temu coupon code $100 off (aci789589) and get $100 off on your purchase with Temu. You can get a $100 discount with Temu coupon code {aci789589}. This exclusive offer is for existing customers and can be used for a $100 reduction on your total purchase. Enter coupon code {aci789589} at checkout to avail of the discount. You can use the code {aci789589} to get a $100 off Temu coupon as a new customer. Apply this Temu coupon code $100 off (aci789589) to get a $100 discount on your shopping with Temu. If you’re a first-time user and looking for a Temu coupon code $100 first time user(aci789589) then using this code will give you a flat $100 Off and a 90% discount on your Temu shopping. Temu $100% Off Coupon Code "aci789589" will save you $100 on your order. To get a discount, click on the item to purchase and enter the code. Temu coupon code$100off-{aci789589} Temu coupon code -{aci789589} Temu coupon code$50 off-{aci789589} Temu Coupon code [aci789589] for existing users can get up to 50% discount on product during checkout. Temu Coupon Codes for Existing Customers-aci789589 Temu values its loyal customers and offers various promo codes, including the Legit Temu Coupon Code (aci789589]) or (aci789589), which existing users can use. This ensures that repeat shoppers can also benefit from significant discounts on their purchases. Keep an eye out for special promotions and offers that are periodically available to enhance your shopping experience.
    • New users at Temu receive a $100 discount on orders over $100 Use the code [aci789589] during checkout to get Temu Coupon Code $100 off For New Users. Yes, Temu offers $100 off coupon code “aci789589” for first-time users. Temu 100% Off coupon code "aci789589" will save you $100 on your order. To get a discount, click on the item to purchase and enter the code. Yes, Temu offers $100 off coupon code “aci789589” for first-time users. You can get a$100 bonus plus 30% off any purchase at Temu with the$100 Coupon Bundle at Temu if you sign up with the referral code [aci789589] and make a first purchase of$50 or more. The Temu $100 Off coupon code (aci789589) will save you $100 on your order. To get a discount, click on the item to purchase and enter the code. Yes Temu offers $100 Off Coupon Code “aci789589” for First Time Users. Yes, Temu offers $100 off coupon code {aci789589} for first-time users. You can get a $100 bonus plus 100% off any purchase at Temu with the $100 Coupon Bundle if you sign up with the referral code [aci789589] and make a first purchase of $100 or more. If you are who wish to join Temu, then you should use this exclusive Temu coupon code $100 off (aci789589) and get $100 off on your purchase with Temu. You can get a $100 discount with Temu coupon code {aci789589}. This exclusive offer is for existing customers and can be used for a $100 reduction on your total purchase. Enter coupon code {aci789589} at checkout to avail of the discount. You can use the code {aci789589} to get a $100 off Temu coupon as a new customer. Apply this Temu coupon code $100 off (aci789589) to get a $100 discount on your shopping with Temu. If you’re a first-time user and looking for a Temu coupon code $100 first time user(aci789589) then using this code will give you a flat $100 Off and a 90% discount on your Temu shopping. Temu $100% Off Coupon Code "aci789589" will save you $100 on your order. To get a discount, click on the item to purchase and enter the code. Temu coupon code$100off-{aci789589} Temu coupon code -{aci789589} Temu coupon code$50 off-{aci789589} Temu Coupon code [aci789589] for existing users can get up to 50% discount on product during checkout. Temu Coupon Codes for Existing Customers-aci789589 Temu values its loyal customers and offers various promo codes, including the Legit Temu Coupon Code (aci789589]) or (aci789589), which existing users can use. This ensures that repeat shoppers can also benefit from significant discounts on their purchases. Keep an eye out for special promotions and offers that are periodically available to enhance your shopping experience.
    • Both Ars Nouveau and Chaos Awakens require a range of geckolib versions, and the build you sent is outside the range. Ars Nouveau has an update, but Chaos Awakens doesn't, which means I can't use the build you sent. Is there any other way to fix the crash?
  • Topics

×
×
  • Create New...

Important Information

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