Jump to content

[1.15.2] Changing variable value for single instance of item


Recommended Posts

Hello, I'm very new to modding and pretty new to java so if my code is stupid, forgive me. 

I have created a HammerBase class for a hammer type tool. Currently I am able to call the setCurrentTier method in HammerBase from an keyboard input event handling class. The problem is, the way I get a hammer instance chances the value of any hammer of said resourceName. How might I change the value for only the hammer in the players hand?


package com.dolecki.simplyobunga.items;

import com.dolecki.simplyobunga.SimplyObunga;
import com.dolecki.simplyobunga.util.KeyHandler;
import net.minecraft.block.BlockState;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.PickaxeItem;
import net.minecraft.util.Direction;
import net.minecraft.util.math.*;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;

import javax.annotation.Nullable;
import java.util.List;

public class HammerBase extends PickaxeItem {
    private String toolTipIn;
    private int currentTier;
    private int maxTier;
    private int xIn;
    private int yIn;
    private int zIn;

    public HammerBase(ToolTier tier, int attackDamageIn, float attackSpeedIn, String toolTip) {
        super(tier, attackDamageIn, attackSpeedIn - 4, new Item.Properties().group(SimplyObunga.TAB_MAIN));
        this.toolTipIn = toolTip;
        this.currentTier = 1;
        this.maxTier = tier.getMaxTier();

    public void addInformation(ItemStack stack, @Nullable World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) {
        KeyHandler.addToolTip(tooltip, toolTipIn);
        super.addInformation(stack, worldIn, tooltip, flagIn);

    public void setCurrentTier(String direction) {
        if(currentTier <= maxTier && currentTier >= 0) {
            if(direction.equals("up")) {
                if(currentTier != maxTier)
                    this.currentTier += 1;
                SimplyObunga.LOGGER.info("Inc +1. Current tier: " + currentTier);
            if(direction.equals("down")) {
                if(currentTier != 0)
                    this.currentTier -= 1;
                SimplyObunga.LOGGER.info("Dec -1. Current tier: " + currentTier);

    public void setXYZ(Direction facing) {
        if(currentTier >= 0 && currentTier <= 1) {
            xIn = currentTier;
            yIn = currentTier;
            zIn = currentTier;
        } else {
            switch (facing.getName()) {
                case "down":
                case "up":
                    xIn = currentTier;
                    yIn = 1;
                    zIn = currentTier;
                case "north":
                case "south":
                    xIn = currentTier;
                    yIn = currentTier;
                    zIn = 1;
                case "east":
                case "west":
                    xIn = 1;
                    yIn = currentTier;
                    zIn = currentTier;
                    SimplyObunga.LOGGER.error("No such facing index");

    public boolean onBlockDestroyed(ItemStack stack, World worldIn, BlockState state, BlockPos pos, LivingEntity entityLiving) {
        if (!worldIn.isRemote && state.getBlockHardness(worldIn, pos) != 0.0F) {
            stack.damageItem(1, entityLiving, (p_220038_0_) -> {
            BlockRayTraceResult targetBlock = getTargetBlock(entityLiving, worldIn);
            Direction blockFace = targetBlock.getFace();

            Vec3d blockAxis = new Vec3d(Math.abs(blockFace.getXOffset()), Math.abs(blockFace.getYOffset()), Math.abs(blockFace.getZOffset()));
            Vec3d plane = new Vec3d(xIn, yIn, zIn).subtract(blockAxis);

            BlockPos blockPos = targetBlock.getPos();
            SimplyObunga.LOGGER.info("Primary Block Cord: " + blockPos + "\nBlock face: " + blockFace);
            // Get the donut
            for(int x =(int) -plane.x; x <= (int)plane.x; x++) {
                for (int y = (int) -plane.y; y <= (int) plane.y; y++) {
                    for (int z = (int) -plane.z; z <= (int) plane.z; z++) {
                        if (!(x == 0 && y == 0 && z == 0)) {
                            BlockPos localCords = new BlockPos(x, y, z);
                            SimplyObunga.LOGGER.info("Local Offset: " + localCords);
                            BlockPos globalCords = localCords.add(blockPos);
                            SimplyObunga.LOGGER.info("Global Position: " + globalCords);

                            BlockState maybeBreakIt = worldIn.getBlockState(globalCords);
                                worldIn.destroyBlock(globalCords, true);

        return true;

    public boolean canHarvestBlock(BlockState blockIn) {
        return super.canHarvestBlock(blockIn);

    // Same as Item.RayTraceResult, sort of
    private RayTraceResult rayTrace(World worldIn, LivingEntity player) {
        double rayTraceDistance = player.getAttribute(PlayerEntity.REACH_DISTANCE).getValue(); // Distance of ray trace

        Vec3d eyePos = player.getEyePosition(0F);
        Vec3d look = player.getLook(0F);
        Vec3d rayDistTo = eyePos.add(look.x * rayTraceDistance, look.y * rayTraceDistance, look.z * rayTraceDistance);

        return worldIn.rayTraceBlocks(new RayTraceContext(eyePos, rayDistTo, RayTraceContext.BlockMode.OUTLINE, RayTraceContext.FluidMode.NONE, player));

    private BlockRayTraceResult getTargetBlock(LivingEntity entity, World worldIn) {
        return (BlockRayTraceResult) rayTrace(worldIn, entity);



package com.dolecki.simplyobunga.util.events;

import com.dolecki.simplyobunga.SimplyObunga;

import com.dolecki.simplyobunga.items.HammerBase;
import com.dolecki.simplyobunga.util.KeyHandler;
import com.dolecki.simplyobunga.util.RegistryHandler;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.registries.ForgeRegistries;

@Mod.EventBusSubscriber(modid = SimplyObunga.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE)
public class EventKeyInputs {

    public static void onInput(TickEvent.ClientTickEvent event) {
        HammerBase hammer = (HammerBase) ForgeRegistries.ITEMS.getValue(new ResourceLocation("obunga:silver_hammer"));
        if(KeyHandler.NUM_PAD_7.isPressed()) {
        if(KeyHandler.NUM_PAD_8.isPressed()) {


Link to comment
Share on other sites

8 minutes ago, poopoodice said:

Btw in my experience setting stack tag on client does not work.

A rule of working with applications and networking: never trust the client.

Always perform validation and logic/actions on the server-side, since you never know if a client and the data/packets they send are legitimate or malicious.


Also, when getting the data, check ItemStack#hasTag, because ItemStack#getTag will return null if no tag exists for the client. When putting data, use ItemStack#getOrCreateTag.

Link to comment
Share on other sites

10 hours ago, TheGreyGhost said:



You might find this working example of nbt storage in items useful


see mbe12

You could use capabilities, but that is probably unnecessarily complicated for what you want to do, by the sound of it



Under what condition will you suggest capability than nbt tags?

Link to comment
Share on other sites



I think capability is great for items, entities, etc where

1) you're attaching the same general capability to a variety of different object types or a variety of different capabilities that you're adding to multiple objects ("composition" instead of inheritance/interfaces); or

2) you want vanilla or other mods to be able to interact with your objects in a general way; or

3) you want to attach information to vanilla objects


For example - the capability to store items CapabilityItemHandler.ITEM_HANDLER_CAPABILITY is very useful because other mods and vanilla objects can automatically interact with your object to add or remove items.  You don't need to tell them anything except that your object provides the capability interface.


Or if you wanted to model a radioactive wasteland you could attach a RadiationSickness capability to each entity, including vanilla, to store the amount of radiation damage that has been suffered by each entity.


In contrast, if you're just storing information (in your item) that's of no particular interest to other items, blocks, or entities, then you're probably better off with just "private" NBT information.




If you're interested in general information on the pros and cons of this coding technique, these links might be interesting





  • Like 2
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.

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.


  • Create New...

Important Information

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