Ejemplo n.º 1
0
void Tile::addThing(const ThingPtr& thing, int stackPos)
{
    if(!thing)
        return;

    if(thing->isEffect()) {
        m_effects.push_back(thing->static_self_cast<Effect>());
    } else {
        // priority                                    854
        // 0 - ground,                        -->      -->
        // 1 - ground borders                 -->      -->
        // 2 - bottom (walls),                -->      -->
        // 3 - on top (doors)                 -->      -->
        // 4 - creatures, from top to bottom  <--      -->
        // 5 - items, from top to bottom      <--      <--
        if(stackPos < 0 || stackPos == 255) {
            int priority = thing->getStackPriority();

            // -1 or 255 => auto detect position
            // -2        => append

            bool append;
            if(stackPos == -2)
                append = true;
            else {
                append = (priority <= 3);

                // newer protocols does not store creatures in reverse order
                if(g_game.getProtocolVersion() >= 854 && priority == 4)
                    append = !append;
            }


            for(stackPos = 0; stackPos < (int)m_things.size(); ++stackPos) {
                int otherPriority = m_things[stackPos]->getStackPriority();
                if((append && otherPriority > priority) || (!append && otherPriority >= priority))
                    break;
            }
        } else if(stackPos > (int)m_things.size())
            stackPos = m_things.size();

        m_things.insert(m_things.begin() + stackPos, thing);

        if(m_things.size() > MAX_THINGS)
            removeThing(m_things[MAX_THINGS]);

        /*
        // check stack priorities
        // this code exists to find stackpos bugs faster
        int lastPriority = 0;
        for(const ThingPtr& thing : m_things) {
            int priority = thing->getStackPriority();
            assert(lastPriority <= priority);
            lastPriority = priority;
        }
        */
    }

    thing->setPosition(m_position);
    thing->onAppear();

    if(thing->isTranslucent())
        checkTranslucentLight();
}