Jump to content

[1.8] Tool that can be used only once.


Koward

Recommended Posts

Hi !

 

I decided to create a tool that can only be used once.

The setMaxDamage(n) method allows a tool to be used n+1 times. But when n = 0, it makes the tool indestructible. (IMHO they should have assigned the negatives numbers to that, since n is an integer anyway.. but hey, there might be a reason)

So I had to find another way. I tried using an event to damage the tool immediately when it's crafted :

public class ToolsEventHandler {
@SubscribeEvent
public void onCrafting(ItemCraftedEvent event){
	if(event.crafting.getItem() == ModItems.stupid_pickaxe) event.crafting.setItemDamage(0);
}
}

 

But I do not see any effect. I registered this event on the FML bus and I do think it's the right one..

I could break the tool as soon as it hits a block with an event, but I do not know any method allowing that.

Anyone has an elegant solution ?

I hope I'm not asking here a stupid question.

 

Link to comment
Share on other sites

Find the method where vanilla tools or swords take extra damage when breaking the "wrong" kinds of blocks. Make your tool take 2 damage every time it breaks a block.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

In you item class (where you initialize you items) try putting in this code:

 

public static final ToolMaterial testToolMaterial = EnumHelper.addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, float damage, int enchantablility);

 

name - should be the same as you variable name, but you can change it.

harvestLevel - used for which blocks can be mined

maxUses - this is what you are looking for. This is basically how much damage your tool can take. Set this value to 1 or something like that. Play around with it and see what you can do

efficiency - how fast can it break blocks (pickaxes)

damage - how much damage it does against an entity

enchantablility - how much the tool can be enchanted

 

Then just create a new class that extends the type of tool you want.

Ex:

public class TestTool extends ItemPickaxe

 

Then just let it add in the constructor. Make sure in your items class that your tool is initialized to "TestTool()" or whatever you named your tool class.

 

 

You might want to refer to this article in the future: http://bedrockminer.jimdo.com/modding-tutorials/basic-modding-1-7/custom-tools-swords/

It may be for 1.7, but it is actually the same thing for 1.8.

He actually has some great tutorials for beginners

Link to comment
Share on other sites

Thank you everyone.

I was aware of the maxUse value but this one also makes the tool indestructible if you put it to 0 and gives two uses if you put it to 1.

I found a "solution" with

	@SubscribeEvent
public void onCrafting(ItemCraftedEvent event){
	if(event.crafting.getItem() == ModItems.stupid_pickaxe) event.crafting.damageItem(1, event.player);
}

But I should try the 2 damage per block idea, that should be cleaner.

Link to comment
Share on other sites

Thank you everyone.

I was aware of the maxUse value but this one also makes the tool indestructible if you put it to 0 and gives two uses if you put it to 1.

I found a "solution" with

	@SubscribeEvent
public void onCrafting(ItemCraftedEvent event){
	if(event.crafting.getItem() == ModItems.stupid_pickaxe) event.crafting.damageItem(1, event.player);
}

But I should try the 2 damage per block idea, that should be cleaner.

 

If you want your item to be destroyed upon one use, just listen for when you use your item (however you handle that), and if you did use it, you can destroy that item manually in code, giving you one use.

 

entityPlayer.inventory.consumeInventoryItem(THEITEMYOUWANTTODESTROY);

Development of Plugins [2012 - 2014] Development of Mods [2012 - Current]

Link to comment
Share on other sites

If you want your item to be destroyed upon one use, just listen for when you use your item (however you handle that), and if you did use it, you can destroy that item manually in code, giving you one use.

 

entityPlayer.inventory.consumeInventoryItem(THEITEMYOUWANTTODESTROY);

This is a horrible idea. Think again.

 

Please elaborate.

 


public class TestItem extends Item
{

//One use (decrements your stack upon use i.e destroying the item depending if your stack size is 1)

@Override
public ItemStack onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn)
{
	playerIn.inventory.consumeInventoryItem(this); //You can use itemStackIn.stackSize--; here - this demonstrates using with the player instance
	return itemStackIn;
}

}

 

EDIT: I see what you mean after some more testing - this will not work due to the fact that consumeInventoryItem decrements the itemstack's stacksize at the nearest stack in the player's inventory (meaning sometimes not the item you are holding i.e another stack of the same item located in your inventory). Sorry about that - misinterpreted what that method really does.

 

@OP I would stick with the crafting table damage to get 1 use.

Development of Plugins [2012 - 2014] Development of Mods [2012 - Current]

Link to comment
Share on other sites

  • 2 weeks later...

I thought I had solved the problem but the OnCrafting event doesn't seem to be always called, resulting in unpredictable behavior and sometimes two uses pickaxes. Raaaah !

 

I'm thinking about an event when a block is broken but I wonder what is the best method to destroy a tool without those annoying effects mentioned by EverythingGames.

Link to comment
Share on other sites

I don't know if you want to do this using events only, but i just tested this on 1.8 and it worked:

 

 

public class testitem extends Item {

 

public testitem(){

this.setMaxDamage(1);

this.setMaxStackSize(1);

}

 

 

@Override

public boolean onBlockDestroyed(ItemStack stack, World worldIn, Block blockIn, BlockPos pos, EntityLivingBase playerIn) {

 

if(playerIn.getHeldItem().getItem() != null && playerIn.getHeldItem() == stack){

stack.damageItem(2, playerIn);

}

 

return super.onBlockDestroyed(stack, worldIn, blockIn, pos, playerIn);

}

 

@Override

public boolean onItemUse(ItemStack stack, EntityPlayer playerIn, World worldIn, BlockPos pos, EnumFacing side,

float hitX, float hitY, float hitZ) {

 

if(playerIn.getHeldItem().getItem() != null && playerIn.getHeldItem() == stack){

stack.damageItem(2, playerIn);

}

 

return super.onItemUse(stack, playerIn, worldIn, pos, side, hitX, hitY, hitZ);

}

 

}

 

Link to comment
Share on other sites

I thought I had solved the problem but the OnCrafting event doesn't seem to be always called...

Ah yes... It is called if one uses drag-drop to pull an item off a result slot and drop it in an inventory slot. If one instead uses shift-click to teleport the item-stack, then the event gets bypassed (or it did last time I checked). I don't know if that's a Forge bug or a Minecraft "feature", but it has affected some of my mods' achievements enough to warrant comments in their descriptions at CurseForge.

 

Try overriding Item.getDamage() to lie about how damaged the item is. If maxDamage is 1, then always return 2. That'll always put the amount of damage above max, destroying the item when checked (which is after hitting/breaking something). Then not even an unbreak enchantment will save it.

 

 

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

This :

	@SubscribeEvent
public void breakWoodenPickaxe(BreakEvent event) {
	if ((event.getPlayer().getHeldItem() != null) && (event.getPlayer().getHeldItem().getItem() == Items.wooden_pickaxe)) {
		event.getPlayer().getHeldItem()
				.damageItem(Integer.MAX_VALUE, event.getPlayer());
	}
}

 

Seems to work well, I have yet to find the problems with this method. Well, I have a problem, the particle&sound are not displayed when I break the tool now, but I don't think it's related. I have to check.

EDIT : It is related. The item disappear, but no sound and effect can be seen. WTF ?

Link to comment
Share on other sites

Even when I manually light up the sound, it's not triggered. Try for yourself, with any tool.

I see absolutely no link between damaging an item and preventing all sounds and particles to be displayed.

I am looking for an event solution to allow using it on Vanilla or other mods tools.

Link to comment
Share on other sites

Try my idea to override Item.getDamage() in your single-use item or tool class and let us know what happens.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

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



×
×
  • Create New...

Important Information

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