Browse Source

Refactor VisionCrawlTable

pull/5042/head
Vladimir Olteanu 4 years ago committed by Anders Jenbo
parent
commit
8fd3be67b5
  1. 15
      Source/engine/displacement.hpp
  2. 170
      Source/lighting.cpp
  3. 4
      Source/lighting.h

15
Source/engine/displacement.hpp

@ -95,6 +95,14 @@ struct DisplacementOf {
return *this;
}
template <typename DeltaU>
constexpr DisplacementOf<DeltaT> &operator*=(const DisplacementOf<DeltaU> factor)
{
deltaX = static_cast<DeltaT>(deltaX * factor.deltaX);
deltaY = static_cast<DeltaT>(deltaY * factor.deltaY);
return *this;
}
constexpr DisplacementOf<DeltaT> &operator/=(const int factor)
{
deltaX /= factor;
@ -284,6 +292,13 @@ constexpr DisplacementOf<DisplacementDeltaT> operator*(DisplacementOf<Displaceme
return a;
}
template <typename DisplacementDeltaT, typename DisplacementDeltaU>
constexpr DisplacementOf<DisplacementDeltaT> operator*(DisplacementOf<DisplacementDeltaT> a, const DisplacementOf<DisplacementDeltaU> factor)
{
a *= factor;
return a;
}
template <typename DisplacementDeltaT>
constexpr DisplacementOf<DisplacementDeltaT> operator/(DisplacementOf<DisplacementDeltaT> a, const int factor)
{

170
Source/lighting.cpp

@ -30,31 +30,31 @@ namespace {
* X- Y-coordinate offsets of lighting visions.
* The last entry-pair is only for alignment.
*/
const uint8_t VisionCrawlTable[23][30] = {
const DisplacementOf<int8_t> VisionCrawlTable[23][15] = {
// clang-format off
{ 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, 0 },
{ 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 1, 9, 1, 10, 1, 11, 1, 12, 1, 13, 1, 14, 1, 15, 1 },
{ 1, 0, 2, 0, 3, 0, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1, 10, 1, 11, 1, 12, 2, 13, 2, 14, 2, 15, 2 },
{ 1, 0, 2, 0, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 2, 9, 2, 10, 2, 11, 2, 12, 2, 13, 3, 14, 3, 15, 3 },
{ 1, 0, 2, 1, 3, 1, 4, 1, 5, 1, 6, 2, 7, 2, 8, 2, 9, 3, 10, 3, 11, 3, 12, 3, 13, 4, 14, 4, 0, 0 },
{ 1, 0, 2, 1, 3, 1, 4, 1, 5, 2, 6, 2, 7, 3, 8, 3, 9, 3, 10, 4, 11, 4, 12, 4, 13, 5, 14, 5, 0, 0 },
{ 1, 0, 2, 1, 3, 1, 4, 2, 5, 2, 6, 3, 7, 3, 8, 3, 9, 4, 10, 4, 11, 5, 12, 5, 13, 6, 14, 6, 0, 0 },
{ 1, 1, 2, 1, 3, 2, 4, 2, 5, 3, 6, 3, 7, 4, 8, 4, 9, 5, 10, 5, 11, 6, 12, 6, 13, 7, 0, 0, 0, 0 },
{ 1, 1, 2, 1, 3, 2, 4, 2, 5, 3, 6, 4, 7, 4, 8, 5, 9, 6, 10, 6, 11, 7, 12, 7, 12, 8, 13, 8, 0, 0 },
{ 1, 1, 2, 2, 3, 2, 4, 3, 5, 4, 6, 5, 7, 5, 8, 6, 9, 7, 10, 7, 10, 8, 11, 8, 12, 9, 0, 0, 0, 0 },
{ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 5, 7, 6, 8, 7, 9, 8, 10, 9, 11, 9, 11, 10, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 9, 11, 10, 11, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 5, 7, 6, 8, 7, 9, 7, 10, 8, 10, 8, 11, 9, 12, 0, 0, 0, 0 },
{ 1, 1, 1, 2, 2, 3, 2, 4, 3, 5, 4, 6, 4, 7, 5, 8, 6, 9, 6, 10, 7, 11, 7, 12, 8, 12, 8, 13, 0, 0 },
{ 1, 1, 1, 2, 2, 3, 2, 4, 3, 5, 3, 6, 4, 7, 4, 8, 5, 9, 5, 10, 6, 11, 6, 12, 7, 13, 0, 0, 0, 0 },
{ 0, 1, 1, 2, 1, 3, 2, 4, 2, 5, 3, 6, 3, 7, 3, 8, 4, 9, 4, 10, 5, 11, 5, 12, 6, 13, 6, 14, 0, 0 },
{ 0, 1, 1, 2, 1, 3, 1, 4, 2, 5, 2, 6, 3, 7, 3, 8, 3, 9, 4, 10, 4, 11, 4, 12, 5, 13, 5, 14, 0, 0 },
{ 0, 1, 1, 2, 1, 3, 1, 4, 1, 5, 2, 6, 2, 7, 2, 8, 3, 9, 3, 10, 3, 11, 3, 12, 4, 13, 4, 14, 0, 0 },
{ 0, 1, 0, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 2, 8, 2, 9, 2, 10, 2, 11, 2, 12, 3, 13, 3, 14, 3, 15 },
{ 0, 1, 0, 2, 0, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1, 10, 1, 11, 2, 12, 2, 13, 2, 14, 2, 15 },
{ 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 1, 8, 1, 9, 1, 10, 1, 11, 1, 12, 1, 13, 1, 14, 1, 15 },
{ 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15 },
{ { 1, 0 }, { 2, 0 }, { 3, 0 }, { 4, 0 }, { 5, 0 }, { 6, 0 }, { 7, 0 }, { 8, 0 }, { 9, 0 }, { 10, 0 }, { 11, 0 }, { 12, 0 }, { 13, 0 }, { 14, 0 }, { 15, 0 } },
{ { 1, 0 }, { 2, 0 }, { 3, 0 }, { 4, 0 }, { 5, 0 }, { 6, 0 }, { 7, 0 }, { 8, 1 }, { 9, 1 }, { 10, 1 }, { 11, 1 }, { 12, 1 }, { 13, 1 }, { 14, 1 }, { 15, 1 } },
{ { 1, 0 }, { 2, 0 }, { 3, 0 }, { 4, 1 }, { 5, 1 }, { 6, 1 }, { 7, 1 }, { 8, 1 }, { 9, 1 }, { 10, 1 }, { 11, 1 }, { 12, 2 }, { 13, 2 }, { 14, 2 }, { 15, 2 } },
{ { 1, 0 }, { 2, 0 }, { 3, 1 }, { 4, 1 }, { 5, 1 }, { 6, 1 }, { 7, 1 }, { 8, 2 }, { 9, 2 }, { 10, 2 }, { 11, 2 }, { 12, 2 }, { 13, 3 }, { 14, 3 }, { 15, 3 } },
{ { 1, 0 }, { 2, 1 }, { 3, 1 }, { 4, 1 }, { 5, 1 }, { 6, 2 }, { 7, 2 }, { 8, 2 }, { 9, 3 }, { 10, 3 }, { 11, 3 }, { 12, 3 }, { 13, 4 }, { 14, 4 }, { 0, 0 } },
{ { 1, 0 }, { 2, 1 }, { 3, 1 }, { 4, 1 }, { 5, 2 }, { 6, 2 }, { 7, 3 }, { 8, 3 }, { 9, 3 }, { 10, 4 }, { 11, 4 }, { 12, 4 }, { 13, 5 }, { 14, 5 }, { 0, 0 } },
{ { 1, 0 }, { 2, 1 }, { 3, 1 }, { 4, 2 }, { 5, 2 }, { 6, 3 }, { 7, 3 }, { 8, 3 }, { 9, 4 }, { 10, 4 }, { 11, 5 }, { 12, 5 }, { 13, 6 }, { 14, 6 }, { 0, 0 } },
{ { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 2 }, { 5, 3 }, { 6, 3 }, { 7, 4 }, { 8, 4 }, { 9, 5 }, { 10, 5 }, { 11, 6 }, { 12, 6 }, { 13, 7 }, { 0, 0 }, { 0, 0 } },
{ { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 2 }, { 5, 3 }, { 6, 4 }, { 7, 4 }, { 8, 5 }, { 9, 6 }, { 10, 6 }, { 11, 7 }, { 12, 7 }, { 12, 8 }, { 13, 8 }, { 0, 0 } },
{ { 1, 1 }, { 2, 2 }, { 3, 2 }, { 4, 3 }, { 5, 4 }, { 6, 5 }, { 7, 5 }, { 8, 6 }, { 9, 7 }, { 10, 7 }, { 10, 8 }, { 11, 8 }, { 12, 9 }, { 0, 0 }, { 0, 0 } },
{ { 1, 1 }, { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 5 }, { 7, 6 }, { 8, 7 }, { 9, 8 }, { 10, 9 }, { 11, 9 }, { 11, 10 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
{ { 1, 1 }, { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 6 }, { 7, 7 }, { 8, 8 }, { 9, 9 }, { 10, 10 }, { 11, 11 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
{ { 1, 1 }, { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 }, { 8, 9 }, { 9, 10 }, { 9, 11 }, { 10, 11 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
{ { 1, 1 }, { 2, 2 }, { 2, 3 }, { 3, 4 }, { 4, 5 }, { 5, 6 }, { 5, 7 }, { 6, 8 }, { 7, 9 }, { 7, 10 }, { 8, 10 }, { 8, 11 }, { 9, 12 }, { 0, 0 }, { 0, 0 } },
{ { 1, 1 }, { 1, 2 }, { 2, 3 }, { 2, 4 }, { 3, 5 }, { 4, 6 }, { 4, 7 }, { 5, 8 }, { 6, 9 }, { 6, 10 }, { 7, 11 }, { 7, 12 }, { 8, 12 }, { 8, 13 }, { 0, 0 } },
{ { 1, 1 }, { 1, 2 }, { 2, 3 }, { 2, 4 }, { 3, 5 }, { 3, 6 }, { 4, 7 }, { 4, 8 }, { 5, 9 }, { 5, 10 }, { 6, 11 }, { 6, 12 }, { 7, 13 }, { 0, 0 }, { 0, 0 } },
{ { 0, 1 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 2, 5 }, { 3, 6 }, { 3, 7 }, { 3, 8 }, { 4, 9 }, { 4, 10 }, { 5, 11 }, { 5, 12 }, { 6, 13 }, { 6, 14 }, { 0, 0 } },
{ { 0, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 2, 5 }, { 2, 6 }, { 3, 7 }, { 3, 8 }, { 3, 9 }, { 4, 10 }, { 4, 11 }, { 4, 12 }, { 5, 13 }, { 5, 14 }, { 0, 0 } },
{ { 0, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 2, 6 }, { 2, 7 }, { 2, 8 }, { 3, 9 }, { 3, 10 }, { 3, 11 }, { 3, 12 }, { 4, 13 }, { 4, 14 }, { 0, 0 } },
{ { 0, 1 }, { 0, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 6 }, { 1, 7 }, { 2, 8 }, { 2, 9 }, { 2, 10 }, { 2, 11 }, { 2, 12 }, { 3, 13 }, { 3, 14 }, { 3, 15 } },
{ { 0, 1 }, { 0, 2 }, { 0, 3 }, { 1, 4 }, { 1, 5 }, { 1, 6 }, { 1, 7 }, { 1, 8 }, { 1, 9 }, { 1, 10 }, { 1, 11 }, { 2, 12 }, { 2, 13 }, { 2, 14 }, { 2, 15 } },
{ { 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, { 0, 6 }, { 0, 7 }, { 1, 8 }, { 1, 9 }, { 1, 10 }, { 1, 11 }, { 1, 12 }, { 1, 13 }, { 1, 14 }, { 1, 15 } },
{ { 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, { 0, 6 }, { 0, 7 }, { 0, 8 }, { 0, 9 }, { 0, 10 }, { 0, 11 }, { 0, 12 }, { 0, 13 }, { 0, 14 }, { 0, 15 } },
// clang-format on
};
@ -155,6 +155,25 @@ bool CrawlFlipsXY(Displacement mirrored, tl::function_ref<bool(Displacement)> fu
return true;
}
bool TileAllowsLight(Point position)
{
if (!InDungeonBounds(position))
return false;
return !TileHasAny(dPiece[position.x][position.y], TileProperties::BlockLight);
}
void DoVisionFlags(Point position, MapExplorationType doAutomap, bool visible)
{
if (doAutomap != MAP_EXP_NONE) {
if (dFlags[position.x][position.y] != DungeonFlag::None)
SetAutomapView(position, doAutomap);
dFlags[position.x][position.y] |= DungeonFlag::Explored;
}
if (visible)
dFlags[position.x][position.y] |= DungeonFlag::Lit;
dFlags[position.x][position.y] |= DungeonFlag::Visible;
}
} // namespace
bool DoCrawl(unsigned radius, tl::function_ref<bool(Displacement)> function)
@ -278,90 +297,37 @@ void DoUnVision(Point position, int nRadius)
}
}
void DoVision(Point position, int nRadius, MapExplorationType doautomap, bool visible)
void DoVision(Point position, int radius, MapExplorationType doAutomap, bool visible)
{
if (InDungeonBounds(position)) {
if (doautomap != MAP_EXP_NONE) {
if (dFlags[position.x][position.y] != DungeonFlag::None) {
SetAutomapView(position, doautomap);
}
dFlags[position.x][position.y] |= DungeonFlag::Explored;
}
if (visible) {
dFlags[position.x][position.y] |= DungeonFlag::Lit;
}
dFlags[position.x][position.y] |= DungeonFlag::Visible;
}
DoVisionFlags(position, doAutomap, visible);
for (int v = 0; v < 4; v++) {
static const Displacement factors[] = { { 1, 1 }, { -1, 1 }, { 1, -1 }, { -1, -1 } };
for (auto factor : factors) {
for (int j = 0; j < 23; j++) {
bool nBlockerFlag = false;
int nLineLen = 2 * (nRadius - RadiusAdj[j]);
for (int k = 0; k < nLineLen && !nBlockerFlag; k += 2) {
int x1adj = 0;
int x2adj = 0;
int y1adj = 0;
int y2adj = 0;
int nCrawlX = 0;
int nCrawlY = 0;
switch (v) {
case 0:
nCrawlX = position.x + VisionCrawlTable[j][k];
nCrawlY = position.y + VisionCrawlTable[j][k + 1];
if (VisionCrawlTable[j][k] > 0 && VisionCrawlTable[j][k + 1] > 0) {
x1adj = -1;
y2adj = -1;
}
break;
case 1:
nCrawlX = position.x - VisionCrawlTable[j][k];
nCrawlY = position.y - VisionCrawlTable[j][k + 1];
if (VisionCrawlTable[j][k] > 0 && VisionCrawlTable[j][k + 1] > 0) {
y1adj = 1;
x2adj = 1;
}
int lineLen = radius - RadiusAdj[j];
for (int k = 0; k < lineLen; k++) {
Point crawl = position + VisionCrawlTable[j][k] * factor;
if (!InDungeonBounds(crawl))
break;
case 2:
nCrawlX = position.x + VisionCrawlTable[j][k];
nCrawlY = position.y - VisionCrawlTable[j][k + 1];
if (VisionCrawlTable[j][k] > 0 && VisionCrawlTable[j][k + 1] > 0) {
x1adj = -1;
y2adj = 1;
}
bool blockerFlag = TileHasAny(dPiece[crawl.x][crawl.y], TileProperties::BlockLight);
bool tileOK = !blockerFlag;
if (VisionCrawlTable[j][k].deltaX > 0 && VisionCrawlTable[j][k].deltaY > 0) {
tileOK = tileOK || TileAllowsLight(crawl + Displacement { -factor.deltaX, 0 });
tileOK = tileOK || TileAllowsLight(crawl + Displacement { 0, -factor.deltaY });
}
if (!tileOK)
break;
case 3:
nCrawlX = position.x - VisionCrawlTable[j][k];
nCrawlY = position.y + VisionCrawlTable[j][k + 1];
if (VisionCrawlTable[j][k] > 0 && VisionCrawlTable[j][k + 1] > 0) {
y1adj = -1;
x2adj = 1;
}
DoVisionFlags(crawl, doAutomap, visible);
if (blockerFlag)
break;
}
if (InDungeonBounds({ nCrawlX, nCrawlY })) {
nBlockerFlag = TileHasAny(dPiece[nCrawlX][nCrawlY], TileProperties::BlockLight);
if ((InDungeonBounds({ x1adj + nCrawlX, y1adj + nCrawlY })
&& !TileHasAny(dPiece[x1adj + nCrawlX][y1adj + nCrawlY], TileProperties::BlockLight))
|| (InDungeonBounds({ x2adj + nCrawlX, y2adj + nCrawlY })
&& !TileHasAny(dPiece[x2adj + nCrawlX][y2adj + nCrawlY], TileProperties::BlockLight))) {
if (doautomap != MAP_EXP_NONE) {
if (dFlags[nCrawlX][nCrawlY] != DungeonFlag::None) {
SetAutomapView({ nCrawlX, nCrawlY }, doautomap);
}
dFlags[nCrawlX][nCrawlY] |= DungeonFlag::Explored;
}
if (visible) {
dFlags[nCrawlX][nCrawlY] |= DungeonFlag::Lit;
}
dFlags[nCrawlX][nCrawlY] |= DungeonFlag::Visible;
if (!nBlockerFlag) {
int8_t nTrans = dTransVal[nCrawlX][nCrawlY];
if (nTrans != 0) {
TransList[nTrans] = true;
}
}
}
}
int8_t trans = dTransVal[crawl.x][crawl.y];
if (trans != 0)
TransList[trans] = true;
}
}
}

4
Source/lighting.h

@ -56,7 +56,7 @@ extern bool UpdateLighting;
void DoLighting(Point position, int nRadius, int Lnum);
void DoUnVision(Point position, int nRadius);
void DoVision(Point position, int nRadius, MapExplorationType doautomap, bool visible);
void DoVision(Point position, int radius, MapExplorationType doAutomap, bool visible);
void MakeLightTable();
#ifdef _DEBUG
void ToggleLighting();
@ -128,6 +128,4 @@ auto Crawl(unsigned minRadius, unsigned maxRadius, F function) -> invoke_result_
return result;
}
/* rdata */
} // namespace devilution

Loading…
Cancel
Save