0ad/source/simulation2/helpers/Los.h
Vantha 21a61721a7 LosRevealAll -> LosRevealWholeMap
This name is more descriptive.
And the plan is to split off the extra player value of the vector into
an own flag in the future, and LosRevealAllForAll would have been a poor
name for that.
2026-03-03 11:25:52 +01:00

130 lines
3.7 KiB
C++

/* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_LOS
#define INCLUDED_LOS
#include "lib/posix/posix_types.h"
#include "lib/types.h"
// It doesn't seem worth moving the implementation to c++ and early-declaring Grid
// since files must include "Los.h" explicitly, and that's only done in .cpp files.
#include "simulation2/helpers/Grid.h"
/**
* Computing LOS data at a very high resolution is not necessary and quite slow.
* This is the size, in meters, separating each LOS vertex.
* (Note that this also means it is the minimal meaningful resolution of any vision range change).
*/
static constexpr i32 LOS_TILE_SIZE = 4;
enum class LosState : u8
{
UNEXPLORED = 0,
EXPLORED = 1,
VISIBLE = 2,
MASK = 3
};
/**
* Object providing efficient abstracted access to the LOS state.
* This depends on some implementation details of CCmpRangeManager.
*
* This *ignores* the GetLosRevealWholeMap flag - callers should check that explicitly.
*/
class CLosQuerier
{
private:
friend class CCmpRangeManager;
friend class TestLOSTexture;
CLosQuerier(u32 playerMask, const Grid<u32>& data, ssize_t verticesPerSide) :
m_Data(data), m_PlayerMask(playerMask), m_VerticesPerSide(verticesPerSide)
{
}
const CLosQuerier& operator=(const CLosQuerier&); // not implemented
public:
/**
* Returns whether the given vertex is visible (i.e. is within a unit's LOS).
*/
inline bool IsVisible(ssize_t i, ssize_t j) const
{
if (!(i >= 0 && j >= 0 && i < m_VerticesPerSide && j < m_VerticesPerSide))
return false;
// Check high bit of each bit-pair
if ((m_Data.get(i, j) & m_PlayerMask) & 0xAAAAAAAAu)
return true;
else
return false;
}
/**
* Returns whether the given vertex is explored (i.e. was (or still is) within a unit's LOS).
*/
inline bool IsExplored(ssize_t i, ssize_t j) const
{
if (!(i >= 0 && j >= 0 && i < m_VerticesPerSide && j < m_VerticesPerSide))
return false;
// Check low bit of each bit-pair
if ((m_Data.get(i, j) & m_PlayerMask) & 0x55555555u)
return true;
else
return false;
}
/**
* Returns whether the given vertex is visible (i.e. is within a unit's LOS).
* i and j must be in the range [0, verticesPerSide), else behaviour is undefined.
*/
inline bool IsVisible_UncheckedRange(ssize_t i, ssize_t j) const
{
#ifndef NDEBUG
ENSURE(i >= 0 && j >= 0 && i < m_VerticesPerSide && j < m_VerticesPerSide);
#endif
// Check high bit of each bit-pair
if ((m_Data.get(i, j) & m_PlayerMask) & 0xAAAAAAAAu)
return true;
else
return false;
}
/**
* Returns whether the given vertex is explored (i.e. was (or still is) within a unit's LOS).
* i and j must be in the range [0, verticesPerSide), else behaviour is undefined.
*/
inline bool IsExplored_UncheckedRange(ssize_t i, ssize_t j) const
{
#ifndef NDEBUG
ENSURE(i >= 0 && j >= 0 && i < m_VerticesPerSide && j < m_VerticesPerSide);
#endif
// Check low bit of each bit-pair
if ((m_Data.get(i, j) & m_PlayerMask) & 0x55555555u)
return true;
else
return false;
}
private:
u32 m_PlayerMask;
const Grid<u32>& m_Data;
ssize_t m_VerticesPerSide;
};
#endif // INCLUDED_LOS