Koward Posted October 31, 2015 Posted October 31, 2015 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. Quote
knokko Posted October 31, 2015 Posted October 31, 2015 There are several methods in the Item class, override one of the methods and destroy your item. Quote
jeffryfisher Posted October 31, 2015 Posted October 31, 2015 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. Quote 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.
plr123 Posted October 31, 2015 Posted October 31, 2015 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 Quote
Koward Posted October 31, 2015 Author Posted October 31, 2015 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. Quote
EverythingGames Posted November 1, 2015 Posted November 1, 2015 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); Quote Development of Plugins [2012 - 2014] Development of Mods [2012 - Current]
EverythingGames Posted November 1, 2015 Posted November 1, 2015 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. Quote Development of Plugins [2012 - 2014] Development of Mods [2012 - Current]
Koward Posted November 12, 2015 Author Posted November 12, 2015 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. Quote
Earthcomputer Posted November 12, 2015 Posted November 12, 2015 Override methods such as hitEntity and onBlockDestroyed. To destroy the item, use stack.damageItem(Integer. MAX_VALUE, attacker) Quote catch(Exception e) { } Yay, Pokémon exception handling, gotta catch 'em all (and then do nothing with 'em).
Cerandior Posted November 12, 2015 Posted November 12, 2015 What do you mean with can be used once. It can destroy only one block and then it will be destroyed? Or you can right click with the item once and then it will be destroyed. Quote
Cerandior Posted November 12, 2015 Posted November 12, 2015 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); } } Quote
jeffryfisher Posted November 12, 2015 Posted November 12, 2015 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. Quote 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.
Koward Posted November 12, 2015 Author Posted November 12, 2015 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 ? Quote
Koward Posted November 13, 2015 Author Posted November 13, 2015 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. Quote
jeffryfisher Posted November 13, 2015 Posted November 13, 2015 Try my idea to override Item.getDamage() in your single-use item or tool class and let us know what happens. Quote 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.
Recommended Posts
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.