transhumandesign / kag-base

King Arthur's Gold base folder.
257 stars 119 forks source link

Problems with knight's cursor animation #2020

Open GELGELAT opened 5 months ago

GELGELAT commented 5 months ago

https://github.com/transhumandesign/kag-base/assets/87004057/7d883fde-38dd-41d8-950a-0942a347d999

In the video, I get stunned and do an insta-slash. Then I keep hitting and the animation breaks. Also with the 2 slash.

mugg91 commented 5 months ago

Are we talking only about the cursor or about the knight as well? If the latter, anyone that looks into it, please check if https://github.com/transhumandesign/kag-base/pull/1839 fixes anything.

GELGELAT commented 5 months ago

Are we talking only about the cursor or about the knight as well? If the latter, anyone that looks into it, please check if #1839 fixes anything.

Well, the cursor is laggy.

mugg91 commented 5 months ago

Why does it look like you are jabbing when you are actually slashing, in your second video? ~I can't reproduce that.~ Nvm, I got it.

It looks like that 1 tick of jabbing shouldn't be there... So it kind of breaks Knight's animation, too?

I can get a "short by 1" cursor when getting attached, and then charging a slash after detaching, though.

GELGELAT commented 5 months ago

Why does it look like you are jabbing when you are actually slashing, in your second video? ~I can't reproduce that.~ Nvm, I got it.

It looks like that 1 tick of jabbing shouldn't be there... So it kind of breaks Knight's animation, too?

I can get a "short by 1" cursor when getting attached, and then charging a slash after detaching, though.

I believe it has to do with the mechanics of insta-slash

mugg91 commented 5 months ago

It takes 15 ticks of "drawing sword" before a slash can be done as dictated by slash_charge = 15; in KnightVars.

I placed

    if (!this.isAttached())
        print(knight.state + " " + knight.swordTimer);

at the beginning of void SwordCursorUpdate(CBlob@ this, KnightInfo@ knight). When doing a slash at the earliest possible time, it will print

0 0 <-- no button press
4 1 <-- "sword_drawn" state
4 2
4 3
4 4
4 5
4 6 
4 7
4 8
4 9
4 10
4 11
4 12
4 13
4 14
4 15
9 0 <-- "sword_power" state
9 1
(...)

For some reason, when

0 0 <-- no button press
4 1 <-- "sword_drawn" state
4 2
4 3
4 4
4 5
4 6 
4 7
4 8
4 9
4 10
4 11
4 12
4 13 <-- it is possible to omit this
4 14 <-- it is possible to omit this
7 0 <-- "sword_cut" state
7 1
9 1 <-- "sword_power" state
9 2
(...)

There is a bug that makes sword_cut state transition into sword_power state. I think the function void SwordCursorUpdate(CBlob@ this, KnightInfo@ knight) itself is behaving properly.

mugg91 commented 5 months ago

Holding action_1, detaching and charging a slash makes knight.swordTimer reach 15 on server, therefore fullfilling the condition to reach the slash state. Whereas it only reaches 13~14 on client, enters cut state at first, but gets overwritten by the "serverKnightstate" code. Interestingly this seems to only happen when keeping holding action_1 out of stun or attachment. It will not be easy to fix this.

mugg91 commented 5 months ago

The problem doesn't happen if this code didn't exist.

    if (isClient())
    {
        if (this.exists("serverKnightState"))
        {
            s32 serverStateIndex = this.get_s32("serverKnightState");
            this.set_s32("serverKnightState", -1);

            if (serverStateIndex != -1 && serverStateIndex != currentStateIndex)
            {
                KnightState@ serverState = states[serverStateIndex];
                u8 net_state = states[serverStateIndex].getStateValue();
                if (this.isMyPlayer())
                {
                    if (net_state >= KnightStates::sword_cut_mid && net_state <= KnightStates::sword_power_super)
                    {
                        if (knight.state != KnightStates::sword_drawn && knight.state != KnightStates::resheathing_cut && knight.state != KnightStates::resheathing_slash)
                        {
                            if ((getGameTime() - serverState.stateEnteredTime) > 20)
                            {
                                knight.state = net_state;
                                serverState.stateEnteredTime = getGameTime();
                                serverState.StateEntered(this, knight, serverState.getStateValue());
                                this.set_s32("currentKnightState", serverStateIndex);
                                currentStateIndex = serverStateIndex;
                            }
                        }
                    }
                }
                else
                {
                    knight.state = net_state;
                    serverState.stateEnteredTime = getGameTime();
                    serverState.StateEntered(this, knight, serverState.getStateValue());
                    this.set_s32("currentKnightState", serverStateIndex);
                    currentStateIndex = serverStateIndex;
                }
            }
        }
    }

Why does this code need to exist? Was this a fix to "no anim" bug in the past?

GELGELAT commented 5 months ago

I dont know :0