Jump to content

Recommended Posts

Posted

I have a custom pickaxe that extends ItemPickaxe, the goal is for the onItemUse method to dig out a hole in front of it whenever the right click happens. What actually happens is for a second, it replaces the blocks with the desired block (air), then fixes it to it's original position. It also refuses to damage the item (inside of the same method) My hypothesis is that it's reverting any changes made during onItemUse. Does anyone know why, and how to fix it?

 

Class for the pickaxe:

 

public class OrangePickaxe extends ItemPickaxe{

public String name = "orangepickaxe";
public static boolean isReady = true;
public static Timer timer;
public static Timer errorTimer;
public static Timer timeWaited;
public static boolean isErrorReady = false;
public static int timeToWait;

public OrangePickaxe() {
	super(ToolMaterial.IRON);
	setUnlocalizedName(Constants.MODID + "_" + name);
	setTextureName(Constants.MODID + ":" + name);
	setCreativeTab(Main.tabOrange);

	GameRegistry.registerItem(this, name);
}

@Override
public boolean onItemUse(ItemStack itemStack,
							EntityPlayer entityPlayer,
							World world, int posX,
							int posY, int posZ, int p_77648_7_,
							float p_77648_8_, float p_77648_9_, float p_77648_10_){

	if (isReady){

		//How many blocks were broken
		int blocksBroken = 0;

		if (isValid(world.getBlock(posX, posY, posZ)) != Blocks.air){
			dropItem(world, posX, posY, posZ); //Not working!

			//Setting the time to wait (Printing purposes)
			timeToWait = 5;

			itemStack.damageItem(10, entityPlayer); //Not working!
			isReady = false;
			isErrorReady = false;

			//Setting up the chat printing
			IChatComponent msg1 = new ChatComponentText(EnumChatFormatting.GOLD +
												"I dug a small cave for you, I'd you to know that");
			IChatComponent msg2 = new ChatComponentText(EnumChatFormatting.GOLD + 
												"everytime you do this, I die a little inside.");

			//Printing to chat
			entityPlayer.addChatMessage(msg1);
			entityPlayer.addChatMessage(msg2);

			//Setting up the timer to allow the skill again
			timer = new Timer(5000, new ValidatePickaxe());
			timer.start();

			//Setting up the timer to prevent error-message spamming
			errorTimer = new Timer(1000, new ValidateError());
			errorTimer.start();

			//Setting up the timer to count how long as passed (Printing purposes)
			timeWaited = new Timer(1000, new IncrementSeconds());
			timeWaited.start();


			return true;

		} else {
			return false;
		}
	} else {

		if (isErrorReady){

			//Printing out the error message
			IChatComponent msg = new       ChatComponentText(EnumChatFormatting.GOLD +
														"The Dig skill is still on cooldown! Time Remaining: "
														+ timeToWait + " seconds");
			entityPlayer.addChatMessage(msg);

			isErrorReady = false;

			//Setting up the timer to prevent error-message spamming
			errorTimer = new Timer(1000, new ValidateError());
			errorTimer.start();

		}
		return false;
	}


}

/*
 * Handles the block dropping and block destroying
         * Not working!
 */
public static void dropItem(World world, int x, int y, int z) {

	//Dropping a block for the player to pick up
	EntityItem item = new EntityItem(world, x, y, z, new ItemStack(world.getBlock(x,y,z), 1));
	world.spawnEntityInWorld(item);

	//Setting the current block to air
	world.setBlock(x, y, z, Blocks.air);

}

/*
 * To check if the block is a valid
 * block to mine
 */
public static Block isValid(Block block){

	if (block == Blocks.stone
		|| block == Blocks.dirt
		|| block == Blocks.gravel
		|| block == Blocks.redstone_ore
		|| block == Blocks.lapis_ore
		|| block == Blocks.gold_ore
		|| block == Blocks.iron_ore
		|| block == Blocks.diamond_ore){

		return block;

	} else {
		return Blocks.air;
	}
}

/**
     * Return the enchantability factor of the item, most of the time is based on material.
    */
@Override
    public int getItemEnchantability()
    {
        return 0;
    }

/**
     * Return whether this item is repairable in an anvil.
    */
@Override
    public boolean getIsRepairable(ItemStack p_82789_1_, ItemStack p_82789_2_)
    {
        return false;
    }

}

 

 

One more thing --

The bit I have about the ItemEntity inside of the dropItem method, it never allows me to pickup the dropped block. Why?

 

Any help is greatly appreciated.

Posted

Hi

 

Those symptoms sound very much like a client<-->server mismatch; i.e. that these actions are happening on the client side but not on the server side.  So you see something happen on the client side (block replaced by air) but the server then immediately overwrites it again, the item won't damage because it's not being damaged on the server, and the dropped item doesn't really exist because the server doesn't know about it.

 

I think it might be because you are using static "ready" flags: on the first call (on the client) isReady is true.  The client sets it to false.  The method is then called a short time later on the server (in response to a vanilla packet), and this time the isReady is false so it does nothing.

 

Easy to test if you put this line at the top of your onItemUse

System.out.println("onItemUse " + (world.isRemote ? "[Client]" : "[server]") + "; isReady:" + isReady);

 

Also, if other players join your game, the isReady will interfere between different players.

 

You need to store the status flags for the action somewhere else; for example in the ItemStack NBT,

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

or in a variable in one of your own classes that is unique for each client, as well as a unique variable on the server for every connected client.

 

-TGG

 

 

 

Posted

This is the output of the suggested println statement;

 

[sTDOUT]: [com.zacharysturtz.items.OrangePickaxe:onItemUse:63]: onItemUse [Client]; isReady:true

 

I think it might be because you are using static "ready" flags: on the first call (on the client) isReady is true.  The client sets it to false.  The method is then called a short time later on the server (in response to a vanilla packet), and this time the isReady is false so it does nothing.

 

The timers I call reset the isReady boolean. I have tested that it does actually execute the if (isReady) statement at the desired time. The issue is with the first bit you said, how would I fix it so it renders server-side as well?

 

Those symptoms sound very much like a client<-->server mismatch; i.e. that these actions are happening on the client side but not on the server side.  So you see something happen on the client side (block replaced by air) but the server then immediately overwrites it again, the item won't damage because it's not being damaged on the server, and the dropped item doesn't really exist because the server doesn't know about it.

 

 

Also, I will look in to the NBT status flags you were talking about.

Posted

I have changed onItemUse(parameters) to onItemUseFirst(parameters) and now, when I set the block to air, it seems to work. That is, until I try to place a block touching the said block or remove a block touching it. When I interact with the removed block in any way, the broken block reappears.

 

For instance,

 

Method is called

Block is replaced by air

I try to place a block over air

Old block reappears in same position

 

I must really be missing something..

Posted

Hi

 

Interesting that you don't get any Server println at all.  For sure you should, eg

[sTDOUT]: [com.zacharysturtz.items.OrangePickaxe:onItemUse:63]: onItemUse [server]; isReady:true

 

When your client presses a key to use the item, vanilla normally calls onItemUse locally and also sends a packet to the server, which executes onItemUse on the server as well.

 

I don't understand why that's not happening for you.  How is the item use triggered, are you calling it manually?

 

-TGG

Posted

I have changed onItemUse(parameters) to onItemUseFirst(parameters) and now, when I set the block to air, it seems to work. That is, until I try to place a block touching the said block or remove a block touching it. When I interact with the removed block in any way, the broken block reappears.

That's another symptom of the same problem.  You place the air block on the client, but s soon as the server updates that air block information (because you place another block next to it), the client air block is overwritten with the original which is still on the server.

 

-TGG

Posted

I do not call onItemUse manually, but let it happen normally through @Override. I have almost completely integrated NBTTagCompound as well.

 

@Override
public boolean onItemUse(ItemStack itemStack,
							EntityPlayer entityPlayer,
							World world, int posX,
							int posY, int posZ, int p_77648_7_,
							float p_77648_8_, float p_77648_9_, float p_77648_10_){

Posted

That's.. Odd.. I set it so if you just hold right click it will break all the blocks you look at and drop them.. It works perfectly. Damages the item, drops the blocks which I can pickup, and removes the blocks.. But not if there's a timer?

 

 

Edit: Nevermind with the timer thing. The other issue above is still.. An issue, though.

Posted

Add a

if(!world.isRemote)

at the start of the method, and wrap all your current code in that if-statement.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

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



×
×
  • Create New...

Important Information

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