Jump to content

[1.8] Tool that can be used only once.


Koward
 Share

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.
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
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.

 Share



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • I made a huge forge 1.7.10 mod pack but whenever I try to create a singleplayer world I get the error saying "A fatal error has occurred, this connection is terminated." Does anyone know what the issue could be?  Here is my fml-client-latest.log from when it crashes: https://paste.ubuntu.com/p/3rKSJSqnrX/ and here is the list of mods: https://imgur.com/a/AZifMbg    
    • Im trying to host a minecraft server using the curseforge serverpack from FTB Direwolf20 and when I try to start the server I run into an error The Error: Starting server A problem occurred running the Server launcher.java.lang.reflect.InvocationTargetException         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)         at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)         at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)         at java.lang.reflect.Method.invoke(Unknown Source)         at cpw.mods.fml.relauncher.ServerLaunchWrapper.run(ServerLaunchWrapper.java:43)         at cpw.mods.fml.relauncher.ServerLaunchWrapper.main(ServerLaunchWrapper.java:12) Caused by: java.lang.NoClassDefFoundError: org/apache/logging/log4j/Level         at net.minecraft.launchwrapper.Launch.launch(Launch.java:94)         at net.minecraft.launchwrapper.Launch.main(Launch.java:28)         ... 6 more Caused by: java.lang.ClassNotFoundException: org.apache.logging.log4j.Level         at java.net.URLClassLoader$1.run(Unknown Source)         at java.net.URLClassLoader$1.run(Unknown Source)         at java.security.AccessController.doPrivileged(Native Method)         at java.net.URLClassLoader.findClass(Unknown Source)         at java.lang.ClassLoader.loadClass(Unknown Source)         at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)         at java.lang.ClassLoader.loadClass(Unknown Source)         ... 8 more   I'have tried deleting and downloading the newset version of java wich didnt work and now im using an older version which is the 1.7.0_80 Here is what my Server folder looks like: https://ibb.co/jkbfRY7 Here is what the ServerStart.bat file looks like: @if NOT "%FTB_VERBOSE%"=="yes" ( @echo off ) call settings.bat if NOT EXIST minecraft_server.1.7.10.jar ( goto install ) if NOT EXIST libraries\%LAUNCHWRAPPER% ( goto install ) goto skipinstall :install echo running install script! call FTBInstall.bat :skipinstall REM Check if java in path REM TODO: use %JAVACMD% where java > NUL 2>&1 if %ERRORLEVEL% NEQ 0 ( echo No java binary in path. Can't run server, exiting... pause exit /B ) REM Test JVM REM e.g. 32-bit JVM does not have server\jvm.dll library java -server -version > java-test.log 2>&1 if %ERRORLEVEL% NEQ 0 ( echo Detected following JVM error: echo ======================================= more java-test.log echo ======================================= echo JVM test failed. Can't run server, Exiting... pause exit /B ) if not exist eula.txt ( echo Missing eula.txt. Startup will fail and eula.txt will be created echo Make sure to read eula.txt before playing! goto startserver ) find "eula=false" eula.txt 1 > NUL 2>&1 if %ERRORLEVEL% EQU 0 ( echo Make sure to read eula.txt before playing! Exiting. pause exit /B ) del /f /q autostart.stamp > nul 2>1 :startserver echo Starting server java -server -Xms512M -Xmx2048M -XX:PermSize=256M -XX:+UseParNewGC -XX:+CMSIncrementalPacing -XX:+CMSClassUnloadingEnabled -XX:ParallelGCThreads=2 -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10 -jar FTBServer-1.7.10-1558.jar nogui :server_loop if exist autostart.stamp ( del /f /q autostart.stamp > nul 2>1 echo If you want to completely stop the server process now, press Ctrl+C before the time is up! for /l %%i in (5,-1,1) do ( echo Restarting server in %%i choice /t 1 /d y > nul ) echo Starting server now java -server -Xms512M -Xmx2048M -XX:PermSize=256M -XX:+UseParNewGC -XX:+CMSIncrementalPacing -XX:+CMSClassUnloadingEnabled -XX:ParallelGCThreads=2 -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10 -jar FTBServer-1.7.10-1558.jar nogui echo Server process finished goto :server_loop ) echo Exiting... pause  
    • Made a modpack (Well Rounded Blockheads, in case the modlist on curseforge helps) and server to host it, worked fine until last night. The issue that pops up after some days being up/working is when you leave a world (singleplayer) or shutdown a server, the process hangs and jumps to 8.5gb ram used, eats up CPU usage (50-60% in taskman on a 3800x) and just sits there. If done on a single player world, the game doesnt fully crash, (e.g. if you alt+f4 buttons like save and quit, options stay in the window, are still clickable but they do nothing) Saving seems to still happen, as location/inventory updates if I restart server or client and play the world again.   If I start the currently afflicted server but dont login the server closes properly, its only once I log back in the problem occurs. Its a priv server and I dont have anyone else to test atm so Idk if its a prob with my player or players/area in general. Only recent changes in game are the additions of a pnuematicraft pressure chamber, an enchanting table, and bookshelves from builders crafts and additions.... I've been trying to get help on this all day, so ANY assistance goes a long way, even if its a way to debug this myself >~< Debug/Latest logs
    • Thanks warjort. I was afraid, that this is because they are entities. Now I know where to dig. But what about water, for example? I have checked via debug code, that there is no entity there (appropriate method return null). What is wrong with liquids?
  • Topics

×
×
  • Create New...

Important Information

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