CecerMCProjects / NoChangeTheGame

A Fabric based Minecraft modification for modern versions that reverts behaviour changes since Minecraft 1.8.9 that are often disliked by PVP players. Intended for use on Hypixel only.
https://www.cecer1.com/projects/nochangethegame/
MIT License
11 stars 2 forks source link

(Feature) Don't swing hand on item drop, interaction #5

Open Yedelo opened 6 months ago

Cecer commented 6 months ago

By interaction I assume you mean with things like villagers?

Yedelo commented 6 months ago

Things like using eggs, snowballs, potions, ender pearls, experience bottles. Most of the swing methods are in the startUseItem method (Minecraft class) and shouldSwing in InteractionResult could be more simple

Cecer commented 6 months ago

That sounds reasonable. I'll try and find some time to add this soon.

(I was wondering as opening the villager trading UI in old versions didn't swing in the distant past either interestingly)

Cecer commented 5 months ago

Can you confirm this functions how you are expecting please @Yedelo? https://github.com/CecerMCProjects/NoChangeTheGame/releases/tag/v.1.1.0-rc2

Yedelo commented 4 months ago

Sorry for the late response. Cancelling swings on item drops seems to work fine, but cancelling swings on item use doesnt work as intended. Using any items cancels the swing, not just items that I mentioned above. Also, cancelling these swings doesnt send the swing packet, which I haven't tested on hypixel but would definitely get you banned for item uses.

Here's some code I made for cancelling all swings, for a seperate mod I made:

@Mixin(LivingEntity.class)
public abstract class MixinLivingEntity { 
    // this is the super method that ClientPlayerEntity calls, packet is always sent after
    @Inject(method = "swingHand(Lnet/minecraft/util/Hand;Z)V", at = @At("HEAD"), cancellable = true)
    public void onSwingHand(Hand hand, boolean fromServerPlayer, CallbackInfo ci) {
        // swing of any entity
        if ((LivingEntity) (Object) this instanceof PlayerEntity) {
            // its a player, not any entity
            if ((Object) this instanceof ClientPlayerEntity) {
                // its the client player
                // item logic here
            }
        }
    }
}

Lastly, when cancelling swings the item still bobs up and down. Injecting into HeldItemRenderer.applyEquipOffset (variable equipProgress) can change the position of the item

Cecer commented 4 months ago

Here are my test cases. Can you think of any other situations that are different?

Throw Snowball:
    Against Block:
        1.8.9:  Bob
        1.20.6: Swing
        NCTG:   Bob
    Against Air:
        1.8.9:  Bob (None in creative)
        1.20.6: Swing
        NCTG:   Bob

Cast Rod:
    Against Block:
        1.8.9:  Swing
        1.20.6: Swing
        NCTG:   Bob [!]
    Against Air:
        1.8.9:  Swing
        1.20.6: Swing
        NCTG:   Bob [!]

Open Door:
    1.8.9:  Swing
    1.20.6: Swing
    NCTG:   None [!]

You're certainly correct that there are some issues with the current implementation. I'll try to go over it this week.

Yedelo commented 4 months ago

All of the swing cases i can think about:

Cecer commented 4 months ago

Having looked into it, I'm not sure how feasible this is without side effects.

Example: By preventing the swing from dropping an item, it means something else can swing sooner than it otherwise would. This means we either cancel the drop swing entirely (including the packet) or we risk sending swings faster than should be normally possible.

One solution to this would be to duplicate all the swing tracking stuff. One for visuals and one for restrictions. Hidden swings would only update the restrictions. This is doable but feels a little convoluted so I would prefer some discussion on this first as you seem to have have some experience in these things.

I don't suppose you have a better solution without side effects do you?

Yedelo commented 4 months ago

I also thought about swing tracking for my own mod but I don't think its possible.

private void renderArmHoldingItem(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, float equipProgress, float swingProgress, Arm arm) {

This, along with other methods in HeldItemRenderer, has an equipProgress and swingProgress variable. These could be changed in a mixin. One solution could be to use a tick counter, which could be decremented every tick and set to an amount when swinging. In the mixin, swingProgress could be set to 0 (or whatever it needs to be) if the tick counter is > 0.

Sending swings faster shouldn't be an issue. At least in 1.8, every swing sends an animation packet, whether it makes the sword actually swing or not. If this is the same in 1.20, the packets should be the same. Also, interactions (with entities and blocks) are done before the swingItem method.

Cecer commented 4 months ago

I'm pretty sure there are sometimes different anti-cheat checks for different versions so we have to be careful using 1.8 details blindly. I'd need to look at the code to verify that it is the same in 1.21. If it does then I'll try and find some time to at very least get a proof of concept system for separating the visuals and the packets.