Dandan642 Posted June 12, 2020 Posted June 12, 2020 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"); } } } Quote
poopoodice Posted June 12, 2020 Posted June 12, 2020 (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 June 12, 2020 by poopoodice Quote
Dandan642 Posted June 12, 2020 Author Posted June 12, 2020 Any examples or documentation you can point me too? I'm not familiar with those concepts yet. Quote
poopoodice Posted June 12, 2020 Posted June 12, 2020 Capability nbt tag compound: use stack.getTag() to get the existing tag of the itemstack, .putBoolean, putInt..etc to store data .getBoolean, getInt... etc to get stored data from the nbt tag Quote
Dandan642 Posted June 12, 2020 Author Posted June 12, 2020 And where would I use that? In the HammerBase constructor? Quote
poopoodice Posted June 12, 2020 Posted June 12, 2020 use it where you want to access/set the data, which option you are using? Quote
Dandan642 Posted June 12, 2020 Author Posted June 12, 2020 Probably NBT data, seems less complicated for a beginner Quote
poopoodice Posted June 12, 2020 Posted June 12, 2020 (edited) use getTag to get tag from the itemstack, and store/get the data from it. Btw in my experience setting stack tag on client does not work. Edited June 12, 2020 by poopoodice Quote
sciwhiz12 Posted June 12, 2020 Posted June 12, 2020 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. Quote
Dandan642 Posted June 12, 2020 Author Posted June 12, 2020 Guess I've got a lot to learn about this Quote
TheGreyGhost Posted June 12, 2020 Posted June 12, 2020 Howdy You might find this working example of nbt storage in items useful https://github.com/TheGreyGhost/MinecraftByExample see mbe12 You could use capabilities, but that is probably unnecessarily complicated for what you want to do, by the sound of it -TGG 1 Quote
poopoodice Posted June 12, 2020 Posted June 12, 2020 10 hours ago, TheGreyGhost said: Howdy You might find this working example of nbt storage in items useful https://github.com/TheGreyGhost/MinecraftByExample see mbe12 You could use capabilities, but that is probably unnecessarily complicated for what you want to do, by the sound of it -TGG Under what condition will you suggest capability than nbt tags? Quote
TheGreyGhost Posted June 13, 2020 Posted June 13, 2020 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 2 Quote
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.