Jump to content

NBT's are not saving or saving too soon when the game is quit


kris91268

Recommended Posts

try
{
return (TileEntity)theTileEntityClass.newInstance();
}
    catch (Exception e)
{
throw new RuntimeException();
}

this seems overkill:

 

public class TileEntityGravityLift extends TileEntity

<-- cant you just

return new TileEntityGravityLift();

(if you know what you're doing, can i ask which different tile entity you intend to use for the same block, out of curiosity :P, also, if you are going to use more then 1 type of tile entity on the same block (weird but :P)

you coudl do something like this in your constructor:

public class BlockGravityLift extends BlockContainer implements BlockProxy{
    public TileEntity theTileEntityClass;

    public BlockGravityLift(int id, Class<? extends TileEntity> theClass){
        theTileEntityClass = theClass;
    }

    public TileEntity createTileEntity(World world, int meta){
        try{
            return theTileEntityClass.newInstance();
        }catch(Exception e){
            System.out.println("this will only print if the TileEntity doesn't have a 0 argument constructor");
        }
    }

}

because  Class<? extends TileEntity> mean that it will crash at compile time if its not a subclass of TileEntity

 

 

 

public class TileEntityGravityLift extends TileEntity
{
private String aString;
public Double height = new Double(0.0D);

are you using the Double object elsewhere? because you could probably use the primitive type "double" (without the capital)

 

protip, you can transform number into string by addign the empty string ("") to any primitive type:

double d = 5;
String dToString = d+"";

you still have to use the parse method to revert to primitive type

 

 

 

not code impacting at all, but your button have weird name:

private GuiButton decByPointZeroOne;//-0.01   this guy here 
private GuiButton decByPointOne;//-0.1
private GuiButton incByPointOne;//+0.1
private GuiButton incByOnePointZero;//+1.0

 

public void initGui()
{
	super.initGui();
	this.buttonList.clear();

in this case it doesnt matter but if you were extending someone else gui that was doing stuff in its initGui(), the method clear() would wipe all his changes

 

 

btw MineMaarten is right, you need to sendPacketToServer, not sendPacketToAllPlayers, you want to tell the SERVER that you have changed the tile entity

 

also send the x, y, z of the tile entity, the server doesnt know which block you're talking about

 

and finally you might want to also send the dimentionID to prevent a very rare vanilla bug from happening

 

i prefer to use Packet250CustomPayload // that only a matter of opinion, sorry :P

 

heres 2 tutorial i made that could help

 

synchronizing tile entities:

http://www.minecraftforge.net/wiki/Synchronizing_tile_entities

 

organising packer handlers:

http://www.minecraftforge.net/wiki/Organising_packet_handlers

 

warning, i dont explain basic java in there

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

update your code, not sure which version is the right one, also feel free to give a thank you to whoever helped you (i actually legit dont know what fixed your code, and who fixed it)

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

You solved the problem why it wasn't writing to it's tile entity, so I gave you a thank you. However, I do believe that packet handling would be neccessary, so MineMarteen also helpedd solve this problem. The thing that solved it was I forgot to use the hasTileEntity(int meta) method in my block class. I'll experiment around with some stuff, let you know how the results turned out and if the block successfully reads the stored nbt.

 

Here is some code explained

 

I used a double object to store the height value in the tile entity class so I can call the .toString() method in the GuiGravityLift class. I didn't know you could do that with a primitive.

 

I intend to use the same tile entity for the gravity lift block, so saying which other tile entities I am using isn't neccessary

 

I do know java, quite well actually, but not fully how Minecraft and Forge works.

 

Thanks so much for your help, and MineMarteen's help with the packet handling

Link to comment
Share on other sites

I used a double object to store the height value in the tile entity class so I can call the .toString() method in the GuiGravityLift class. I didn't know you could do that with a primitive.

 

I intend to use the same tile entity for the gravity lift block, so saying which other tile entities I am using isn't neccessary

 

I do know java, quite well actually, but not fully how Minecraft and Forge works.

my tips were PURELLY informationnal btw, you are free to do wtv u want with them :P

 

and yes you are still required to send the change to the server because if you don't the server (the guy that decide everything) doesnt know that the TE values have changed

 

i beleive my 2 tutorial will help you :)

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

I try to use the packet to send a message to the server to change it's tile entity when the buttons of the gui are clicked, but it crashes with a protocol exception when I try. I know I coded it to do this, but it was in the tutorial with advanced packet handling.

 

How would you suggest I send a packet to the server with the x y z coordinates when I click a button on the gui?

Link to comment
Share on other sites

well for 1 i suggest you use the packet read/write class i made, they are in this tutorial at the every begining

 

http://www.minecraftforge.net/wiki/Organising_packet_handlers

 

they make code much clearer

 

basicly all you have to do is

PacketWriteStream stream = new PacketWriteStream();

stream.put(tileEntityX);

stream.put(tileEntityY);

stream.put(tileEntityZ);

stream.put(height);

Packet p = stream.makePacket("channel");

 

PacketDispatcher.sendPacketToServer(p);

 

and server side:

 

PacketReadStream stream = new PacketReadStream(originalPacket);

int x = stream.readInt();

int y = stream.readInt();

int z = stream.readInt();

double height = stream.readDouble();

 

and then somethign like

World world = //get a world reference

world.getTileEntityAt(x, y, z).setHeight(height);

 

sry i gtg IRL gl (ill be there later so post question if you still need some help)

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

I have made the PacketOutputStream and the PacketInputStream, but I don't understand where I should put the rest. Where should I declare a new PacketWriteStream object and put the tileEntity x, y, and z coordinates in it? Do I declare it in the gui file, or the PacketHandler file?

Link to comment
Share on other sites

Actually, I found that it is much easier just to use a packet already used in Minecraft, in this case, I use the Packet132TileEntityData packet since that is all I need, and I found it actually saves data. Thanks for the help everyone has given me.

Link to comment
Share on other sites

Packet132TileEntityData cannot be sent to server without causing the server to kick the client, but it can be send from server to client, but thats basicly what the method markBlockForUpdate do

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

In that case, what do you think I should do? How do you propose I implement the packet sending code.

 

Here is the files that I have changed

 

GuiGravityLift.java

package kris91268.lbd;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;

import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;

import cpw.mods.fml.common.network.PacketDispatcher;

import kris91268.lbd.Blocks.BlockGravityLift;
import kris91268.lbd.Packet.PacketBlockChange;
import kris91268.lbd.Tileentity.TileEntityGravityLift;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.packet.Packet132TileEntityData;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;

/**
* 
* @author Arbiter
*
*/
public class GuiGravityLift extends GuiContainer
{
private static final ResourceLocation texture = new ResourceLocation("lbd:textures/gui/gravlift.png");
private GuiButton dnButton;
private GuiButton decByPointZeroOne;
private GuiButton decByPointOne;
private GuiButton incByPointOne;
private GuiButton incByOnePointZero;
private GuiTextField number;
public static String gravLiftHeight;
private TileEntityGravityLift tileEntity;

public GuiGravityLift(InventoryPlayer par1, TileEntityGravityLift par2)
{
	super(new ContainerGravityLift(par1, par2));
	tileEntity = par2;
}
@Override
protected void drawGuiContainerForegroundLayer(int par1, int par2)
{
	fontRenderer.drawString("Gravity Lift", 8, 6, 4210752);
	fontRenderer.drawString("Inventory", 8, ySize - 96 + 2, 4210752);
}
@Override
protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3)
{
	this.mc.func_110434_K().func_110577_a(texture);
	GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
	int x = (width - xSize) / 2;
	int y = (height - ySize) / 2;
	this.drawTexturedModalRect(x, y, 0, 0, xSize, ySize);
	this.number.drawTextBox();
}
@Override
public void initGui()
{
	super.initGui();
	Keyboard.enableRepeatEvents(true);
	this.buttonList.add(this.dnButton = new GuiButton(0, this.width / 2 - 25, this.height / 4 + 35, 50, 20, "Done"));
	this.buttonList.add(this.decByPointZeroOne = new GuiButton(1, this.width / 2 - 75, this.height / 4 + 0, 40, 20, "-0.1"));
	this.buttonList.add(this.decByPointOne = new GuiButton(2, this.width / 2 - 75, this.height / 4 + 25, 40, 20, "-1.0"));
	this.buttonList.add(this.incByPointOne = new GuiButton(3, this.width / 2 + 25, this.height / 4 + 0, 40, 20, "+0.1"));
	this.buttonList.add(this.incByOnePointZero = new GuiButton(4, this.width / 2 + 25, this.height / 4 + 25, 40, 20, "+1.0"));
	this.number = new GuiTextField(this.fontRenderer, this.width / 2 - 20, this.height / 4 + 1, 40, 20);
	this.number.setVisible(true);
	this.number.setCanLoseFocus(false);
	this.number.setFocused(true);
	if (tileEntity.height == null)
	{
		tileEntity.height = 0.0D;
		this.number.setText(tileEntity.height.toString());
		gravLiftHeight = tileEntity.height.toString();
	}
	else
	{
		this.number.setText(tileEntity.height.toString());
		gravLiftHeight = tileEntity.height.toString();
	}
}
public void onGuiClosed()
{
	Keyboard.enableRepeatEvents(false);
	Double theNumber = Double.parseDouble(gravLiftHeight);
	tileEntity.bindHeightToTileEntity(theNumber);
	String s = "gravlift";
	ByteArrayOutputStream out = new ByteArrayOutputStream();
	DataOutputStream dataOut = new DataOutputStream(out);
	try
	{
		dataOut.writeDouble(theNumber);
		this.mc.getNetHandler().addToSendQueue(new Packet250CustomPayload(s, out.toByteArray()));
		this.tileEntity.getDescriptionPacket();
		this.tileEntity.bindHeightToTileEntity(theNumber);
	}
	catch (Exception e)
	{
		e.printStackTrace();
	}
}
public boolean isAboveZero(String par1Str)
{
	Double theDouble = Double.parseDouble(par1Str);
	return theDouble >= 0.00 ? true : false;
}
public boolean isBelowFive(String par1Str)
{
	Double theDouble = Double.parseDouble(par1Str);
	return theDouble <= 5.00 ? true : false;
}
public void updateScreen()
{
	this.number.updateCursorCounter();
}
/**
public void mouseClicked(int par1, int par2, int par3)
{
	super.mouseClicked(par1, par2, par3);
	this.number.mouseClicked(par1, par2, par3);
}
public void keyTyped(char par1, int par2)
{
	this.number.textboxKeyTyped(par1, par2);
	((GuiButton)this.buttonList.get(0)).enabled = this.number.getText().trim().length() > 0;
	if (par2 == 28 || par2 == 156)
	{
		this.actionPerformed((GuiButton)this.buttonList.get(0));
	}
}**/
@Override
protected void actionPerformed(GuiButton guiButton)
{
	int x = tileEntity.xCoord;
	int y = tileEntity.yCoord;
	int z = tileEntity.zCoord;
	switch (guiButton.id)
	{
	case 0:
		this.mc.displayGuiScreen((GuiScreen)null);
		break;
	case 1:
		Double heightInDoubles = Double.parseDouble(gravLiftHeight);
		if (heightInDoubles != 0.0)
		{
			heightInDoubles -= 0.1;
		}
		gravLiftHeight = heightInDoubles.toString();
		number.setText(gravLiftHeight);
		PacketDispatcher.sendPacketToServer(new PacketBlockChange(heightInDoubles, tileEntity, x, y, z).makePacket());
		break;
	case 2:
		Double heightInDoubles1 = Double.parseDouble(gravLiftHeight);
		if (heightInDoubles1 < 1.0)
		{
			heightInDoubles1 = 0.0;
		}
		else
		{
			heightInDoubles1 -= 1.0;
		}
		gravLiftHeight = heightInDoubles1.toString();
		number.setText(gravLiftHeight);
		PacketDispatcher.sendPacketToServer(new PacketBlockChange(heightInDoubles1, tileEntity, x, y, z).makePacket());
		break;
	case 3:
		Double theHeight = Double.parseDouble(gravLiftHeight);
		if (theHeight != 5.0)
		{
			theHeight += 0.1;
		}
		gravLiftHeight = theHeight.toString();
		number.setText(gravLiftHeight);
		tileEntity.bindHeightToTileEntity(theHeight);
		PacketDispatcher.sendPacketToServer(new PacketBlockChange(theHeight, tileEntity, x, y, z).makePacket());
		break;
	case 4:
		Double theNumber = Double.parseDouble(gravLiftHeight);
		if (theNumber > 4.0)
		{
			theNumber = 5.0;
		}
		else
		{
			theNumber += 1.0;
		}
		gravLiftHeight = theNumber.toString();
		number.setText(gravLiftHeight);
		String s = "gravlift";
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		DataOutputStream dataOut = new DataOutputStream(out);
		try
		{
			dataOut.writeDouble(theNumber);
			this.mc.getNetHandler().addToSendQueue(new Packet250CustomPayload(s, out.toByteArray()));
			tileEntity.getDescriptionPacket();
			this.tileEntity.bindHeightToTileEntity(theNumber);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		default:
			break;
	}
}
}

 

TileEntityGravityLift.java

package kris91268.lbd.Tileentity;

import java.awt.List;

import kris91268.lbd.Blocks.BlockGravityLift;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagDouble;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet132TileEntityData;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;

/**
* 
* @author Arbiter
*
*/
public class TileEntityGravityLift extends TileEntity implements IInventory
{
private String aString;
public Double height;		

public void readFromNBT(NBTTagCompound par1NBTTagCompound)
{
	super.readFromNBT(par1NBTTagCompound);
	height = par1NBTTagCompound.getDouble("height");
	System.out.println(height);
}
public void writeToNBT(NBTTagCompound par1NBTTagCompound)
{
	super.writeToNBT(par1NBTTagCompound);
	par1NBTTagCompound.setDouble("height", height);
	System.out.println(height);
}
public boolean isUsableByPlayer(EntityPlayer par1EntityPlayer)
{
	return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : 
		par1EntityPlayer.getDistanceSq((double)this.xCoord + 0.5D, (double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D) <= 64.0D;
}
public void something(String par1Str)
{
	this.aString = par1Str;
}
@Override
public String getInvName()
{
	return "Gravity Lift";
}
public void bindHeightToTileEntity(double theHeight)
{
	this.height = theHeight;
	worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
public double getHeightLevel()
{
	return this.height; 
}
public Packet getDescriptionPacket()
{
	NBTTagCompound nbt = new NBTTagCompound();
	this.writeToNBT(nbt);
	return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 3, nbt);
}
@Override
public int getSizeInventory()
{		
	return 0;
}
@Override
public ItemStack getStackInSlot(int i) 
{
	return null;
}
@Override
public ItemStack decrStackSize(int i, int j)
{
	return null;
}
@Override
public ItemStack getStackInSlotOnClosing(int i)
{
	return null;
}
@Override
public void setInventorySlotContents(int i, ItemStack itemstack)
{

}
@Override
public boolean isInvNameLocalized()
{
	return false;
}
@Override
public int getInventoryStackLimit()
{
	return 64;
}
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer)
{
	return true;
}
@Override
public void openChest()
{

}
@Override
public void closeChest()
{

}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
	return false;
}
}

Link to comment
Share on other sites

public Packet getDescriptionPacket()
{
	NBTTagCompound nbt = new NBTTagCompound();
	this.writeToNBT(nbt);
	return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 3, nbt);
}

This is the packet that will be sent when world.markBlockForUpdate(...) is called.

If you want to manage the receiving part of this packet, you can change it into a Packet250CustomPayload, add extra data, and send it through your channel.

Actually, you should change it. A Packet132TileEntityData with type 3 is assumed to come from a TileEntityBeacon.

Link to comment
Share on other sites

public Packet getDescriptionPacket()
{
	NBTTagCompound nbt = new NBTTagCompound();
	this.writeToNBT(nbt);
	return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 3, nbt);
}

This is the packet that will be sent when world.markBlockForUpdate(...) is called.

If you want to manage the receiving part of this packet, you can change it into a Packet250CustomPayload, add extra data, and send it through your channel.

Actually, you should change it. A Packet132TileEntityData with type 3 is assumed to come from a TileEntityBeacon.

 

no actually that's wrong, more then 1 tile entity in the game use it

 

beacon, command block, mob spawner and skull

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

no actually that's wrong, more then 1 tile entity in the game use it

 

beacon, command block, mob spawner and skull

Only with types being respectively, 3, 2, 1 and 4.

 

You can use whatever packet type indeed, but in this case, the tileentity needs to override like this:

@Override
onDataPacket(INetworkManager net, Packet132TileEntityData pkt)
{
         this.readFromNBT(pkt.customParam1);
}

Link to comment
Share on other sites

I have been doing some work and following the Packet handling tutorial again, and I have successfully sended a packet to the tile entity, and it writes to it's nbt. That is all solved. However, when I collide with the block, it doesn't get the set height for the specific tile entity. How would I retrieve this for use in the block class. Here is the changed files

 

GuiGravityLift.java

package kris91268.lbd;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.relauncher.Side;
import kris91268.lbd.Blocks.BlockGravityLift;
import kris91268.lbd.Packet.PacketBlockChange;
import kris91268.lbd.Tileentity.TileEntityGravityLift;
import net.minecraft.client.entity.EntityClientPlayerMP;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.packet.Packet132TileEntityData;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;

/**
* 
* @author Arbiter
*
*/
public class GuiGravityLift extends GuiContainer
{
private static final ResourceLocation texture = new ResourceLocation("lbd:textures/gui/gravlift.png");
private GuiButton dnButton;
private GuiButton decByPointZeroOne;
private GuiButton decByPointOne;
private GuiButton incByPointOne;
private GuiButton incByOnePointZero;
private GuiTextField number;
public static String gravLiftHeight;
private TileEntityGravityLift tileEntity;
public EntityPlayer player;

public GuiGravityLift(InventoryPlayer par1, TileEntityGravityLift par2, EntityPlayer player)
{
	super(new ContainerGravityLift(par1, par2));
	tileEntity = par2;
	this.player = player;
}
@Override
protected void drawGuiContainerForegroundLayer(int par1, int par2)
{
	fontRenderer.drawString("Gravity Lift", 8, 6, 4210752);
	fontRenderer.drawString("Inventory", 8, ySize - 96 + 2, 4210752);
}
@Override
protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3)
{
	this.mc.func_110434_K().func_110577_a(texture);
	GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
	int x = (width - xSize) / 2;
	int y = (height - ySize) / 2;
	this.drawTexturedModalRect(x, y, 0, 0, xSize, ySize);
	this.number.drawTextBox();
}
@Override
public void initGui()
{
	super.initGui();
	Keyboard.enableRepeatEvents(true);
	this.buttonList.add(this.dnButton = new GuiButton(0, this.width / 2 - 25, this.height / 4 + 35, 50, 20, "Done"));
	this.buttonList.add(this.decByPointZeroOne = new GuiButton(1, this.width / 2 - 75, this.height / 4 + 0, 40, 20, "-0.1"));
	this.buttonList.add(this.decByPointOne = new GuiButton(2, this.width / 2 - 75, this.height / 4 + 25, 40, 20, "-1.0"));
	this.buttonList.add(this.incByPointOne = new GuiButton(3, this.width / 2 + 25, this.height / 4 + 0, 40, 20, "+0.1"));
	this.buttonList.add(this.incByOnePointZero = new GuiButton(4, this.width / 2 + 25, this.height / 4 + 25, 40, 20, "+1.0"));
	this.number = new GuiTextField(this.fontRenderer, this.width / 2 - 20, this.height / 4 + 1, 40, 20);
	this.number.setVisible(true);
	this.number.setCanLoseFocus(false);
	this.number.setFocused(true);
	this.number.setText(tileEntity.height.toString());
	gravLiftHeight = tileEntity.height.toString();
}
public void onGuiClosed()
{
	Keyboard.enableRepeatEvents(false);
	Double theNumber = Double.parseDouble(gravLiftHeight);
}
public boolean isAboveZero(String par1Str)
{
	Double theDouble = Double.parseDouble(par1Str);
	return theDouble >= 0.00 ? true : false;
}
public boolean isBelowFive(String par1Str)
{
	Double theDouble = Double.parseDouble(par1Str);
	return theDouble <= 5.00 ? true : false;
}
public void updateScreen()
{
	this.number.updateCursorCounter();
}
/**
public void mouseClicked(int par1, int par2, int par3)
{
	super.mouseClicked(par1, par2, par3);
	this.number.mouseClicked(par1, par2, par3);
}
public void keyTyped(char par1, int par2)
{
	this.number.textboxKeyTyped(par1, par2);
	((GuiButton)this.buttonList.get(0)).enabled = this.number.getText().trim().length() > 0;
	if (par2 == 28 || par2 == 156)
	{
		this.actionPerformed((GuiButton)this.buttonList.get(0));
	}
}**/
@Override
protected void actionPerformed(GuiButton guiButton)
{
	int x = tileEntity.xCoord;
	int y = tileEntity.yCoord;
	int z = tileEntity.zCoord;
	switch (guiButton.id)
	{
	case 0:
		this.mc.displayGuiScreen((GuiScreen)null);
		break;
	case 1:
		Double heightInDoubles = Double.parseDouble(gravLiftHeight);
		if (heightInDoubles != 0.0)
		{
			heightInDoubles -= 0.1;
		}
		gravLiftHeight = heightInDoubles.toString();
		number.setText(gravLiftHeight);
		PacketDispatcher.sendPacketToServer(new PacketBlockChange(heightInDoubles, tileEntity, x, y, z).makePacket());
		break;
	case 2:
		Double heightInDoubles1 = Double.parseDouble(gravLiftHeight);
		if (heightInDoubles1 < 1.0)
		{
			heightInDoubles1 = 0.0;
		}
		else
		{
			heightInDoubles1 -= 1.0;
		}
		gravLiftHeight = heightInDoubles1.toString();
		number.setText(gravLiftHeight);
		PacketDispatcher.sendPacketToServer(new PacketBlockChange(heightInDoubles1, tileEntity, x, y, z).makePacket());
		break;
	case 3:
		Double theHeight = Double.parseDouble(gravLiftHeight);
		if (theHeight != 5.0)
		{
			theHeight += 0.1;
		}
		gravLiftHeight = theHeight.toString();
		number.setText(gravLiftHeight);
		tileEntity.bindHeightToTileEntity(theHeight);
		PacketDispatcher.sendPacketToServer(new PacketBlockChange(theHeight, tileEntity, x, y, z).makePacket());
		break;
	case 4:
		Double theNumber = Double.parseDouble(gravLiftHeight);
		if (theNumber > 4.0)
		{
			theNumber = 5.0;
		}
		else
		{
			theNumber += 1.0;
		}
		gravLiftHeight = theNumber.toString();
		number.setText(gravLiftHeight);
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream(;
		DataOutputStream dataStream = new DataOutputStream(outputStream);
		try
		{
			dataStream.writeDouble(theNumber);
			dataStream.writeInt(tileEntity.xCoord);
			dataStream.writeInt(tileEntity.yCoord);
			dataStream.writeInt(tileEntity.zCoord);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		Packet250CustomPayload packet = new Packet250CustomPayload();
		packet.channel = "lbd";
		packet.data = outputStream.toByteArray();
		packet.length = outputStream.size();
		Side side = FMLCommonHandler.instance().getEffectiveSide();
		if (side == Side.SERVER)
		{
			EntityPlayerMP playerMP = (EntityPlayerMP)player;
		}
		else if (side == Side.CLIENT)
		{
			EntityClientPlayerMP clientPlayer = (EntityClientPlayerMP)player;
			clientPlayer.sendQueue.addToSendQueue(packet);
		}
		default:
			break;
	}
}
}

 

GuiGravityLiftHandler.java

package kris91268.lbd;

import kris91268.lbd.Tileentity.TileEntityGravityLift;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import cpw.mods.fml.common.network.IGuiHandler;

/**
* 
* @author Arbiter
*
*/
public class GuiGravLiftHandler implements IGuiHandler
{
@Override
public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z)
{
	TileEntityGravityLift tileEntity = (TileEntityGravityLift)world.getBlockTileEntity(x, y, z);
	return new ContainerGravityLift(player.inventory, tileEntity);
}
@Override
public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z)
{
	TileEntity tileEntity = world.getBlockTileEntity(x, y, z);
	return tileEntity instanceof TileEntityGravityLift ? new GuiGravityLift(player.inventory, (TileEntityGravityLift)tileEntity, player) : null;
}
}

 

TileEntityGravityLift.java

package kris91268.lbd.Tileentity;

import java.awt.List;

import kris91268.lbd.Blocks.BlockGravityLift;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagDouble;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet132TileEntityData;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;

/**
* 
* @author Arbiter
*
*/
public class TileEntityGravityLift extends TileEntity implements IInventory
{
private String aString;
public Double height = new Double(0.0D);			

public void readFromNBT(NBTTagCompound par1NBTTagCompound)
{
	super.readFromNBT(par1NBTTagCompound);
	height = par1NBTTagCompound.getDouble("height");
	System.out.println(height);
}
public void writeToNBT(NBTTagCompound par1NBTTagCompound)
{
	super.writeToNBT(par1NBTTagCompound);
	par1NBTTagCompound.setDouble("height", height);
	System.out.println(height);
}
public boolean isUsableByPlayer(EntityPlayer par1EntityPlayer)
{
	return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : 
		par1EntityPlayer.getDistanceSq((double)this.xCoord + 0.5D, (double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D) <= 64.0D;
}
public void something(String par1Str)
{
	this.aString = par1Str;
}
@Override
public String getInvName()
{
	return "Gravity Lift";
}
public void bindHeightToTileEntity(double theHeight)
{
	this.height = theHeight;
	worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
public double getHeightLevel()
{
	return height; 
}
public Packet getDescriptionPacket()
{
	NBTTagCompound nbt = new NBTTagCompound();
	this.writeToNBT(nbt);
	return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 3, nbt);
}
@Override
public int getSizeInventory()
{		
	return 0;
}
@Override
public ItemStack getStackInSlot(int i) 
{
	return null;
}
@Override
public ItemStack decrStackSize(int i, int j)
{
	return null;
}
@Override
public ItemStack getStackInSlotOnClosing(int i)
{
	return null;
}
@Override
public void setInventorySlotContents(int i, ItemStack itemstack)
{

}
@Override
public boolean isInvNameLocalized()
{
	return false;
}
@Override
public int getInventoryStackLimit()
{
	return 64;
}
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer)
{
	return true;
}
@Override
public void openChest()
{

}
@Override
public void closeChest()
{

}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
	return false;
}
}

 

BlockGravityLift.jaca

package kris91268.lbd.Blocks;

import java.util.Random;
import kris91268.lbd.GuiGravityLift;
import kris91268.lbd.ModLBD;
import kris91268.lbd.Tileentity.TileEntityGravityLift;
import cpw.mods.fml.common.registry.BlockProxy;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon;
import net.minecraft.world.World;

/**
* 
* @author Arbiter
*
*/
public class BlockGravityLift extends BlockContainer implements BlockProxy
{
public Class theTileEntityClass;

public BlockGravityLift(int par1, Class<? extends TileEntity> entityClass)
{
	super(par1, Material.iron);
	theTileEntityClass = entityClass;
	setHardness(1.5F);
	setResistance(1.0F);
	setStepSound(Block.soundMetalFootstep);
	setUnlocalizedName("lbd:gravityLift");
	func_111022_d("lbd:gravityLift");
	setCreativeTab(CreativeTabs.tabRedstone);
	setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.3F, 1.0F);
}
public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity)
{
	par5Entity.fallDistance = 0.0F;
	TileEntityGravityLift tileEntity = (TileEntityGravityLift)par1World.getBlockTileEntity(par2, par3, par4);
	double height = tileEntity.getHeightLevel();
	if (height <= 0.0D)
	{
		return;
	}
	if (par1World.isRemote)
	{
		if (par5Entity instanceof EntityPlayer)
		{
			par5Entity.setVelocity(0.0D, height / 2, 0.0D);
			par5Entity.moveEntity(0.0D, height, 0.0D);
		}
	}
	else
	{
		if (par5Entity instanceof EntityPlayerMP)
		{
			par5Entity.addVelocity(0.0D, height / 2, 0.0D);
			par5Entity.moveEntity(0.0D, height, 0.0D);
		}
	}
}
@Override
public void onBlockAdded(World par1World, int par2, int par3, int par4)
{
	super.onBlockAdded(par1World, par2, par3, par4);
	par1World.setBlockTileEntity(par2, par3, par4, new TileEntityGravityLift());
}
public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer player, int metadata, float par7, float par8, float par9)
{
    if (!par1World.isRemote)
    {
    	TileEntityGravityLift tileEntity = (TileEntityGravityLift)par1World.getBlockTileEntity(par2, par3, par4);
    	if (tileEntity != null)
    	{
    		player.openGui(ModLBD.instance, 0, par1World, par2, par3, par4);
    	}
    }
    return true;
}
public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random)
{
	double d0 = (double)((float)par2 + 0.5F);
	double d1 = (double)((float)par3 + 0.3F);
	double d2 = (double)((float)par4 + 0.5F);
	par1World.spawnParticle("portal", d0, d1, d2, 0.0D, 0.0D, 0.0D);
}
public boolean isOpaqueCube()
{
	return false;
}
public boolean renderAsNormalBlock()
{
	return false;
}
public int getRenderType()
{
	return -1;
}
@Override
public boolean hasTileEntity(int par1)
{
	return true;
}
public TileEntity createNewTileEntity(World par1World)
{
	try
	{
		return new TileEntityGravityLift();
	}
	catch (Exception e)
	{
		System.out.println("Error creating a new tile entity");
		return null;
	}
}
}

 

PacketHandler.java

package kris91268.lbd.Packet;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.logging.Logger;

import kris91268.lbd.Packet.PacketBase.ProtocolException;
import kris91268.lbd.Tileentity.TileEntityGravityLift;

import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet250CustomPayload;
import cpw.mods.fml.common.network.IPacketHandler;
import cpw.mods.fml.common.network.Player;
import cpw.mods.fml.relauncher.Side;

/**
* 
* @author Arbiter
*
*/
public class PacketHandler implements IPacketHandler
{
@Override
public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player)
{
	if (packet.channel.equals("lbd"))
	{
		handleHeight(packet, player);
	}
}
private void handleHeight(Packet250CustomPayload packet, Player player)
{
	DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(packet.data));
	double height;
	int x; 
	int y;
	int z;
	try
	{
		height = inputStream.readDouble();
		x = inputStream.readInt();
		y = inputStream.readInt();
		z = inputStream.readInt();
	}
	catch (IOException e)
	{
		e.printStackTrace();
		return;
	}
	EntityPlayer entityPlayer = (EntityPlayer)player;
	TileEntityGravityLift tileEntity = (TileEntityGravityLift)entityPlayer.worldObj.getBlockTileEntity(x, y, z);
	tileEntity.bindHeightToTileEntity(height);
}
}

Link to comment
Share on other sites

did you check that server really has the right value ?

 

i dont think you need to, but its always a good thing to resync from server to client

 

entityPlayer.worldObj.markBlockForUpdate(x, y, z); // or similar name

 

call this inside your packet handler AFTER youve made the changes to your TE

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

  • 2 weeks later...

OK, I have been doing some testing with other entities, and they seem to launch fine, even with different height settings set on the grav lift, its like it seems to work for everything, but the player. Why is this? (I have removed the code about the par5Entity instanceof EntityPlayer, e.t.c and just placed the methods to propel entites in the air).

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.



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • The future of Bitcoin recovery is a topic of great interest and excitement, particularly with the emergence of innovative companies like Dexdert Net Pro Recovery leading the charge. As the cryptocurrency market continues to evolve and face new challenges, the need for effective solutions to help users recover lost or stolen Bitcoin has become increasingly critical. Dexdert Net Pro, a specialized firm dedicated to this very purpose, has positioned itself at the forefront of this emerging field. Through their proprietary techniques and deep expertise in blockchain technology, Dexdert Net Pro has developed a comprehensive approach to tracking down and retrieving misplaced or compromised Bitcoin, providing a lifeline to individuals and businesses who have fallen victim to the inherent risks of the digital currency landscape. Their team of seasoned investigators and cryptography experts employ a meticulous, multi-pronged strategy, leveraging advanced data analysis, forensic techniques, and collaborative partnerships with law enforcement to painstakingly trace the movement of lost or stolen coins, often recovering funds that would otherwise be considered irrecoverable. This pioneering work not only restores financial assets but also helps to bolster confidence and trust in the long-term viability of Bitcoin, cementing Dexdert Net Pro role as a crucial player in shaping the future of cryptocurrency recovery and security. As the digital finance ecosystem continues to evolve, the importance of innovative solutions like those offered by Dexdert Net Pro will only grow, ensuring that users can navigate the complexities of Bitcoin with greater peace of mind and protection. Call Dexdert Net Pro now     
    • I'm developing a dimension, but it's kinda resource intensive so some times during player teleporting it lags behind making the player phase down into the void, so im trying to implement some kind of pregeneration to force the game loading a small set of chunks in the are the player will teleport to. Some of the things i've tried like using ServerLevel and ServerChunkCache methods like getChunk() dont actually trigger chunk generation if the chunk isn't already on persistent storage (already generated) or placing tickets, but that doesn't work either. Ideally i should be able to check when the task has ended too. I've peeked around some pregen engines, but they're too complex for my current understanding of the system of which I have just a basic understanding (how ServerLevel ,ServerChunkCache  and ChunkMap work) of. Any tips or other classes I should be looking into to understand how to do this correctly?
    • https://mclo.gs/4UC49Ao
    • Way back in the Forge 1.17 days, work started for adding JPMS (Java Platform Module Support) to ModLauncher and ForgeModLoader. This has been used internally by Forge and some libraries for a while now, but mods (those with mods.toml specifically) have not been able to take advantage of it. As of Forge 1.21.1 and 1.21.3, this is now possible!   What is JPMS and what does it mean for modders? JPMS is the Java Platform Module System, introduced in Java 9. It allows you to define modules, which are collections of packages and resources that can be exported or hidden from other modules. This allows for much more fine-tuned control over visibility, cleaner syntax for service declarations and support for sealed types across packages. For example, you might have a mod with a module called `com.example.mod` that exports `com.example.mod.api` and `com.example.mod.impl` to other mods, but hides `com.example.mod.internal` from them. This would allow you to have a clean API for other mods to use, while keeping your internal implementation details hidden from IDE hints, helping prevent accidental usage of internals that might break without prior notice. This is particularly useful if you'd like to use public records with module-private constructors or partially module-private record components, as you can create a sealed interface that only your record implements, having the interface be exported and the record hidden. It's also nice for declaring and using services, as you'll get compile-time errors from the Java compiler for typos and the like, rather than deferring to runtime errors. In more advanced cases, you can also have public methods that are only accessible to specific other modules -- handy if you want internal interactions between multiple of your own mods.   How do I bypass it? We understand there may be drama in implementing a system that prevents mods from accessing each other's internals when necessary (like when a mod is abandoned or you need to fix a compat issue) -- after all, we are already modding a game that doesn't have explicit support for Java mods yet. We have already thought of this and are offering APIs from day one to selectively bypass module restrictions. Let me be clear: Forge mods are not required to use JPMS. If you don't want to use it, you don't have to. The default behaviour is to have fully open, fully exported automatic modules. In Java, you can use the `Add-Opens` and `Add-Exports` manifest attributes to selectively bypass module restrictions of other mods at launch time, and we've added explicit support for these when loading your Forge mods. At compile-time, you can use existing solutions such as the extra-java-module-info Gradle plugin to deal with non-modular dependencies and add extra opens and exports to other modules. Here's an example on how to make the internal package `com.example.examplemod.internal` open to your mod in your build.gradle: tasks.named('jar', Jar) { manifest { attributes([ 'Add-Opens' : 'com.example.examplemod/com.example.examplemod.internal' 'Specification-Title' : mod_id, 'Specification-Vendor' : mod_authors // (...) ]) } } With the above in your mod's jar manifest, you can now reflectively access the classes inside that internal package. Multiple entries are separated with a space, as per Java's official spec. You can also use Add-Exports to directly call without reflection, however you'd need to use the Gradle plugin mentioned earlier to be able to compile. The syntax for Add-Exports is the same as Add-Opens, and instructions for the compile-time step with the Gradle plugin are detailed later in this post. Remember to prefer the opens and exports keywords inside module-info.java for sources you control. The Add-Opens/Add-Exports attributes are only intended for forcing open other mods.   What else is new with module support? Previously, the runtime module name was always forced to the first mod ID in your `mods.toml` file and all packages were forced fully open and exported. Module names are now distinguished from mod IDs, meaning the module name in your module-info.java can be different from the mod ID in your `mods.toml`. This allows you to have a more descriptive module name that doesn't have to be the same as your mod ID, however we strongly recommend including your mod ID as part of your module name to aid troubleshooting. The `Automatic-Module-Name` manifest attribute is now also honoured, allowing you to specify a module name for your mod without needing to create a `module-info.java` file. This is particularly useful for mods that don't care about JPMS features but want to have a more descriptive module name and easier integration with other mods that do use JPMS.   How do I use it? The first step is to create a `module-info.java` file in your mod's source directory. This file should be in the same package as your main mod class, and should look something like this: open module com.example.examplemod { requires net.minecraftforge.eventbus; requires net.minecraftforge.fmlcore; requires net.minecraftforge.forge; requires net.minecraftforge.javafmlmod; requires net.minecraftforge.mergetool.api; requires org.slf4j; requires logging; } For now, we're leaving the whole module open to reflection, which is a good starting point. When we know we want to close something off, we can remove the open modifier from the module and open or export individual packages instead. Remember that you need to be open to Forge (module name net.minecraftforge.forge), otherwise it can't call your mod's constructor. Next is fixing modules in Gradle. While Forge and Java support modules properly, Gradle does not put automatic modules on the module path by default, meaning that the logging module (from com.mojang:logging) is not found. To fix this, add the Gradle plugin and add a compile-time module definition for that Mojang library: plugins { // (...) id 'org.gradlex.extra-java-module-info' version "1.9" } // (...) extraJavaModuleInfo { failOnMissingModuleInfo = false automaticModule("com.mojang:logging", "logging") } The automatic module override specified in your build.gradle should match the runtime one to avoid errors. You can do the same for any library or mod dependency that is missing either a module-info or explicit Automatic-Module-Name, however be aware that you may need to update your mod once said library adds one. That's all you need to get started with module support in your mods. You can learn more about modules and how to use them at dev.java.
    • Faire la mise à jour grâce à ce lien m'a aider personnellement, merci à @Paint_Ninja. https://www.amd.com/en/support 
  • Topics

×
×
  • Create New...

Important Information

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