Jump to content

[Solved] [1.7.2] Preventing Players Harvesting Blocks With Their Fists


qpwoeiruty

Recommended Posts

I am trying to create a mod that makes the game more challenging, and so I would like to be able to remove the feature in vanilla Minecraft that allows the player to harvest wood through the power of their fist. However, I am not entirely sure how this would be possible as everywhere I looks seems to lead me back to changing the harvest level of the vanilla blocks, but this doesn't seem to do anything or I cannot get it working correctly. So I am wondering if anyone knew how this could be done, or could link me to any useful sources. If so this would be highly appreciated, thanks.

Link to comment
Share on other sites

Use the PlayerEvent.BreakSpeed event and cancled it or set the newSpeed to -1.

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/

Link to comment
Share on other sites

Firstly, thanks for the fast reply, but I am quite new to modding and events seem to be something I cannot get my head round. Could you show me how I would go about this as I have tried some events before and couldn't get them working. Sorry if this is really simple, I just have a poor understanding of events.

Link to comment
Share on other sites

First,you need to make a class and register that in the MinecraftForge.EVENT_BUS. Then you need to make a method, eg. setBreakSpeed and put the PlayerEvent.BreakSpeed in that as a parameter. After that, put the @SubscribeEvent annotation above the method. In that method you can set the newSpeed of the event and that's it! If you need more help, post your code so we can help.

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/

Link to comment
Share on other sites

Wow, thanks again for another quick reply, I will try that out now...

 

Well that was certainly one step in the right direction something is actually happening; the player can no longer break any blocks. However, they can't break any blocks with tools either which is not exactly what I wanted. Considering I entered one line of code inside my method I'm sure there is a way around this.

 

  @SubscribeEvent

public void setBreakSpeed(PlayerEvent.BreakSpeed event) {

 

event.setCanceled(true);

 

}

Link to comment
Share on other sites

In the event (or actually the parent class, which is PlayerEvent), you also get a EntityPlayer object, so you can use that to check if entityPlayer.getCurrentEquippedItem() is null and then cancel the event.

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/

Link to comment
Share on other sites

Alright will do thanks...

 

I am using this and don't really understand whats wrong with it:

private boolean objectInHand = true;

@SubscribeEvent
public void objectInHand(EntityPlayer event) {

	if(event.getCurrentEquippedItem() != null) {

		objectInHand = false;

	}

}

@SubscribeEvent
public void setBreakSpeed(PlayerEvent.BreakSpeed event) {

	if(objectInHand = false) {

		event.setCanceled(true);

	} else {

		event.setCanceled(false);

	}

}

Link to comment
Share on other sites

In the PlayerEvent.BreakSpeed you are given an entityPlayer object. You can use that to get the current item instead of the other @SubscribeEvent (EntityPlayer is not even an event). For your purpose you can use event.entityPlayer.getCurrentEquippedItem == null.

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/

Link to comment
Share on other sites

Now the problem arises that they can't break blocks when they nothing in their hand but they can say if they had a dirt block. So would I have to specify which blocks can be used with which tools? As in if the block they are mining equals stone and if they have a diamond pickaxe, allow them to break it.

Link to comment
Share on other sites

You can use the ForgeHooks.isToolEffective method to check if the tool is effective for that block, and if it is, don't cancel it, but if it isn't, then cancel it.

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/

Link to comment
Share on other sites

Ok, the first parameter, stack, is the stack the player is currently using for mining the block. the second parameter, block is the block being broken, you get that passed in via the event, and the same goes for metadate, you get that passed in via the event.

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/

Link to comment
Share on other sites

No, you need to do it this way:

if(!ForgeHoos.isToolEffective(event.entityPlayer.getCurrentEquippedItem(),event.block,event.metadata))
{
     event.setCanceled(true);
}

Please don't copy paste, but try to figure out what i did, so you can learn from it.

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/

Link to comment
Share on other sites

Look at what i did, i added a not sign (the thingy on the same key as the number, forget how to call it in english), before the ForgeHook.isToolEffective() call so if the was NOT effective, it would cancel it.

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/

Link to comment
Share on other sites

Hahaha yeah, both are working, but I am now getting a crash when I try and break a block with my fist but everything else works great. I believe it may have something to do with this error...

 

FML has detected a mod that is using a package name based on 'net.minecraft.src' : net.minecraft.src.FMLRenderAccessLibrary. This is generally a severe programming error.  There should be no mod code in the minecraft namespace. MOVE YOUR MOD! If you're in eclipse, select your source code and 'refactor' it into a new package. Go on. DO IT NOW!

 

...which sounds fairly bad, however I don't believe I am using a package based on 'net.minecraft.src' so I am confused.

 

Edit: Actually I don't think it does as when I remover the MinecraftForge.EVENT_BUS.register(new WSPEventHandler()); everything works fine, so I now I believe it is something to do with this line:

 

if(ForgeHooks.isToolEffective(event.entityPlayer.getCurrentEquippedItem(), event.block, event.metadata)) {

 

Its within this class:

 

package com.willr27survivalplus.handler;

 

import net.minecraft.block.Block;

import net.minecraft.entity.player.EntityPlayer;

import net.minecraft.init.Blocks;

import net.minecraft.init.Items;

import net.minecraft.item.ItemStack;

import net.minecraftforge.common.ForgeHooks;

import net.minecraftforge.event.entity.player.PlayerEvent;

import net.minecraftforge.event.world.BlockEvent;

import cpw.mods.fml.common.eventhandler.SubscribeEvent;

 

public class WSPEventHandler {

 

@SubscribeEvent

public void setBreakSpeed(PlayerEvent.BreakSpeed event) {

 

if(ForgeHooks.isToolEffective(event.entityPlayer.getCurrentEquippedItem(), event.block, event.metadata)) {

 

event.setCanceled(true);

 

} else {

 

event.setCanceled(false);

 

}

 

}

 

}

 

Link to comment
Share on other sites

 

FYI, what I do when I get an error like this:

 

java.lang.NullPointerException: Unexpected error
at net.minecraftforge.common.ForgeHooks.isToolEffective(ForgeHooks.java:131)

Looking at ForgeHooks.java:131

    public static boolean isToolEffective(ItemStack stack, Block block, int metadata)
    {
        List toolClass = toolClasses.get(stack.getItem());          // NPE here
        return toolClass != null && toolEffectiveness.contains(Arrays.asList(block, metadata, toolClass.get(0)));
    }

 

Not sure what a NullPointerException is? 

Google ->

http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it

 

So that means that I am using an object which is null.  There are only two on this line - stack and toolClasses.  Since stack is being provided by my code when it calls this method, it's a good guess that stack is null.

Why is it null?

It was called at com.willr27survivalplus.handler.WSPEventHandler.setBreakSpeed(WSPEventHandler.java:18)

      if(ForgeHooks.isToolEffective(event.entityPlayer.getCurrentEquippedItem(), event.block, event.metadata)) {

and that means that

event.entityPlayer.getCurrentEquippedItem()

returned null.

 

Why did it return null?  Well the name is a strong clue, because the crash only happens when you're not holding anything.

 

-TGG

 

 

Link to comment
Share on other sites

Thanks for the very detailed explanation, I understand far better what a NullPointerException is now, however, how to fix it is still quite confusing as I am trying to take in a lot of new information at once. Would have to somewhere say that getCurrentEquippedItem() != null then, or have I misunderstood?

Link to comment
Share on other sites

Basically what that means is you can't use the isToolEffective method when the player is not holding anything, because it expects an ItemStack, not a null pointer; so, if the player is not holding anything, or the currently held item is not effective against the current block, then cancel the event.

 

Translating the above statement into pseudocode:

if (currentItem == null || isToolEffective(currentItem, etc.)) { cancelEvent; }

Link to comment
Share on other sites

I can't thank you all enough, this has been bugging me for a while and to finally get to a stage where the basics actually work is fantastic. Is there a simpler way than listing every single block to only have select blocks able to be broken, as I could just list every block but it would be very inefficient.

 

Edit: This does work (just listing all the blocks I want) so it is technically solved but anyone with any better ideas feel free to post them.

 

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

    • 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.
    • In 1.20.6 any potion brewed in the brewing stand disappears upon completion.
    • My game crashes whenever I click on Singleplayer then it crashes after the "Saving world". I'm playing on fabric 1.20.1 on forge for the easy instance loading. My game is using 12GB of RAM, I tried deleting the options.txt, and also renaming the saves file but neither worked. Here's the crash report link: https://mclo.gs/qByOqVK
  • Topics

×
×
  • Create New...

Important Information

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