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(); }