From efc46f3fab9675f9e0c265e11f0f1d7e2c07fd68 Mon Sep 17 00:00:00 2001 From: Roman Penyaev Date: Tue, 22 Apr 2025 03:23:52 +0200 Subject: [PATCH] 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 --- Source/lighting.cpp | 40 +++++++++++++++++++++++++++++++--------- Source/lighting.h | 6 ++++++ 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/Source/lighting.cpp b/Source/lighting.cpp index dccd45bd8..aa794ab26 100644 --- a/Source/lighting.cpp +++ b/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 markVisibleFn, + tl::function_ref markTransparentFn, + tl::function_ref passesLightFn, + tl::function_ref 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 LoadTrns() { RETURN_IF_ERROR(LoadFileInMemWithStatus("plrgfx\\infra.trn", InfravisionTable)); diff --git a/Source/lighting.h b/Source/lighting.h index 2a0de57ad..eb4fb9816 100644 --- a/Source/lighting.h +++ b/Source/lighting.h @@ -9,6 +9,7 @@ #include #include +#include #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 offset); void DoUnVision(Point position, uint8_t radius); +void DoVision(Point position, uint8_t radius, + tl::function_ref markVisibleFn, + tl::function_ref markTransparentFn, + tl::function_ref passesLightFn, + tl::function_ref inBoundsFn); void DoVision(Point position, uint8_t radius, MapExplorationType doAutomap, bool visible); tl::expected LoadTrns(); void MakeLightTable();