bool Map::placeCreature(const Position& centerPos, Creature* creature, bool extendedPos /*= false*/, bool forced /*= false*/)
{
bool foundTile = false, placeInPz = false;
Tile* tile = getTile(centerPos);
if(tile && !extendedPos)
{
placeInPz = tile->hasFlag(TILESTATE_PROTECTIONZONE);
uint32_t flags = FLAG_IGNOREBLOCKITEM;
if(creature->isAccountManager())
flags |= FLAG_IGNOREBLOCKCREATURE;
ReturnValue ret = tile->__queryAdd(0, creature, 1, flags);
if(forced || ret == RET_NOERROR || ret == RET_PLAYERISNOTINVITED)
foundTile = true;
}
size_t shufflePos = 0;
PairVector relList;
if(extendedPos)
{
shufflePos = 8;
relList.push_back(PositionPair(-2, 0));
relList.push_back(PositionPair(0, -2));
relList.push_back(PositionPair(0, 2));
relList.push_back(PositionPair(2, 0));
std::random_shuffle(relList.begin(), relList.end());
}
relList.push_back(PositionPair(-1, -1));
relList.push_back(PositionPair(-1, 0));
relList.push_back(PositionPair(-1, 1));
relList.push_back(PositionPair(0, -1));
relList.push_back(PositionPair(0, 1));
relList.push_back(PositionPair(1, -1));
relList.push_back(PositionPair(1, 0));
relList.push_back(PositionPair(1, 1));
std::random_shuffle(relList.begin() + shufflePos, relList.end());
uint32_t radius = 1;
Position tryPos;
for(uint32_t n = 1; n <= radius && !foundTile; ++n)
{
for(PairVector::iterator it = relList.begin(); it != relList.end() && !foundTile; ++it)
{
int32_t dx = it->first * n, dy = it->second * n;
tryPos = centerPos;
tryPos.x = tryPos.x + dx;
tryPos.y = tryPos.y + dy;
if(!(tile = getTile(tryPos)) || (placeInPz && !tile->hasFlag(TILESTATE_PROTECTIONZONE)) || tile->hasFlag(TILESTATE_BLOCKSOLID))
continue;
if(tile->__queryAdd(0, creature, 1, 0) == RET_NOERROR)
{
if(!extendedPos)
{
foundTile = true;
break;
}
if(isSightClear(centerPos, tryPos, false))
{
foundTile = true;
break;
}
}
}
}
if(!foundTile)
return false;
int32_t index = 0;
uint32_t flags = 0;
Item* toItem = NULL;
if(Cylinder* toCylinder = tile->__queryDestination(index, creature, &toItem, flags))
{
toCylinder->__internalAddThing(creature);
if(Tile* toTile = toCylinder->getTile())
toTile->qt_node->addCreature(creature);
}
return true;
}