bool Map::Walk(NPC *from, Direction direction) { PacketBuilder builder; int seedistance = this->world->config["SeeDistance"]; unsigned char target_x = from->x; unsigned char target_y = from->y; switch (direction) { case DIRECTION_UP: target_y -= 1; if (target_y > from->y) { return false; } break; case DIRECTION_RIGHT: target_x += 1; if (target_x < from->x) { return false; } break; case DIRECTION_DOWN: target_y += 1; if (target_x < from->x) { return false; } break; case DIRECTION_LEFT: target_x -= 1; if (target_x > from->x) { return false; } break; } if (from->pet && from->Data()->type == ENF::Pet && (!this->Walkable(target_x, target_y, Map_Tile::Wall))) { return false; } if (!from->pet && !from->Data()->type != ENF::Pet && (!this->Walkable(target_x, target_y, true)) || this->Occupied(target_x, target_y, Map::PlayerAndNPC)) { return false; } from->x = target_x; from->y = target_y; int newx; int newy; int oldx; int oldy; std::vector<std::pair<int, int> > newcoords; std::vector<std::pair<int, int> > oldcoords; PtrVector<Character> newchars; PtrVector<Character> oldchars; switch (direction) { case DIRECTION_UP: for (int i = -seedistance; i <= seedistance; ++i) { newy = from->y - seedistance + std::abs(i); newx = from->x + i; oldy = from->y + seedistance + 1 - std::abs(i); oldx = from->x + i; newcoords.push_back(std::make_pair(newx, newy)); oldcoords.push_back(std::make_pair(oldx, oldy)); } break; case DIRECTION_RIGHT: for (int i = -seedistance; i <= seedistance; ++i) { newx = from->x + seedistance - std::abs(i); newy = from->y + i; oldx = from->x - seedistance - 1 + std::abs(i); oldy = from->y + i; newcoords.push_back(std::make_pair(newx, newy)); oldcoords.push_back(std::make_pair(oldx, oldy)); } break; case DIRECTION_DOWN: for (int i = -seedistance; i <= seedistance; ++i) { newy = from->y + seedistance - std::abs(i); newx = from->x + i; oldy = from->y - seedistance - 1 + std::abs(i); oldx = from->x + i; newcoords.push_back(std::make_pair(newx, newy)); oldcoords.push_back(std::make_pair(oldx, oldy)); } break; case DIRECTION_LEFT: for (int i = -seedistance; i <= seedistance; ++i) { newx = from->x - seedistance + std::abs(i); newy = from->y + i; oldx = from->x + seedistance + 1 - std::abs(i); oldy = from->y + i; newcoords.push_back(std::make_pair(newx, newy)); oldcoords.push_back(std::make_pair(oldx, oldy)); } break; } from->direction = direction; UTIL_PTR_LIST_FOREACH(this->characters, Character, checkchar) { for (std::size_t i = 0; i < oldcoords.size(); ++i) { if (checkchar->x == oldcoords[i].first && checkchar->y == oldcoords[i].second) { oldchars.push_back(*checkchar); } else if (checkchar->x == newcoords[i].first && checkchar->y == newcoords[i].second) { newchars.push_back(*checkchar); } } } builder.SetID(PACKET_APPEAR, PACKET_REPLY); builder.AddChar(0); builder.AddByte(255); builder.AddChar(from->index); builder.AddShort(from->id); builder.AddChar(from->x); builder.AddChar(from->y); builder.AddChar(from->direction); UTIL_PTR_VECTOR_FOREACH(newchars, Character, character) { character->player->client->SendBuilder(builder); } builder.Reset(); builder.SetID(PACKET_NPC, PACKET_PLAYER); builder.AddChar(from->index); builder.AddChar(from->x); builder.AddChar(from->y); builder.AddChar(from->direction); builder.AddByte(255); builder.AddByte(255); builder.AddByte(255); UTIL_PTR_LIST_FOREACH(this->characters, Character, character) { if (!character->InRange(from)) { continue; } character->player->client->SendBuilder(builder); } UTIL_PTR_VECTOR_FOREACH(oldchars, Character, character) { from->RemoveFromView(*character); } return true; }