Jump to content

[1.3.2][SOLVED] Problem with saving/loading block's data in NBT


bormoshka

Recommended Posts

Hello again. I have a problem with saving value of TileEntity. I have items and blocks with metadata, so I can't storage angle there. When I place block - it's OK. But, when i reenter - all blocks rotated at 0 angle. Maybe I missed something.

Before:

 

before.png

 

After:

 

after.png

 

BlockFlag.java:

public class BlockFlag extends Block
{
private byte flagType;
private Class flagEntityClass;
private byte angle;
public BlockFlag(int i, Class class1)
    {
            super(i, Material.cloth);
            flagEntityClass = class1;
            setHardness(1.5F);
            setResistance(1.5F);
            setStepSound(Block.soundWoodFootstep);
            setBlockName("Minecraft Standart");
            this.setTextureFile(getTextureFile());
            blockIndexInTexture = 5;
            this.setRequiresSelfNotify();
            this.isBlockContainer = true;
    }
    public void setValue(Item anItemDrop, byte aFlagType)
    {
    	flagType = aFlagType;
    	//flagMetadata = aFlagMetadata;
    }
    public TileEntity getBlockEntity()
    {
            try
            {
                    return (TileEntity)flagEntityClass.newInstance();
            }
            catch (Exception exception)
            {
                    throw new RuntimeException(exception);
            }
    }
    public TileEntity createTileEntity(World world, int metadata)
    {
    	TileEntityFlag myTile = new TileEntityFlag();
    	myTile.setValues(flagType);
    	myTile.onInventoryChanged();
    	return myTile;
    }   
    public TileEntity createNewTileEntity(World var1)
    {
    	TileEntityFlag tileEntityFlag = new TileEntityFlag();
    	return tileEntityFlag;
    }
    public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
    {
// NOT IMPORTANT
    }
    private boolean canPlaceFlagOn(World par1World, int par2, int par3, int par4)
    {
// NOT IMPORTANT
    }
    protected int damageDropped(int par1)
    {
        return par1;
    }
    public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
    {
        return canPlaceFlagOn(par1World, par2, par3 - 1, par4);
    }
    private boolean dropFlagIfCantStay(World par1World, int par2, int par3, int par4)
    {
// NOT IMPORTANT
    }
    public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
    {
// NOT IMPORTANT
    }
    public int idDropped(int i, Random random, int j)
    {
            return UltimateExtender.itemFlag.shiftedIndex;
    }
    @SideOnly(Side.CLIENT)

    /**
     * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks)
     */
    public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List)
    {
// NOT IMPORTANT
    }
    public int quantityDropped(Random random)
    {
            return 1;
    }
    public int getRenderType()
    {
            return -1;
    }
    @Override
    public String getTextureFile()
    {
        return Params.TEXTURE_PATH_BLOCKS;
    }
    public boolean isOpaqueCube()
    {
            return false;
    }
    public boolean renderAsNormalBlock()
    {
            return false;
    }
    public void onBlockAdded(World par1World, int par2, int par3, int par4)
    {
        super.onBlockAdded(par1World, par2, par3, par4);
        TileEntityFlag myTile = (TileEntityFlag)this.createTileEntity(par1World, par1World.getBlockMetadata(par2, par3, par4));
        par1World.setBlockTileEntity(par2, par3, par4, myTile);        
    }
    public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving)
    {
    	TileEntityFlag myTile = (TileEntityFlag)par1World.getBlockTileEntity(par2, par3, par4);
    	this.angle = (byte) (MathHelper.floor_double((double)(par5EntityLiving.rotationYaw + 180.0F) * 16.0F / 360.0F) & 15);
    	myTile.angle = this.angle;
    	myTile.onInventoryChanged();
    }
    public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
    {
        super.breakBlock(par1World, par2, par3, par4, par5, par6);
        par1World.removeBlockTileEntity(par2, par3, par4);
    }
    
}

ItemFlag.java

public class ItemFlag extends Item
{
private int blockID;
public static String[] flagNames = new String[]{"flag1","flag2","flag3","flag4","flag5","flag6","flag7","flag8",
"flag9","flag10","flag11","flag12","flag13","flag14","flag15","flag16"};

    public ItemFlag(int i, Block block)
    {
        super(i);
        blockID = block.blockID;
        this.setHasSubtypes(true);
        this.setMaxDamage(0);
    }
    public int getIconFromDamage(int par1)
    {
    	int var2 = MathHelper.clamp_int(par1, 0, 15);
        return this.iconIndex + var2;
    }
    public String getItemNameIS(ItemStack par1ItemStack)
    {
        int var2 = MathHelper.clamp_int(par1ItemStack.getItemDamage(), 0, 15);
        return super.getItemName() + "." + flagNames[var2];
    }
    @SideOnly(Side.CLIENT)

    /**
     * returns a list of items with the same ID, but different meta (eg: dye returns 16 items)
     */
    public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List)
    {
        for (int var4 = 0; var4 < 16; ++var4)
        {
            par3List.add(new ItemStack(par1, 1, var4));
        }
    }
    public int getMetadata(int par1)
    {
        return par1;
    }
    public int getBlockID()
    {
        return this.blockID;
    }   
    public boolean tryPlaceIntoWorld(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, 
World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10)
    {
        int var11 = par3World.getBlockId(par4, par5, par6);

        if (var11 == Block.snow.blockID)
        {
            par7 = 1;
        }
        else if (var11 != Block.vine.blockID && var11 != Block.tallGrass.blockID && var11 != Block.deadBush.blockID
                && (Block.blocksList[var11] == null || !Block.blocksList[var11].isBlockReplaceable(par3World, par4, par5, par6)))
        {
            if (par7 == 0)
            {
                --par5;
            }

            if (par7 == 1)
            {
                ++par5;
            }

            if (par7 == 2)
            {
                --par6;
            }

            if (par7 == 3)
            {
                ++par6;
            }

            if (par7 == 4)
            {
                --par4;
            }

            if (par7 == 5)
            {
                ++par4;
            }
        }

        if (par1ItemStack.stackSize == 0)
        {
            return false;
        }
        else if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6))
        {
            return false;
        }
        else if (par5 == 255 && Block.blocksList[this.blockID].blockMaterial.isSolid())
        {
            return false;
        }
        else if (par3World.canPlaceEntityOnSide(this.blockID, par4, par5, par6, false, par7, par2EntityPlayer))
        {
            Block var12 = Block.blocksList[this.blockID];

            if (placeBlockAt(par1ItemStack, par2EntityPlayer, par3World, par4, par5, par6, par7, par8, par9, par10))
            {
                par3World.playSoundEffect((double)((float)par4 + 0.5F), 
(double)((float)par5 + 0.5F), (double)((float)par6 + 0.5F), var12.stepSound.getStepSound(), 
(var12.stepSound.getVolume() + 1.0F) / 2.0F, var12.stepSound.getPitch() * 0.8F);
                --par1ItemStack.stackSize;
            }

            return true;
        }
        else
        {
            return false;
        }
    }
    public boolean placeBlockAt(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
    {
       if (!world.setBlockAndMetadataWithNotify(x, y, z, this.blockID, this.getMetadata(stack.getItemDamage())))
       {
               return false;
       }

       if (world.getBlockId(x, y, z) == this.blockID)
       {
           Block.blocksList[this.blockID].updateBlockMetadata(world, x, y, z, side, hitX, hitY, hitZ);
           Block.blocksList[this.blockID].onBlockPlacedBy(world, x, y, z, player);
       }

       return true;
    }
}

TileEntityFlag.java:

public class TileEntityFlag extends TileEntity
{
public byte angle;
private byte type;
    public void writeToNBT(NBTTagCompound par1NBTTagCompound)
    {
        super.writeToNBT(par1NBTTagCompound);
        par1NBTTagCompound.setByte("ang", this.angle);
        par1NBTTagCompound.setByte("type", this.type);
    }
    public void readFromNBT(NBTTagCompound par1NBTTagCompound)
    {
        super.readFromNBT(par1NBTTagCompound);
        this.type = par1NBTTagCompound.getByte("type");
        this.angle = par1NBTTagCompound.getByte("ang");
    }
    public void setAngle(byte i)
    {
        this.angle = i;
    }
    public int getAngle()
    {
        return this.angle;
    }
    public void setValues(byte i)
    {
        this.type = i;
    }
    public int getType()
    {
        return this.type;
    }
}

Link to comment
Share on other sites

I don't know why, but its not.

In Render i'm trying to get angle from TileEntity is it right?

public void renderFlag(TileEntity tileEntity, double d, double d1, double d2, float f)
    {
    	
    TileEntityFlag myTile = (TileEntityFlag)tileEntity;
    //System.out.println(myTile.getSkin());
    float deg = (float)(myTile.getAngle() * 360) / 16.0F;
    int i = myTile.getType();
    int j = myTile.getBlockMetadata();
    GL11.glPushMatrix();
    GL11.glTranslatef((float)d + 0.5F, (float)d1 + 1.5F, (float)d2 + 0.5F);
            GL11.glScalef(1.0F, 1.0F, 1.0F);
            GL11.glRotatef(180F, 0.0F, 0.0F, 1.0F);
            GL11.glRotatef(deg, 0.0F, 1.0F, 0.0F);
            bindTextureByName(getPath(i,j));
            modelFlag.render(0.0625F);
            GL11.glPopMatrix();
    }

 

 

Link to comment
Share on other sites

Might want to send a packet to the client with the angle in it so the render can get the updated angle. Also might want to send what ever other info the client needs for the render as well.

 

 

If you need help making packet stuff check out my gitup https://github.com/DarkGuardsman

Link to comment
Share on other sites

Thanks, I'll try. But I'm testing it in singleplayer and this value is saves and loads(after exit) propertly:

public TileEntity createTileEntity(World world, int metadata)

    {

    TileEntityFlag myTile = new TileEntityFlag();

    myTile.setValues(flagType);

    myTile.onInventoryChanged();

    return myTile;

    }

and this is not:

public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving)

    {

    TileEntityFlag myTile = (TileEntityFlag)par1World.getBlockTileEntity(par2, par3, par4);

    this.angle = (byte) (MathHelper.floor_double((double)(par5EntityLiving.rotationYaw + 180.0F) * 16.0F / 360.0F) & 15);

    myTile.angle = this.angle;

    myTile.onInventoryChanged();

    }

Link to comment
Share on other sites

Thanks, I'll try. But I'm testing it in singleplayer and this value is saves and loads(after exit) propertly:

public TileEntity createTileEntity(World world, int metadata)

    {

    TileEntityFlag myTile = new TileEntityFlag();

    myTile.setValues(flagType);

    myTile.onInventoryChanged();

    return myTile;

    }

and this is not:

public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving)

    {

    TileEntityFlag myTile = (TileEntityFlag)par1World.getBlockTileEntity(par2, par3, par4);

    this.angle = (byte) (MathHelper.floor_double((double)(par5EntityLiving.rotationYaw + 180.0F) * 16.0F / 360.0F) & 15);

    myTile.angle = this.angle;

    myTile.onInventoryChanged();

    }

You sure in 1.3.2 Minecraft single player is a lan server. I use to think it worked fine til a lot of my stuff stopped updating correctly. Namely the rotation of my Machines for several of my mods.

Link to comment
Share on other sites

You sure in 1.3.2 Minecraft single player is a lan server. I use to think it worked fine til a lot of my stuff stopped updating correctly. Namely the rotation of my Machines for several of my mods.

Ok, maybe when i create TileEntity and change some values in createTileEntity(World world, int metadata) it works, but if I trying to change it from client side - it fails. That's why I must create proper packet exchange. So I looked in your code, made something that look pretty the same... but it fails again. So can you or someone that reads this help with this? Maybe manuals or something?

 

Link to comment
Share on other sites

You sure in 1.3.2 Minecraft single player is a lan server. I use to think it worked fine til a lot of my stuff stopped updating correctly. Namely the rotation of my Machines for several of my mods.

Ok, maybe when i create TileEntity and change some values in createTileEntity(World world, int metadata) it works, but if I trying to change it from client side - it fails. That's why I must create proper packet exchange. So I looked in your code, made something that look pretty the same... but it fails again. So can you or someone that reads this help with this? Maybe manuals or something?

next chance i get i'll create a short tut on the subject, or at least raw code that can be copied.

Link to comment
Share on other sites

Ok, this if funny, I just went through this EXACT same problem, and for me the key lied in... signs! :-P

 

If you look at how the signs metadata works, that's EXACTLY what you want... so, here's some of the legwork done for ya':

 

Just look at

ItemSign.java for how your ItemFlag.java should be

BlockSign.java for how your BlockFlag.java should be

TileEntitySign.java for how your TileEntityFlag.java should be

 

Also, do NOT forget to do the following when your mod loads....

Make SURE you register your tileentity like this....

 

GameRegistry.registerTileEntity(TileEntityFlag.class, "ang");

 

Also, in your ItemFlag, you should probably pass the angle to it then using something like:

int myAng = MathHelper.floor_double((double)((par2EntityPlayer.rotationYaw + 180.0F) * 16.0F / 360.0F) + 0.5D) & 15;

(it just gets the angle from the player's angle)

 

Now let me know if you still can't sort it out, but I believe most of what you're doing should be covered by the sign example.

Also, you should really put the following line of code in your stuff so you can track what angle it's storing, and getting....

Minecraft mc = Minecraft.getMinecraft();
mc.thePlayer.sendChatMessage(""+ang);

 

Now lastly, here's a brief overview of how your metadata should be working:

When you place the flag ItemFlag gets the angle from the player, then it passes the data to the block's metadata

The TileEntityFlag just handles the reading and writing of the metadata (which seems kinda repetitive and unnecessary to me, but that's how it is! :-P)

The BlockFlag should then reads that metadata

 

Now.... with all that said... are you sure you can't just extend the "Sign" class, override the render type and a few things, and call it good? :-P LOL

 

Good luck to ya', let me know if you have any questions about my irrational ramblings! :-P

 

I struggled with this same exact problem for a week though, and it took me that long, to reach this level of insanity (and yes, I finally got it working last night, due to registering my tileentity class) :-)

 

 

 

Link to comment
Share on other sites

speaking of sign class there is a method in there to send a packet to the client with the sign text. You can change it up a bit to fit your needs.

 /**
     * signs and mobSpawners use this to send text and meta-data
     */
    public Packet getAuxillaryInfoPacket()
    {
        String[] var1 = new String[4];
        System.arraycopy(this.signText, 0, var1, 0, 4);
        return new Packet130UpdateSign(this.xCoord, this.yCoord, this.zCoord, var1);
    }

change packet to Packet250 or what ever the custom packet is. I  used this for a while till i need to update the server from the client. However if you want to do it the more reusable way, in which you can set it up to send any info to and from the server.

 

 

Your packet Handler class

public class PacketManager implements IPacketHandler
{
@Override
public void onPacketData(NetworkManager network, Packet250CustomPayload packet, Player player)
{
	try
        {
		ByteArrayDataInput data = ByteStreams.newDataInput(packet.data);
		int x = data.readInt();
		int y = data.readInt();
		int z = data.readInt();
                        //the following two are not used but can be for sorting packets by ID and restricting packet reading by lengths
		int id = data.readInt();//packet ID your welcome to set to zero 
		int l = data.readInt(); //packet length a safety var to make sure only data is read.
		EntityPlayer ePlayer = (EntityPlayer) player;
		if(ePlayer != null)
		{
			TileEntity tileEntity = ePlayer.worldObj.getBlockTileEntity(x, y, z);

			if(tileEntity != null)
			{
				if(tileEntity instanceof IPacketReceiver)
				{
					((IPacketReceiver) tileEntity). handlePacketData(network,packet.channel,
							data);

				}
			}
		}
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
}
/**
 * 
 * @param sender - TileEntity sending this packet
 * @param channelName - channel name "channelName"
 * @param id - packet id 
 * @param sendData - list of Integers to be sent is read after main data
 * @param string - list of strings to be sent is read last
 * @return a constructed packet ready to be sent
 */
     //If your looking for a better version check out Calclavia's PacketManager his is very well developed
public static Packet TECommonPacket(TileEntity sender, String channelName,int id, int[] sendData, String[] string)
    {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        DataOutputStream data = new DataOutputStream(bytes);

        try
        {
            data.writeInt(sender.xCoord);
            data.writeInt(sender.yCoord);
            data.writeInt(sender.zCoord);
            data.writeInt(id);
            data.writeInt(3+sendData.length);
           //only writes ints and string you can change this to write anything
            for(int i =0; i < sendData.length; i++)
            {
                data.writeInt(sendData[i]);
            }
            for(int i =0; i < string.length; i++)
            {
                data.writeUTF(string[i]);
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

        Packet250CustomPayload packet = new Packet250CustomPayload();
        packet.channel = "ChannelName";//TODO change to registered channel for you mod
        packet.data = bytes.toByteArray();
        packet.length = packet.data.length;
        packet.isChunkDataPacket = true;
        return packet;
    }

}

Here is the IPacketHandler interface. Implement this in every tileEntity you need to send packets with.

 

package npc.Network;
import net.minecraft.src.NetworkManager;

import com.google.common.io.ByteArrayDataInput;

public interface IPacketReceiver
{
    /**
     * Sends the tileEntity the rest of the data
     */
    public void handlePacketData(NetworkManager network, String channel, ByteArrayDataInput data);
}

Your tileEntity

public class TileEntity extends TileEntity{
   
    @Override
    public void updateEntity()
    {
//highly suggest setting a timer function to only send a packet every so often, also you can change send packetToAll to sendToAll around to reduce lag furthur
    	if(!worldObj.isRemote)
    	{
                      FMLCommonHandler.instance().getMinecraftServerInstance().getConfigurationManager().sendPacketToAllPlayers(getPacket());
		    	
    	}
    	
    	super.updateEntity();
    }
  
  public Packet getPacket()
{
	int[] data = this.getSendLoadInt(); ;
	if(data == null)
	{
		data = new int[]{};
	}
	String[] string = this.getSendLoadStr(); ;
	if(string == null)
	{
		string = new String[]{};
	}
	return PacketManager.TECommonPacket(this, "ChannelName",0, data,string );//TODO change channel name
}
   
 @Override
  public int[] getSendLoadInt()
	{
		return new int[] {angle,type,etc};	//TODO	//array that stores all int that need to be sent by packet make sure what is in here ir read in handlePacketData	
	}
 @Override
	public void handlePacketData(NetworkManager network, String channel, ByteArrayDataInput data) {

		if(worldObj.isRemote)
		 {
                              //this.angle = (int)data.readInt();
                              //this.type = (int)data.readInt();

		 }



	}
public void updateInfo(int[] sRange) {
	if(sRange.length == 5)
	{
	this.minX = sRange[1];
	this.minZ = sRange[2];
	this.maxX = sRange[3];
	this.maxZ = sRange[4];
	}

}


}
}

in you main mod class make sure you have this

@NetworkMod(channels = { "ChannelName" }, clientSideRequired = true, serverSideRequired = false, packetHandler = PacketManager.class)

 

 

Link to comment
Share on other sites

Bandayd, thanks for inchat debug. I can't use metadata - its used for skin. I've used metadata for storage rotation value, but here I cant =C

 

DarkGuardsman, Thanks! It works!

For history:

TileEntity

public class TileEntityFlag extends TileEntity implements IPacketReceiver
{
public int angle;
public int type;
    public void writeToNBT(NBTTagCompound par1NBTTagCompound)
    {
        super.writeToNBT(par1NBTTagCompound);
        par1NBTTagCompound.setInteger("type", this.type);
        par1NBTTagCompound.setInteger("ang", this.angle);
    }
    public void readFromNBT(NBTTagCompound par1NBTTagCompound)
    {
        super.readFromNBT(par1NBTTagCompound);
        this.type = par1NBTTagCompound.getInteger("type");
        this.angle = par1NBTTagCompound.getInteger("ang");
    }
    public int getAngle()
    {
        return this.angle;
    }
    public void setValues(byte i, byte j)
    {
        this.type = i;
        this.angle = j;
    }
    public int getType()
    {
        return this.type;
    }
    //method used for getting packet from PacketManager
public Packet getPacket()
{
	int[] data = this.getSendLoadInt(); ;
	if(data == null)
	{
		data = new int[]{};
	}
	return PacketManager.TECommonPacket(this, "UltimateExtender", 0, data);
}
public int[] getSendLoadInt()
	{
		return new int[] {angle,type};	//array that stores all int that need to be sent by packet make sure what is in here ir read in handlePacketData	
	}
//is it a standard method?
public Packet getAuxillaryInfoPacket()
    {
        return getPacket();
    }
@Override
public void handlePacketData(NetworkManager network, String channel, ByteArrayDataInput data) {
	try
        {
            this.angle = data.readInt();
            this.type = data.readInt();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
}
}

 

PacketManager

public class PacketManager implements IPacketHandler
{
//thanks to DarkGuardsman 
@Override
public void onPacketData(NetworkManager network, Packet250CustomPayload packet, Player player)
{
	try
        {
		ByteArrayDataInput data = ByteStreams.newDataInput(packet.data);
		int x = data.readInt();
		int y = data.readInt();
		int z = data.readInt();
                        //the following two are not used but can be for sorting packets by ID and restricting packet reading by lengths
		int id = data.readInt();//packet ID your welcome to set to zero 
		int l = data.readInt(); //packet length a safety var to make sure only data is read.
		EntityPlayer ePlayer = (EntityPlayer) player;
		if(ePlayer != null)
		{
			TileEntity tileEntity = ePlayer.worldObj.getBlockTileEntity(x, y, z);

			if(tileEntity != null)
			{
				if(tileEntity instanceof IPacketReceiver)
				{
					((IPacketReceiver) tileEntity). handlePacketData(network,packet.channel,
							data);

				}
			}
		}
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
}
/**
 * 
 * @param sender - TileEntity sending this packet
 * @param channelName - channel name "channelName"
 * @param id - packet id 
 * @param sendData - list of Integers to be sent is read after main data
 * @param string - list of strings to be sent is read last
 * @return a constructed packet ready to be sent
 */
     //If your looking for a better version check out Calclavia's PacketManager his is very well developed
public static Packet TECommonPacket(TileEntity sender, String channelName,int id, int[] sendData)
    {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        DataOutputStream data = new DataOutputStream(bytes);

        try
        {
            data.writeInt(sender.xCoord);
            data.writeInt(sender.yCoord);
            data.writeInt(sender.zCoord);
            data.writeInt(id);
            data.writeInt(3+sendData.length);
           //Here we writes our data;
            for(int i =0; i < sendData.length; i++)
            {
                data.writeInt(sendData[i]);
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

        Packet250CustomPayload packet = new Packet250CustomPayload();
        packet.channel = "UltimateExtender";//TODO change to registered channel for you mod
        packet.data = bytes.toByteArray();
        packet.length = packet.data.length;
        packet.isChunkDataPacket = true;
        return packet;
    }
}

 

YAY!

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

    • I'm using Modrinth as a launcher for a forge modpack on 1.20.1, and can't diagnose the issue on the crash log myself. Have tried repairing the Minecraft instillation as well as removing a few mods that have been problematic for me in the past to no avail. Crash log is below, if any further information is necessary let me know. Thank you! https://paste.ee/p/k6xnS
    • Hey folks. I am working on a custom "Mecha" entity (extended from LivingEntity) that the player builds up from blocks that should get modular stats depending on the used blocks. e.g. depending on what will be used for the legs, the entity will have a different jump strength. However, something unexpected is happening when trying to override a few of LivingEntity's functions and using my new own "Mecha" specific fields: instead of their actual instance-specific value, the default value is used (0f for a float, null for an object...) This is especially strange as when executing with the same entity from a point in the code specific to the mecha entity, the correct value is used. Here are some code snippets to better illustrate what I mean: /* The main Mecha class, cut down for brevity */ public class Mecha extends LivingEntity { protected float jumpMultiplier; //somewhere later during the code when spawning the entity, jumpMultiplier is set to something like 1.5f //changing the access to public didn't help @Override //Overridden from LivingEntity, this function is only used in the jumpFromGround() function, used in the aiStep() function, used in the LivingEntity tick() function protected float getJumpPower() { //something is wrong with this function //for some reason I can't correctly access the fields and methods from the instanciated entity when I am in one of those overridden protected functions. this is very annoying LogUtils.getLogger().info(String.valueOf(this.jumpMultiplier))) //will print 0f return this.jumpMultiplier * super.getJumpPower(); } //The code above does not operate properly. Written as is, the entity will not jump, and adding debug logs shows that when executing the code, the value of this.jumpMultiplier is 0f //in contrast, it will be the correct value when done here: @Override public void tick() { super.tick(); //inherited LivingEntity logic //Custom logic LogUtils.getLogger().info(String.valueOf(this.jumpMultiplier))) //will print 1.5f } } My actual code is slightly different, as the jumpMuliplier is stored in another object (so I am calling "this.legModule.getJumpPower()" instead of the float), but even using a simple float exactly like in the code above didn't help. When running my usual code, the object I try to use is found to be null instead, leading to a crash from a nullPointerException. Here is the stacktrace of said crash: The full code can be viewed here. I have found a workaround in the case of jump strength, but have already found the same problem for another parameter I want to do, and I do not understand why the code is behaving as such, and I would very much like to be able to override those methods as intended - they seemed to work just fine like that for vanilla mobs... Any clues as to what may be happening here?
    • Please delete post. Had not noticed the newest edition for 1.20.6 which resolves the issue.
    • https://paste.ee/p/GTgAV Here's my debug log, I'm on 1.18.2 with forge 40.2.4 and I just want to get it to work!! I cant find any mod names in the error part and I would like some help from the pros!! I have 203 mods at the moment.
  • Topics

×
×
  • Create New...

Important Information

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