Browse Source

lighting: make `DoVision()` more generic

This change does not have any functional impact. Instead, it separates
dungeon-dependent data from the vision algorithm, making the
`DoVision()` function suitable to be called from the test case, which
comes next.

Signed-off-by: Roman Penyaev <r.peniaev@gmail.com>
pull/7665/head
Roman Penyaev 12 months ago committed by Anders Jenbo
parent
commit
efc46f3fab
  1. 40
      Source/lighting.cpp
  2. 6
      Source/lighting.h

40
Source/lighting.cpp

@ -230,9 +230,13 @@ void DoUnVision(Point position, uint8_t radius)
}
}
void DoVision(Point position, uint8_t radius, MapExplorationType doAutomap, bool visible)
void DoVision(Point position, uint8_t radius,
tl::function_ref<void(Point)> markVisibleFn,
tl::function_ref<void(Point)> markTransparentFn,
tl::function_ref<bool(Point)> passesLightFn,
tl::function_ref<bool(Point)> inBoundsFn)
{
DoVisionFlags(position, doAutomap, visible);
markVisibleFn(position);
// Adjustment to a ray length to ensure all rays lie on an
// accurate circle
@ -251,7 +255,7 @@ void DoVision(Point position, uint8_t radius, MapExplorationType doAutomap, bool
const auto &relRayPoint = VisionRays[j][k];
// Calculate the next point on a ray in the quadrant
Point rayPoint = position + relRayPoint * quadrant;
if (!InDungeonBounds(rayPoint))
if (!inBoundsFn(rayPoint))
break;
// We've cast an approximated ray on an integer 2D
@ -280,28 +284,46 @@ void DoVision(Point position, uint8_t radius, MapExplorationType doAutomap, bool
Displacement adjacent1 = { -quadrant.deltaX, 0 };
Displacement adjacent2 = { 0, -quadrant.deltaY };
bool passesLight = (TileAllowsLight(rayPoint + adjacent1) || TileAllowsLight(rayPoint + adjacent2));
bool passesLight = (passesLightFn(rayPoint + adjacent1) || passesLightFn(rayPoint + adjacent2));
if (!passesLight)
// Diagonally adjacent tiles do not pass the
// light further, we are done with this ray
break;
}
DoVisionFlags(rayPoint, doAutomap, visible);
markVisibleFn(rayPoint);
bool passesLight = TileAllowsLight(rayPoint);
bool passesLight = passesLightFn(rayPoint);
if (!passesLight)
// Tile does not pass the light further, we are
// done with this ray
break;
int8_t trans = dTransVal[rayPoint.x][rayPoint.y];
if (trans != 0)
TransList[trans] = true;
markTransparentFn(rayPoint);
}
}
}
}
void DoVision(Point position, uint8_t radius, MapExplorationType doAutomap, bool visible)
{
auto markVisibleFn = [doAutomap, visible](Point rayPoint) {
DoVisionFlags(rayPoint, doAutomap, visible);
};
auto markTransparentFn = [](Point rayPoint) {
int8_t trans = dTransVal[rayPoint.x][rayPoint.y];
if (trans != 0)
TransList[trans] = true;
};
auto passesLightFn = [](Point rayPoint) {
return TileAllowsLight(rayPoint);
};
auto inBoundsFn = [](Point rayPoint) {
return InDungeonBounds(rayPoint);
};
DoVision(position, radius, markVisibleFn, markTransparentFn, passesLightFn, inBoundsFn);
}
tl::expected<void, std::string> LoadTrns()
{
RETURN_IF_ERROR(LoadFileInMemWithStatus("plrgfx\\infra.trn", InfravisionTable));

6
Source/lighting.h

@ -9,6 +9,7 @@
#include <cstdint>
#include <expected.hpp>
#include <function_ref.hpp>
#include "automap.h"
#include "engine/displacement.hpp"
@ -62,6 +63,11 @@ extern bool UpdateLighting;
void DoUnLight(Point position, uint8_t radius);
void DoLighting(Point position, uint8_t radius, DisplacementOf<int8_t> offset);
void DoUnVision(Point position, uint8_t radius);
void DoVision(Point position, uint8_t radius,
tl::function_ref<void(Point)> markVisibleFn,
tl::function_ref<void(Point)> markTransparentFn,
tl::function_ref<bool(Point)> passesLightFn,
tl::function_ref<bool(Point)> inBoundsFn);
void DoVision(Point position, uint8_t radius, MapExplorationType doAutomap, bool visible);
tl::expected<void, std::string> LoadTrns();
void MakeLightTable();

Loading…
Cancel
Save