Jump to content

Recommended Posts

Posted

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?

HammerBase.java

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();
    }

    @Override
    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;
                    break;
                case "north":
                case "south":
                    xIn = currentTier;
                    yIn = currentTier;
                    zIn = 1;
                    break;
                case "east":
                case "west":
                    xIn = 1;
                    yIn = currentTier;
                    zIn = currentTier;
                    break;
                default:
                    SimplyObunga.LOGGER.error("No such facing index");
                    break;
            }
        }
    }

    @Override
    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_) -> {
                p_220038_0_.sendBreakAnimation(EquipmentSlotType.MAINHAND);
            });
            BlockRayTraceResult targetBlock = getTargetBlock(entityLiving, worldIn);
            Direction blockFace = targetBlock.getFace();
            setXYZ(blockFace);

            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);
                            if(this.canHarvestBlock(maybeBreakIt))
                                worldIn.destroyBlock(globalCords, true);
                        }
                    }
                }
            }


        }
        return true;
    }

    @Override
    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);
    }
}

 

EventKeyInputs.java

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 {

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

 

Posted (edited)

Use nbt tags or capability to store data in itemstacks instead otherwise every hammer (item) will share the same data stored because there's only "one item" but multiple itemstacks.

Edited by poopoodice
Posted
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.

Posted

Howdy

 

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.

 

-TGG

 

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

https://www.baeldung.com/java-decorator-pattern

https://www.geeksforgeeks.org/decorator-pattern/?ref=lbp

 

 

  • Like 2

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.