The cause of this issue lies in how the `block_experience` component is checked. The component is only checked on the main hand item (the tool) of the breaking player. The OP is attempting to make a Helmet Enchantment containing this component, which means it will never be accessed by the enchantment logic.
The entrypoint for enchantment-modified experience is Block#tryDropExperience, which only retains the context of the tool that was used to break the block. To allow this component to work on items other than the tool, this function will need to accept the Entity who broke the block,
The components `ammo_use` and `projectile_piercing` share the same issue (only being applicable on the used bow instead of all gear slots).
Technically `repair_with_xp` and `item_damage` also share the same behavior, but I believe those two are working-as-intended, since those components should not impact other items.
Confirmed to still exist in 1.20.5-pre1. This issue can be fixed by changing the following code in LivingEntity#updateUsingItem
if(--this.useItemRemaining== 0&& !this.level().isClientSide&& !p_147201_.useOnRelease()) {
this.completeUsingItem();
}
to
if(--this.useItemRemaining<= 0&& !this.level().isClientSide&& !p_147201_.useOnRelease()) {
this.completeUsingItem();
}
The change is switching out `==` for `<=`, which fixes completeUsingItem() not being called for items with a use duration of 0.
Guess if this is being closed as WAI then we should go open another issue against the "stepping down is actually a fall and not a step down"
@Misode No. From years of this attribute existing in forge, the expected behavior from players is that the step-down height is static (always 0.5). The attribute (step height / maxUpStep) should only control how far up you can go, without causing you to lose the ability to hug a block via sneaking.
See https://github.com/SlimeKnights/TinkersConstruct/issues/4956 (first instance of a player-sourced issue report against this issue) and https://github.com/MinecraftForge/MinecraftForge/pull/8927 (the fix implemented to forge, noting that forge's attribute does not change the value of maxUpStep() )
Depending on the desired implementation, either this or MC-172289 should be marked as a duplicate of the other, or one should be closed as WAI - the fix for the two is the same since no other checks in the game discriminate between placeable non-mobs and mobs, only between entities and blocks for reach checks. See my comment on the other issue about that.
The code responsible for truncating entity reach to 3.0 is in GameRenderer#pick(), where the check if (flag && d2 > 9.0D) discards the entity pick result if the entity is further than 3 blocks away. This is despite the fact that the actual entity pick (via ProjectileUtil.getEntityHitResult) is done with a distance equal to the pick range, which is higher than 3.0.
Even if this line is fixed, there will be other issues with large entities, since the serverside validation checks perform bottom center-to-center distance checks, instead of eye-to-closest-corner. But for the scope of vanilla, bottom center-to-center works, since there are no large entities.
This issue can be fixed with a one line change in GameRenderer#pick
The check if (this.minecraft.hitResult != null) needs to be updated to if (this.minecraft.hitResult != null && this.minecraft.hitResult.getType() != HitResult.Type.MISS) so that it does not cap the distance when the block pick fails.
We have adopted a client-side fix in NeoForge for this bug here, by recording the BlockEntity before the break and restoring it in BlockStatePredidtionHandler#endPredictionsUpTo if the server notifies the client that the break was cancelled. An alternative fix to this problem would be to make the client respect ClientboundBlockUpdatePacket(s) immediately instead of storing them until endPredictionsUpTo, and sending the BE data from Server to client when the break is cancelled.