Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
14 kB
6
Indexable
 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;
	//}
}