Untitled
unknown
plain_text
a year ago
14 kB
5
Indexable
Never
bool Algorithm::OnFindPath(std::shared_ptr<NetAvatar> player, std::shared_ptr<World> world, const CL_Vec2i& current_pos, const CL_Vec2i& future_pos) { int start = current_pos.m_x + current_pos.m_y * world->GetSize().m_x; int end = future_pos.m_x + future_pos.m_y * world->GetSize().m_x; if (current_pos.m_x < 0 || current_pos.m_x >= world->GetSize().m_x || current_pos.m_y < 0 || current_pos.m_y >= world->GetSize().m_y) return false; if (future_pos.m_x < 0 || future_pos.m_x >= world->GetSize().m_x || future_pos.m_y < 0 || future_pos.m_y >= world->GetSize().m_y) return false; if (world->IsObstacle(player, current_pos) || world->IsObstacle(player, future_pos)) return false; if (start == end) return true; for (auto& tile : world->GetTiles()) { tile.m_path_parent = -1; tile.m_visited = false; tile.m_local = INFINITY; tile.m_global = INFINITY; } auto get_distance = [&](int32_t a, int32_t b) { return sqrtf( (world->GetTile(a)->GetPosition().m_x - world->GetTile(b)->GetPosition().m_x) * (world->GetTile(a)->GetPosition().m_x - world->GetTile(b)->GetPosition().m_x) + (world->GetTile(a)->GetPosition().m_y - world->GetTile(b)->GetPosition().m_y) * (world->GetTile(a)->GetPosition().m_y - world->GetTile(b)->GetPosition().m_y) ); }; int current = start; world->GetTile(start)->m_local = 0.0f; world->GetTile(start)->m_global = get_distance(start, end); std::list<int> not_tested; not_tested.emplace_back(start); while(!not_tested.empty() && current != end) { not_tested.sort([&](const int lhs, const int rhs) { return world->GetTile(lhs)->m_global < world->GetTile(rhs)->m_global; }); while(!not_tested.empty() && world->GetTile(not_tested.front())->m_visited) not_tested.pop_front(); if (not_tested.empty()) break; current = not_tested.front(); world->GetTile(current)->m_visited = true; int x = world->GetTile(current)->GetPosition().m_x, y = world->GetTile(current)->GetPosition().m_y; if (y + 1 < world->GetSize().m_y) { int index = world->GetTile(x + (y + 1) * world->GetSize().m_x)->GetPosition().m_x + world->GetTile(x + (y + 1) * world->GetSize().m_x)->GetPosition().m_y * world->GetSize().m_x; if (!world->GetTile(index)->m_visited && world->IsObstacle(player, { world->GetTile(index)->GetPosition().m_x, world->GetTile(index)->GetPosition().m_y }) == false) not_tested.emplace_back(index); float distance = world->GetTile(current)->m_local + get_distance(current, index); if (distance < world->GetTile(index)->m_local) { world->GetTile(index)->m_path_parent = current; world->GetTile(index)->m_local = distance; world->GetTile(index)->m_global = world->GetTile(index)->m_local + get_distance(index, end); } } if (x + 1 < world->GetSize().m_x) { int index = world->GetTile((x + 1) + y * world->GetSize().m_x)->GetPosition().m_x + world->GetTile((x + 1) + y * world->GetSize().m_x)->GetPosition().m_y * world->GetSize().m_x; if (!world->GetTile(index)->m_visited && world->IsObstacle(player, { world->GetTile(index)->GetPosition().m_x, world->GetTile(index)->GetPosition().m_y }) == false) not_tested.emplace_back(index); float distance = world->GetTile(current)->m_local + get_distance(current, index); if (distance < world->GetTile(index)->m_local) { world->GetTile(index)->m_path_parent = current; world->GetTile(index)->m_local = distance; world->GetTile(index)->m_global = world->GetTile(index)->m_local + get_distance(index, end); } } if (y - 1 >= 0) { int index = world->GetTile(x + (y - 1) * world->GetSize().m_x)->GetPosition().m_x + world->GetTile(x + (y - 1) * world->GetSize().m_x)->GetPosition().m_y * world->GetSize().m_x; if (!world->GetTile(index)->m_visited && world->IsObstacle(player, { world->GetTile(index)->GetPosition().m_x, world->GetTile(index)->GetPosition().m_y }) == false) not_tested.emplace_back(index); float distance = world->GetTile(current)->m_local + get_distance(current, index); if (distance < world->GetTile(index)->m_local) { world->GetTile(index)->m_path_parent = current; world->GetTile(index)->m_local = distance; world->GetTile(index)->m_global = world->GetTile(index)->m_local + get_distance(index, end); } } if (x - 1 >= 0) { int index = world->GetTile((x - 1) + y * world->GetSize().m_x)->GetPosition().m_x + world->GetTile((x - 1) + y * world->GetSize().m_x)->GetPosition().m_y * world->GetSize().m_x; if (!world->GetTile(index)->m_visited && world->IsObstacle(player, { world->GetTile(index)->GetPosition().m_x, world->GetTile(index)->GetPosition().m_y }) == false) not_tested.emplace_back(index); float distance = world->GetTile(current)->m_local + get_distance(current, index); if (distance < world->GetTile(index)->m_local) { world->GetTile(index)->m_path_parent = current; world->GetTile(index)->m_local = distance; world->GetTile(index)->m_global = world->GetTile(index)->m_local + get_distance(index, end); } } } if (end != -1) { int p = end; if (p < 0 || p >= world->GetSize().m_x * world->GetSize().m_y) return false; while (world->GetTile(p)->m_path_parent != -1) { if (world->GetTile(p)->m_path_parent == p) return false; if (p < 0 || p >= world->GetSize().m_x * world->GetSize().m_y) return false; p = world->GetTile(p)->m_path_parent; } if (p == start) return true; } return false; } bool ar_turi_noclipa(World* world_, int x, int y, WorldBlock* target_, ENetPeer* p_) { //try { vector<int> new_tiles{}; if (items[world_->blocks[(int)x / 32 + ((int)y / 32 * 100)].fg].collisionType != 1 or items[world_->blocks[(int)x / 32 + ((int)y / 32 * 100)].fg].entrance or items[world_->blocks[(int)x / 32 + ((int)y / 32 * 100)].fg].toggleable or items[world_->blocks[(int)x / 32 + ((int)y / 32 * 100)].fg].vipentrance) { if (items[world_->blocks[(int)x / 32 + ((int)y / 32 * 100)].fg].vipentrance and not world_->blocks[(int)x / 32 + ((int)y / 32 * 100)].limit_admins and world_->owner_name != pInfo(p_)->tankIDName and not world_->owner_name.empty() and find(world_->blocks[(int)x / 32 + ((int)y / 32 * 100)].admins.begin(), world_->blocks[(int)x / 32 + ((int)y / 32 * 100)].admins.end(), pInfo(p_)->tankIDName) == world_->blocks[(int)x / 32 + ((int)y / 32 * 100)].admins.end()) { } else if (items[world_->blocks[(int)x / 32 + ((int)y / 32 * 100)].fg].entrance and is_false_state(world_->blocks[(int)x / 32 + ((int)y / 32 * 100)], 0x00800000) and world_->owner_name != pInfo(p_)->tankIDName and not world_->open_to_public and not world_->owner_name.empty() and !guild_access(p_, world_->guild_id) and find(world_->admins.begin(), world_->admins.end(), pInfo(p_)->tankIDName) == world_->admins.end()) { } else if (items[world_->blocks[(int)x / 32 + ((int)y / 32 * 100)].fg].toggleable and is_false_state(world_->blocks[(int)x / 32 + ((int)y / 32 * 100)], 0x00400000)) { } else { new_tiles.push_back((int)x / 32 + ((int)y / 32 * 100)); } } int ySize = world_->blocks.size() / 100, xSize = world_->blocks.size() / ySize; vector<WorldBlock> shadow_copy = world_->blocks; for (int i2 = 0; i2 < new_tiles.size(); i2++) { int x_ = new_tiles[i2] % 100, y_ = new_tiles[i2] / 100; /*if (abs(x_ - x) >= 10 and abs(y_ - y) >= 10) { return true; }*/ if (&world_->blocks[x_ + (y_ * 100)] == target_ and items[shadow_copy[x_ + (y_ * 100)].fg].collisionType != 1) { return false; } if (x_ < 99 and items[shadow_copy[x_ + 1 + (y_ * 100)].fg].collisionType != 1 or x_ < 99 and items[shadow_copy[x_ + 1 + (y_ * 100)].fg].entrance or x_ < 99 and items[shadow_copy[x_ + 1 + (y_ * 100)].fg].toggleable) { if (items[shadow_copy[x_ + 1 + (y_ * 100)].fg].vipentrance and not shadow_copy[x_ + 1 + (y_ * 100)].limit_admins and world_->owner_name != pInfo(p_)->tankIDName and not world_->owner_name.empty() and find(shadow_copy[x_ + 1 + (y_ * 100)].admins.begin(), shadow_copy[x_ + 1 + (y_ * 100)].admins.end(), pInfo(p_)->tankIDName) == shadow_copy[x_ + 1 + (y_ * 100)].admins.end()) { } else if (items[shadow_copy[x_ + 1 + (y_ * 100)].fg].entrance and is_false_state(shadow_copy[x_ + 1 + (y_ * 100)], 0x00800000) and world_->owner_name != pInfo(p_)->tankIDName and not world_->open_to_public and not world_->owner_name.empty() and !guild_access(p_, world_->guild_id) and find(world_->admins.begin(), world_->admins.end(), pInfo(p_)->tankIDName) == world_->admins.end()) { } else if (items[shadow_copy[x_ + 1 + (y_ * 100)].fg].toggleable and is_false_state(shadow_copy[x_ + 1 + (y_ * 100)], 0x00400000)) { } else { if (not shadow_copy[x_ + 1 + (y_ * 100)].scanned) { shadow_copy[x_ + 1 + (y_ * 100)].scanned = true; new_tiles.push_back(x_ + 1 + (y_ * 100)); } } } if (x_ > 0 and items[shadow_copy[x_ - 1 + (y_ * 100)].fg].collisionType != 1 or x_ > 0 and items[shadow_copy[x_ - 1 + (y_ * 100)].fg].entrance or x_ > 0 and items[shadow_copy[x_ - 1 + (y_ * 100)].fg].toggleable) { if (items[shadow_copy[x_ - 1 + (y_ * 100)].fg].vipentrance and not shadow_copy[x_ - 1 + (y_ * 100)].limit_admins and world_->owner_name != pInfo(p_)->tankIDName and not world_->owner_name.empty() and find(shadow_copy[x_ - 1 + (y_ * 100)].admins.begin(), shadow_copy[x_ - 1 + (y_ * 100)].admins.end(), pInfo(p_)->tankIDName) == shadow_copy[x_ - 1 + (y_ * 100)].admins.end()) { } else if (items[shadow_copy[x_ - 1 + (y_ * 100)].fg].entrance and is_false_state(shadow_copy[x_ - 1 + (y_ * 100)], 0x00800000) and world_->owner_name != pInfo(p_)->tankIDName and not world_->open_to_public and not world_->owner_name.empty() and !guild_access(p_, world_->guild_id) and find(world_->admins.begin(), world_->admins.end(), pInfo(p_)->tankIDName) == world_->admins.end()) { } else if (items[shadow_copy[x_ - 1 + (y_ * 100)].fg].toggleable and is_false_state(shadow_copy[x_ - 1 + (y_ * 100)], 0x00400000)) { } else { if (not shadow_copy[x_ - 1 + (y_ * 100)].scanned) { shadow_copy[x_ - 1 + (y_ * 100)].scanned = true; new_tiles.push_back(x_ - 1 + (y_ * 100)); } } } if (y_ < 59 and items[shadow_copy[x_ + ((y_ + 1) * 100)].fg].collisionType != 1 or y_ < 59 and items[shadow_copy[x_ + ((y_ + 1) * 100)].fg].entrance or y_ < 59 and items[shadow_copy[x_ + ((y_ + 1) * 100)].fg].toggleable) { if (items[shadow_copy[x_ + ((y_ + 1) * 100)].fg].vipentrance and not shadow_copy[x_ + ((y_ + 1) * 100)].limit_admins and world_->owner_name != pInfo(p_)->tankIDName and not world_->owner_name.empty() and find(shadow_copy[x_ + ((y_ + 1) * 100)].admins.begin(), shadow_copy[x_ + ((y_ + 1) * 100)].admins.end(), pInfo(p_)->tankIDName) == shadow_copy[x_ + ((y_ + 1) * 100)].admins.end()) { } else if (items[shadow_copy[x_ + ((y_ + 1) * 100)].fg].entrance and is_false_state(shadow_copy[x_ + ((y_ + 1) * 100)], 0x00800000) and world_->owner_name != pInfo(p_)->tankIDName and not world_->open_to_public and not world_->owner_name.empty() and !guild_access(p_, world_->guild_id) and find(world_->admins.begin(), world_->admins.end(), pInfo(p_)->tankIDName) == world_->admins.end()) { } else if (items[shadow_copy[x_ + ((y_ + 1) * 100)].fg].toggleable and is_false_state(shadow_copy[x_ + ((y_ + 1) * 100)], 0x00400000)) { } else { if (not shadow_copy[x_ + ((y_ + 1) * 100)].scanned) { shadow_copy[x_ + ((y_ + 1) * 100)].scanned = true; new_tiles.push_back(x_ + ((y_ + 1) * 100)); } } } if (y_ > 0 and items[shadow_copy[x_ + ((y_ - 1) * 100)].fg].collisionType != 1 or y_ > 0 and items[shadow_copy[x_ + 1 + ((y_ - 1) * 100)].fg].entrance or y_ > 0 and items[shadow_copy[x_ + 1 + ((y_ - 1) * 100)].fg].toggleable) { if (items[shadow_copy[x_ + ((y_ - 1) * 100)].fg].vipentrance and not shadow_copy[x_ + ((y_ - 1) * 100)].limit_admins and world_->owner_name != pInfo(p_)->tankIDName and not world_->owner_name.empty() and find(shadow_copy[x_ + ((y_ - 1) * 100)].admins.begin(), shadow_copy[x_ + ((y_ - 1) * 100)].admins.end(), pInfo(p_)->tankIDName) == shadow_copy[x_ + ((y_ - 1) * 100)].admins.end()) { } else if (items[shadow_copy[x_ + ((y_ - 1) * 100)].fg].entrance and is_false_state(shadow_copy[x_ + ((y_ - 1) * 100)], 0x00800000) and world_->owner_name != pInfo(p_)->tankIDName and not world_->open_to_public and not world_->owner_name.empty() and !guild_access(p_, world_->guild_id) and find(world_->admins.begin(), world_->admins.end(), pInfo(p_)->tankIDName) == world_->admins.end()) { } else if (items[shadow_copy[x_ + ((y_ - 1) * 100)].fg].toggleable and is_false_state(shadow_copy[x_ + ((y_ - 1) * 100)], 0x00400000)) { } else { if (not shadow_copy[x_ + ((y_ - 1) * 100)].scanned) { shadow_copy[x_ + ((y_ - 1) * 100)].scanned = true; new_tiles.push_back(x_ + ((y_ - 1) * 100)); } } } } return true; //} //catch (out_of_range) { //return false; //} }