std::list<BlockingObject> World::LoS(const position &startingpos, const position &endingpos) const { std::list<BlockingObject> ret; ret.clear(); bool steep = std::abs(startingpos.y - endingpos.y) > std::abs(startingpos.x - endingpos.x); short int startx=startingpos.x; short int starty=startingpos.y; short int endx=endingpos.x; short int endy=endingpos.y; if (steep) { //change x,y values for correct algorithm in negativ range short int change; change = startx; startx = starty; starty = change; change = endx; endx = endy; endy = change; } bool swapped = startx > endx; if (swapped) { short int change; change = startx; startx = endx; endx = change; change = starty; starty = endy; endy = change; } short int deltax = endx - startx; short int deltay = std::abs(endy - starty); short int error = 0; short int ystep=1; short int y = starty; if (starty > endy) { ystep = -1; } for (short int x = startx; x <= endx; ++x) { if (!(x == startx && y == starty) && !(x == endx && y == endy)) { BlockingObject bo; Field *temp; position pos{x, y, startingpos.z}; if (steep) { pos.x = y; pos.y = x; } if (GetPToCFieldAt(temp, pos)) { if (temp->IsPlayerOnField()) { bo.blockingType = BlockingObject::BT_CHARACTER; bo.blockingChar = findCharacterOnField(pos); if (swapped) { ret.push_back(bo); } else { ret.push_front(bo); } } else { ScriptItem it; for (size_t i = 0; i < temp->NumberOfItems(); ++i) { auto testItem = temp->getStackItem(i); if (testItem.getVolume() > it.getVolume()) { it = testItem; } } if (it.isLarge()) { bo.blockingType = BlockingObject::BT_ITEM; it.pos = pos; it.type = ScriptItem::it_field; bo.blockingItem = it; if (swapped) { ret.push_back(bo); } else { ret.push_front(bo); } } } } } error += deltay; if (2*error >= deltax) { y+=ystep; error -= deltax; } } return ret; }