#Itemstack won't take damage when conditions are met (Solved)

75 messages · Page 1 of 1 (latest)

pulsar socket
#

I'm trying to add climbing claws that'll take durability while you climb and my item won't take durability when I have this conditions set but everything else works

   public void inventoryTick(ItemStack stack, World world, Entity entity, int slot, boolean selected) {
       if (!stack.isOf(ModTools.CLIMBING_CLAW) || !selected) {return;}

       if (entity instanceof LivingEntity livingentity) {
           if (startPos == null) {startPos = livingentity.getBlockPos();}

           HitResult hit = entity.raycast(1,0,false);
           stack.set(ModComponents.CAN_CLIMB_ON_BLOCK,CanClimb(hit,livingentity));

           BlockPos currentpos = livingentity.getBlockPos();

           boolean didYChange = startPos.getY() != currentpos.getY();

           if (livingentity.horizontalCollision && !livingentity.getBlockStateAtPos().isIn(BlockTags.CLIMBABLE)) {
               System.out.println("HELP ME");
               stack.damage(1,livingentity,EquipmentSlot.MAINHAND);
               startPos = null;
           }
       }
   }```
ruby spoke
#

So "HELP ME" is printed, but the stack isn't damaged?

pulsar socket
#

yes

hollow dove
#

If it's convenient at the moment, try throwing in System.out.println(stack.isDamageable()); just before you try to damage it, and let me know what it says

#

I suspect the problem is that the item isn't damageable. If so, it would be useful to see other parts of your code.

pulsar socket
#

it should be, when I set it outside of any if statements it damages itself

            "climbing_claw",
            new ClimbingClawItem(new Item.Settings().maxDamage(250).component(ModComponents.CAN_CLIMB_ON_BLOCK,false))
    );```
hollow dove
#

Huh, okay.

pulsar socket
#

when I check if the entity is climbing it works but specifically on ladders and not on every block
and my guess is related to the mixin I made that lets you climb on any block if you use the item

Climb Claw Class

    @Override
    public void inventoryTick(ItemStack stack, World world, Entity entity, int slot, boolean selected) {
        if (!stack.isOf(ModTools.CLIMBING_CLAW) || !selected) {return;}

        if (entity instanceof LivingEntity livingentity) {
            HitResult hit = entity.raycast(1,0,false);
            stack.set(ModComponents.CAN_CLIMB_ON_BLOCK,CanClimb(hit,livingentity));
            
            if (livingentity.isClimbing()) {
                System.out.println("HELP ME");
                stack.damage(1,livingentity,EquipmentSlot.MAINHAND);
            }
        }
    }```

Living Entity Mixin
   ```@Inject(
            method = "Lnet/minecraft/entity/LivingEntity;isClimbing()Z",
            at = @At("TAIL"),
            cancellable = true)
    public void ClimbClawFunctionalityBunnycraft(CallbackInfoReturnable<Boolean> cir) {
        BlockPos blockPos = entity.getBlockPos();

        if ((this.hasOneOrBothClaws() && entity.horizontalCollision && !this.onClimbableBlock())) {
            if (this.CanClimb()) {
               entity.climbingPos = Optional.of(blockPos);
               cir.setReturnValue(true);
           }
        }
    }```
hollow dove
#

Where do onClimableBlock() and CanClimb() come from?

#

(and apparently I don't know how to do discord text formatting properly lol)

pulsar socket
#
    public boolean hasClimbingClaw() {
        return (entity.getMainHandStack().isOf(ModTools.CLIMBING_CLAW)
                || entity.getOffHandStack().isOf(ModTools.CLIMBING_CLAW))
                && !this.hasBothClimbingClaws();
    }```

 ``` @Unique
    public boolean hasBothClimbingClaws() {
        return entity.getMainHandStack().isOf(ModTools.CLIMBING_CLAW) && entity.getOffHandStack().isOf(ModTools.CLIMBING_CLAW);
    }```

    ```@Unique
    public boolean hasOneOrBothClaws() {
        return this.hasClimbingClaw() || this.hasBothClimbingClaws();
    }```

    ```@Unique
    public boolean isStackClimbingClawThatClimbs(Hand hand) {
        ItemStack stack = entity.getStackInHand(hand);
        return stack.isOf(ModTools.CLIMBING_CLAW) && Boolean.TRUE.equals(stack.get(ModComponents.CAN_CLIMB_ON_BLOCK));
}```

    ```@Unique
    public boolean CanClimb() {
        if (!this.hasOneOrBothClaws()) {return false;}

        // probably messy so we may change this later
        boolean or = isStackClimbingClawThatClimbs(Hand.MAIN_HAND) || isStackClimbingClawThatClimbs(Hand.OFF_HAND);
        boolean and = isStackClimbingClawThatClimbs(Hand.MAIN_HAND) && isStackClimbingClawThatClimbs(Hand.OFF_HAND);

        return or || and;
    }```
```@Unique
    public boolean onClimbableBlock() {
        return entity.getBlockStateAtPos().isIn(BlockTags.CLIMBABLE);
    }```
#

sorry let me fix the format

hollow dove
#

Does getBlockStateAtPos() return the blockstate at the players feet? And if so, wouldn't that usually be air?

pulsar socket
#

yes, I check if the player collides with a block and it lets me go up, I also check if the player is looking at a block so they can't just fly off

#

in the climb claw itself

hollow dove
#

So just checking, you can climb any block with the claw equipped, and that works, but the isClimbing method only returns true for normally climbable blocks?

pulsar socket
#

yes

hollow dove
#

Still, I wouldn't have thought that would be the problem with the damaging thing, because the print statement works.

pulsar socket
#

I did change the if statement so let me check if it still does

#

wait nvm sorry 😭

#

it basically just acts like how it does without the mixin

#

so it just damages only on climbable blocks like ladders

hollow dove
#

Okay, well, that's probably easier to figure out the problem anyway

pulsar socket
#

just checked again and it only damages the item on climbable blocks but it prints on both

hollow dove
#

Weird. If it damages on climbable blocks, then the damage line must work, but if the damage line works, then it should still work any time the print statement is called.

pulsar socket
#

yeah it's weird

#

let me check again though

hollow dove
#

Does "HELP ME" print exactly once in every case? Or does it print twice simultaneously sometimes?

pulsar socket
#

let me try printing with the actual statement

#

cause I think it did earlier and while that happened it was printing true and false

#

and it only prints true when I'm on the ladder

hollow dove
#

Might be a server/client thing. Try adding if (world.isClient()) { System.out.println("client"); } else { System.out.println("server"); } just before the damage call to check where it is running

pulsar socket
#

ooh yeah

#

it prints both

#

though it seems to be printing false after the server print and true on the client let me check with it in one line

hollow dove
#

Damaging the stack happens server side, so the isClimbing method not working on the server would explain it. Which narrows the search area.

pulsar socket
#

yeah seems like it

#

I appreciate the help btw 🙏

hollow dove
#

Also, regarding this section:```@Unique
public boolean CanClimb() {
if (!this.hasOneOrBothClaws()) {return false;}

    // probably messy so we may change this later
    boolean or = isStackClimbingClawThatClimbs(Hand.MAIN_HAND) || isStackClimbingClawThatClimbs(Hand.OFF_HAND);
    boolean and = isStackClimbingClawThatClimbs(Hand.MAIN_HAND) && isStackClimbingClawThatClimbs(Hand.OFF_HAND);

    return or || and;
}``` the ``and`` boolean should be unnecesary since ``||`` (or) will return true if one or both is true by default.
#

but that shouldn't be causing problems

pulsar socket
#

oh that makes sense

#

thanks

#

I guess the mixin is just applying on the client?

hollow dove
#

Can I see your mixins.json file?

hollow dove
pulsar socket
#
  "required": true,
  "package": "net.bunnycraft.mixin",
  "compatibilityLevel": "JAVA_21",
  "mixins": [
    "block.BrushableBlockDropXP",
    "block.DispenserUsesMoreShears",
    "block.VaultBlockRewinderUse",
    "entity.ChickenLayLootTableMixin",
    "entity.DealmakerLoseDurabilityOnTrade",
    "entity.DealmakerVillagerInteraction",
    "entity.LivingEntityMixin",
    "entity.PlayerEntityMixin",
    "entity.ShearableZombieMixin",
    "entity.SheepShearsTypeMixin",
    "entity.TurtleBrushingMixin",
    "entity.VaultRewinderBlockEntity",
    "item.CauldronAlloyerMixin",
    "item.HoeItemMixin",
    "item.PickaxeItemMixin",
    "item.ShearsBecomeSwordMixin",
    "item.ShovelItemMixin",
    "item.attribute.ArmorAttributesMixin",
    "item.attribute.ItemAttributesMixin"
  ],
  "injectors": {
    "defaultRequire": 1
  },
  "client": [
    "item.ItemRendererMixin",
    "item.ModelLoaderMixin"
  ]
}```
hollow dove
#

Looks fine.

#

Where does entity in hasClimbingClaw and hasBothClimbingClaws come from?

#

Also are they in the LivingEntityMixin?

pulsar socket
#

yes

#

all of the booleans should be in living entity mixin

hollow dove
#

Because it may also be one of the methods used doesn't work properly on the client for some reason

pulsar socket
#

it seems to print both

#

I put it in the wrong place let me check again

#

okay it only prints on the client

#

I guess it might be one of my checks ?

hollow dove
hollow dove
#

You said it printed both, but in the wrong place, and only printed client in the right place. Where were those places?

pulsar socket
#

ohh let me show you

#

sorry

hollow dove
#

It's alr, that wasn't the clearest message from me

pulsar socket
#
            method = "Lnet/minecraft/entity/LivingEntity;isClimbing()Z",
            at = @At("TAIL"))
    public boolean ClimbClawFunctionalityBunnycraft(boolean original) {
        BlockPos blockPos = entity.getBlockPos();

        if ((this.hasOneOrBothClaws() && entity.horizontalCollision && !this.onClimbableBlock())) {
            if (this.CanClimb()) 
            {
                if (entity.getWorld().isClient) {
                    System.out.println("Client");
                } else {
                    System.out.println("Server");
                }
                entity.climbingPos = Optional.of(blockPos);
                return true;
            }
        }
        return original;
    }``` only prints client

``` @ModifyReturnValue(
            method = "Lnet/minecraft/entity/LivingEntity;isClimbing()Z",
            at = @At("TAIL"))
    public boolean ClimbClawFunctionalityBunnycraft(boolean original) {
        BlockPos blockPos = entity.getBlockPos();

        if (entity.getWorld().isClient) {
            System.out.println("Client");
        } else {
            System.out.println("Server");
        }

        if ((this.hasOneOrBothClaws() && entity.horizontalCollision && !this.onClimbableBlock())) {
            if (this.CanClimb())
            {
                entity.climbingPos = Optional.of(blockPos);
                return true;
            }
        }
        return original;
    }``` prints server and client
hollow dove
#

That's useful, looks like one of these three only returns the correct result on the client: if ((this.hasOneOrBothClaws() && entity.horizontalCollision && !this.onClimbableBlock()))

pulsar socket
#

I just removed that statement and it works fine

#

I think it helps that I added checking if the item can climb when you're looking at a block

hollow dove
#

Can you clarify 'works fine'? as in does the damage happen only when you want it to, or also happens under circumstances where you don't want it to?

pulsar socket
#

the damage happens only when I want it to

hollow dove
#

So problem solved?

pulsar socket
#

yes

#

thank you so much 🙏

hollow dove
#

Nice

#

You're welcome