• 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!

Bug solved Idle Animation

gugu15

Well-Known Member
Joined
Dec 15, 2014
Messages
99
Reaction score
63
Hello guys
After getting very angry at seeing the wrong animations of the creatures, I decided to put my hand in the dough and settle, and it worked. What was happening was that the animations of the creatures are separated in the .dat file, stopped group and walking group. Otclient even reads the two groups, byt after reading the first one it overrides the same, ant then only animations are left, the creatures are walking. It was very simple to solve, I was amazed how they have not corrected it yet. The resolution was simple, I just made them put the two groups together in order.

file to apply changes: otclient/src/client/thingtype.cpp in function ThingType::unserialize
Code:
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);
}

picture of my otclient with the bug solved:
Zd5Re78.png


Edit1: The changes have already been implemented in the official project
 
Last edited:
Back
Top