Gugu - Karin Uzumaki

Bug nas animações resolvido

4 posts in this topic

Fala galera..

Depois de muito tempo puto com aquele bug do otclient onde as animações das perninhas ficavam travadas(bug que aliás já tem mais de 1 ano), me cansei e decidi resolver essa bagaça. Pityko também me ajudou, descompilou o Flash Client do global para que eu pudesse dar uma olhada.

Então agora está resolvido, era algo mto simples, fiquei até desacreditado como algo tão simples não foi resolvido até hoje.

Pra quem não notou o bug, vou explicar: O otclient estava com uns problemas pra ler os sprites do arquivo .spr, ele só lia as animações onde as criaturas estavam andando e descartava as animações onde o player estava parado, então mesmo vc parado o otclient desenha voce como se estivesse andando com um pé a frente e outro atrás.

Como não posso postar meu otclient aqui, porque eu estou usando ubuntu e não tem como compilar pra windows daqui, vou deixar o codigo da correção do bug aqui pro Faramir compilar e colocar no client do servidor dele.

o arquivo que as alterações devem ser feitas é o otclient/src/client/thingtype.cpp, na função ThingType::unserialize

 

 

 


void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileStreamPtr& fin)
{
    m_null = false;
    m_id = clientId;
    m_category = category;

    int count = 0, attr = -1;
    bool done = false;
    for(int i = 0 ; i < ThingLastAttr;++i) {
        count++;
        attr = fin->getU8();
        if(attr == ThingLastAttr) {
            done = true;
            break;
        }

        if(g_game.getClientVersion() >= 1000) {
            /* In 10.10+ all attributes from 16 and up were
             * incremented by 1 to make space for 16 as
             * "No Movement Animation" flag.
             */
            if(attr == 16)
                attr = ThingAttrNoMoveAnimation;
            else if(attr > 16)
                attr -= 1;
        } else if(g_game.getClientVersion() >= 860) {
            /* Default attribute values follow
             * the format of 8.6-9.86.
             * Therefore no changes here.
             */
        } else if(g_game.getClientVersion() >= 780) {
            /* In 7.80-8.54 all attributes from 8 and higher were
             * incremented by 1 to make space for 8 as
             * "Item Charges" flag.
             */
            if(attr == 8) {
                m_attribs.set(ThingAttrChargeable, true);
                continue;
            } else if(attr > 8)
                attr -= 1;
        } else if(g_game.getClientVersion() >= 755) {
            /* In 7.55-7.72 attributes 23 is "Floor Change". */
            if(attr == 23)
                attr = ThingAttrFloorChange;
        } else if(g_game.getClientVersion() >= 740) {
            /* In 7.4-7.5 attribute "Ground Border" did not exist
             * attributes 1-15 have to be adjusted.
             * Several other changes in the format.
             */
            if(attr > 0 && attr <= 15)
                attr += 1;
            else if(attr == 16)
                attr = ThingAttrLight;
            else if(attr == 17)
                attr = ThingAttrFloorChange;
            else if(attr == 18)
                attr = ThingAttrFullGround;
            else if(attr == 19)
                attr = ThingAttrElevation;
            else if(attr == 20)
                attr = ThingAttrDisplacement;
            else if(attr == 22)
                attr = ThingAttrMinimapColor;
            else if(attr == 23)
                attr = ThingAttrRotateable;
            else if(attr == 24)
                attr = ThingAttrLyingCorpse;
            else if(attr == 25)
                attr = ThingAttrHangable;
            else if(attr == 26)
                attr = ThingAttrHookSouth;
            else if(attr == 27)
                attr = ThingAttrHookEast;
            else if(attr == 28)
                attr = ThingAttrAnimateAlways;

            /* "Multi Use" and "Force Use" are swapped */
            if(attr == ThingAttrMultiUse)
                attr = ThingAttrForceUse;
            else if(attr == ThingAttrForceUse)
                attr = ThingAttrMultiUse;
        }

        switch(attr) {
            case ThingAttrDisplacement: {
                if(g_game.getClientVersion() >= 755) {
                    m_displacement.x = fin->getU16();
                    m_displacement.y = fin->getU16();
                } else {
                    m_displacement.x = 8;
                    m_displacement.y = 8;
                }
                m_attribs.set(attr, true);
                break;
            }
            case ThingAttrLight: {
                Light light;
                light.intensity = fin->getU16();
                light.color = fin->getU16();
                m_attribs.set(attr, light);
                break;
            }
            case ThingAttrMarket: {
                MarketData market;
                market.category = fin->getU16();
                market.tradeAs = fin->getU16();
                market.showAs = fin->getU16();
                market.name = fin->getString();
                market.restrictVocation = fin->getU16();
                market.requiredLevel = fin->getU16();
                m_attribs.set(attr, market);
                break;
            }
            case ThingAttrElevation: {
                m_elevation = fin->getU16();
                m_attribs.set(attr, m_elevation);
                break;
            }
            case ThingAttrUsable:
            case ThingAttrGround:
            case ThingAttrWritable:
            case ThingAttrWritableOnce:
            case ThingAttrMinimapColor:
            case ThingAttrCloth:
            case ThingAttrLensHelp:
                m_attribs.set(attr, fin->getU16());
                break;
            default:
                m_attribs.set(attr, true);
                break;
        };
    }

    if(!done)
        stdext::throw_exception(stdext::format("corrupt data (id: %d, category: %d, count: %d, lastAttr: %d)",
            m_id, m_category, count, attr));

    bool hasFrameGroups = (category == ThingCategoryCreature && g_game.getFeature(Otc::GameIdleAnimations));
    uint8 groupCount = hasFrameGroups ? fin->getU8() : 1;

    /*
		Sobre o bug:
		Este loop esta sobreescrevendo o grupo de frames antigos, ou seja, o grupo idle.
		O grupo é apagado, e então só resta a animação walking.
		O que deve ser feito é juntar as duas animações.
		Informações:
		width, height, layers, e pattern(x,y,z) são os mesmos valores, os que mudam são: animationsPhase, e consequentemente o totalSpŕites
		bug resolvido por: Slash/Gugu
    */
    m_animationPhases = 0;
    int lastTotalSprites = 0;

    for(int i = 0; i < groupCount; ++i) {
        uint8 frameGroupType = FrameGroupDefault;
        if(hasFrameGroups)
            frameGroupType = fin->getU8();

        uint8 width = fin->getU8();
        uint8 height = fin->getU8();
        m_size = Size(width, height);
        if(width > 1 || height > 1) {
            m_realSize = fin->getU8();
            m_exactSize = std::min<int>(m_realSize, std::max<int>(width * 32, height * 32));
        }
        else
            m_exactSize = 32;

        m_layers = fin->getU8();
        m_numPatternX = fin->getU8();
        m_numPatternY = fin->getU8();
        if(g_game.getClientVersion() >= 755)
            m_numPatternZ = fin->getU8();
        else
            m_numPatternZ = 1;
        int n_phases = fin->getU8();

        m_animationPhases += n_phases;

        if(n_phases > 1 && g_game.getFeature(Otc::GameEnhancedAnimations)) {
            m_animator = AnimatorPtr(new Animator);
            m_animator->unserialize(n_phases, fin);
        }

        int totalSprites = m_size.area() * m_layers * m_numPatternX * m_numPatternY * m_numPatternZ * n_phases;

        if((lastTotalSprites+totalSprites) > 4096)
            stdext::throw_exception("a thing type has more than 4096 sprites");

        m_spritesIndex.resize((lastTotalSprites+totalSprites));
        for(int i = lastTotalSprites; i < (lastTotalSprites+totalSprites); i++)
            m_spritesIndex[i] = g_game.getFeature(Otc::GameSpritesU32) ? fin->getU32() : fin->getU16();

        lastTotalSprites += totalSprites;
    }

    m_textures.resize(m_animationPhases);
    m_texturesFramesRects.resize(m_animationPhases);
    m_texturesFramesOriginRects.resize(m_animationPhases);
    m_texturesFramesOffsets.resize(m_animationPhases);
}

 

Imagem do bug corrgido:

Zd5Re78.png

 

 

5 people like this

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now