• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Final thread for fixing OTClient dashing animation issue for TFS 1.3

Togu

Advanced OT User
Joined
Jun 22, 2018
Messages
308
Solutions
1
Reaction score
183
Location
Brazil
I made a super slow motion to show the exactly dashing issue:
final - Streamable (https://streamable.com/2xek1) troll going from up to down and comparing with real gif and sprites
test - Streamable (https://streamable.com/wmv6e) troll going from right to left
Split animated GIF image in frames (free online tool) (https://ezgif.com/split/ezgif-1-1c80fb2cf982.gif) gif and sprites troll going from up to down

More information you can find here:
https://github.com/edubart/otclient/issues/937
https://otland.net/threads/looking-...nimations-walking-frames-for-otclient.260611/
https://otland.net/threads/animations-lets-give-it-a-try.262781/
otland/otclient (https://github.com/otland/otclient/compare/master...otland:WalkAnimation?expand=1) Ninja's solution for local player walking animation (I changed it a little to my client)

I fixed the local player walking animation issue using Ninja's solution and fixed the pushing diagonal laggy issue (https://i.gyazo.com/412d93e4a799cdc93fd098c04001d7e2.mp4) setting the factor from getStepDuration() (in creature.cpp in client sources) to 1.

But this dashing issue is not so easy to solve, I need tips and help from the community and I guess this is wanted from everybody.

My guess is that creatures that aren't the local player are being drawn with wrong position or wrong speed and then when the creature reach the next tile position on server side the creature position on client side is refreshed (you can see that Troll's name and health bar teleports too, so its not a problem on skipping frames, its skipping positions) without the sprite reaching it.

I've seen that the information sent from server to client is just the oldPos and the newPos, on client the sprites are rendered using the oldPos + newPos + gettingStepDuration() + totalPixelsWalked (something like that) and I verified the getStepDuration() formula from client sources and server sources and they look almost the same thing... I'm kind of lost here

@Ninja @Gesior.pl @Evolunia @Dual Core

Edit:
Created an official issue on otland/otclient github:
[10.98] Creatures on screen appears to be dashing/teleporting to next tile when walking · Issue #21 · otland/otclient (https://github.com/otland/otclient/issues/21)
 
Last edited:
I made a super slow motion to show the exactly dashing issue:
final - Streamable (https://streamable.com/2xek1) troll going from up to down and comparing with real gif and sprites
test - Streamable (https://streamable.com/wmv6e) troll going from right to left
Split animated GIF image in frames (free online tool) (https://ezgif.com/split/ezgif-1-1c80fb2cf982.gif) gif and sprites troll going from up to down

More information you can find here:
https://github.com/edubart/otclient/issues/937
https://otland.net/threads/looking-...nimations-walking-frames-for-otclient.260611/
https://otland.net/threads/animations-lets-give-it-a-try.262781/
otland/otclient (https://github.com/otland/otclient/compare/master...otland:WalkAnimation?expand=1) Ninja's solution for local player walking animation (I changed it a little to my client)

I fixed the local player walking animation issue using Ninja's solution and fixed the pushing diagonal laggy issue (https://i.gyazo.com/412d93e4a799cdc93fd098c04001d7e2.mp4) setting the factor from getStepDuration() (in creature.cpp in client sources) to 1.

But this dashing issue is not so easy to solve, I need tips and help from the community and I guess this is wanted from everybody.

My guess is that creatures that aren't the local player are being drawn with wrong position or wrong speed and then when the creature reach the next tile position on server side the creature position on client side is refreshed (you can see that Troll's name and health bar teleports too, so its not a problem on skipping frames, its skipping positions) without the sprite reaching it.

I've seen that the information sent from server to client is just the oldPos and the newPos, on client the sprites are rendered using the oldPos + newPos + gettingStepDuration() + totalPixelsWalked (something like that) and I verified the getStepDuration() formula from client sources and server sources and they look almost the same thing... I'm kind of lost here

@Ninja @Gesior.pl @Evolunia @Dual Core

Edit:
Created an official issue on otland/otclient github:
[10.98] Creatures on screen appears to be dashing/teleporting to next tile when walking · Issue #21 · otland/otclient (https://github.com/otland/otclient/issues/21)

I think I found the bug.

creature.cpp:

I changed the return value of this function to 80% of the original value.
The factor is commented to solve the pushing diagonal laggy issue.
This line interval = std::ceil(interval / (50 * 1.f)) * 50; uses 50 cause I use TFS 1.3.
Code:
int Creature::getStepDuration(bool ignoreDiagonal, Otc::Direction dir)
{
    int speed = m_speed;
    if(speed < 1)
        return 0;

    if(g_game.getFeature(Otc::GameNewSpeedLaw))
        speed *= 2;

    int groundSpeed = 0;
    Position tilePos;

    if(dir == Otc::InvalidDirection)
        tilePos = m_lastStepToPosition;
    else
        tilePos = m_position.translatedToDirection(dir);

    if(!tilePos.isValid())
        tilePos = m_position;
    const TilePtr& tile = g_map.getTile(tilePos);
    if(tile) {
        groundSpeed = tile->getGroundSpeed();
        if(groundSpeed == 0)
            groundSpeed = 150;
    }

    int interval = 1000;
    if(groundSpeed > 0 && speed > 0)
        interval = 1000 * groundSpeed;

    if(g_game.getFeature(Otc::GameNewSpeedLaw) && hasSpeedFormula()) {
        int formulatedSpeed = 1;
        if(speed > -m_speedFormula[Otc::SpeedFormulaB]) {
            formulatedSpeed = std::max<int>(1, (int)floor((m_speedFormula[Otc::SpeedFormulaA] * log((speed / 2)
                 + m_speedFormula[Otc::SpeedFormulaB]) + m_speedFormula[Otc::SpeedFormulaC]) + 0.5));
        }
        interval = std::floor(interval / (double)formulatedSpeed);
    }
    else
        interval /= speed;

    if(g_game.getClientVersion() >= 900)
        interval = std::ceil(interval / (50 * 1.f)) * 50;

    //float factor = 3;
    //if(g_game.getClientVersion() <= 810)
    //    factor = 2;

    //interval = std::max<int>(interval, g_game.getServerBeat());

    //if(!ignoreDiagonal && (m_lastStepDirection == Otc::NorthWest || m_lastStepDirection == Otc::NorthEast ||
    //   m_lastStepDirection == Otc::SouthWest || m_lastStepDirection == Otc::SouthEast))
    //    interval *= factor;

   
    if (this->isLocalPlayer()) {
        return interval;
    }

    return (int)interval*0.8f;
}

My updateWalkAnimation function based on ninjalulz fix for walking and idle animations
Code:
void Creature::updateWalkAnimation(int totalPixelsWalked)
{
    // update outfit animation
    if(m_outfit.getCategory() != ThingCategoryCreature)
        return;

    int footAnimPhases = getAnimationPhases() - 1; //returns 8
    float footDelay = getStepDuration(true) / footAnimPhases; //varies with the g round

    // since mount is a different outfit we need to get the mount animation phases
    if(m_outfit.getMount() != 0) {
        ThingType *type = g_things.rawGetThingType(m_outfit.getMount(), m_outfit.getCategory());
        footAnimPhases = type->getAnimationPhases() - 1;
        footDelay = getStepDuration(true) / footAnimPhases;
    }

    if (totalPixelsWalked >= 32 && !m_walkFinishAnimEvent) {
        m_footStep = 0;

        auto self = static_self_cast<Creature>();
        m_walkFinishAnimEvent = g_dispatcher.scheduleEvent([self] {
            if (!self->m_walking || self->m_walkTimer.ticksElapsed() >= self->getStepDuration(true)) {
                self->m_walkAnimationPhase = 0;
            }
            self->m_walkFinishAnimEvent = nullptr;
        }, std::min<int>(footDelay, 200));
    }

    if (footAnimPhases == 0) {
        m_walkAnimationPhase = 0;
    }
    else if(m_footStepDrawn && m_footTimer.ticksElapsed() >= footDelay && totalPixelsWalked < 32) {
        m_footStep++;
        m_walkAnimationPhase = (m_footStep % footAnimPhases);
        m_footStepDrawn = false;
        m_footTimer.restart();
    }
    else if(m_walkAnimationPhase == 0 && totalPixelsWalked < 32) {
        m_walkAnimationPhase = (m_footStep % footAnimPhases);
    }
}

Videos
https://streamable.com/2gq1h
https://streamable.com/j679m

Conclusion
Client creature speed values are treated different from server creature speed values or the getStepDuration is wrong on client or server sources.

This works, but how do we know we can rely on this as a permanent fix and that it doesnt break something else? Because Diagonal movement rubberbanding seems to be twice as much on players after fixing rendering issue on diagonal push for monsters.

It would be really nice if we could come to a permanent good solution on this one.
 
Back
Top