diff --git a/Source/automap.cpp b/Source/automap.cpp index f3c97bc85..055abdf86 100644 --- a/Source/automap.cpp +++ b/Source/automap.cpp @@ -96,47 +96,47 @@ void DrawDiamond(const Surface &out, Point center, uint8_t color) DrawMapLineNE(out, bottom, AmLine8, color); } -void DrawMapVerticalDoor(const Surface &out, Point center) +void DrawMapVerticalDoor(const Surface &out, Point center, uint8_t colorBright, uint8_t colorDim) { - DrawMapLineNE(out, { center.x + AmLine8, center.y - AmLine4 }, AmLine4, MapColorsDim); - DrawMapLineNE(out, { center.x - AmLine16, center.y + AmLine8 }, AmLine4, MapColorsDim); - DrawDiamond(out, center, MapColorsBright); + DrawMapLineNE(out, { center.x + AmLine8, center.y - AmLine4 }, AmLine4, colorDim); + DrawMapLineNE(out, { center.x - AmLine16, center.y + AmLine8 }, AmLine4, colorDim); + DrawDiamond(out, center, colorBright); } -void DrawMapHorizontalDoor(const Surface &out, Point center) +void DrawMapHorizontalDoor(const Surface &out, Point center, uint8_t colorBright, uint8_t colorDim) { - DrawMapLineSE(out, { center.x - AmLine16, center.y - AmLine8 }, AmLine4, MapColorsDim); - DrawMapLineSE(out, { center.x + AmLine8, center.y + AmLine4 }, AmLine4, MapColorsDim); - DrawDiamond(out, center, MapColorsBright); + DrawMapLineSE(out, { center.x - AmLine16, center.y - AmLine8 }, AmLine4, colorDim); + DrawMapLineSE(out, { center.x + AmLine8, center.y + AmLine4 }, AmLine4, colorDim); + DrawDiamond(out, center, colorBright); } -void DrawDirt(const Surface &out, Point center) +void DrawDirt(const Surface &out, Point center, uint8_t color) { - out.SetPixel(center, MapColorsDim); - out.SetPixel({ center.x - AmLine8, center.y - AmLine4 }, MapColorsDim); - out.SetPixel({ center.x - AmLine8, center.y + AmLine4 }, MapColorsDim); - out.SetPixel({ center.x + AmLine8, center.y - AmLine4 }, MapColorsDim); - out.SetPixel({ center.x + AmLine8, center.y + AmLine4 }, MapColorsDim); - out.SetPixel({ center.x - AmLine16, center.y }, MapColorsDim); - out.SetPixel({ center.x + AmLine16, center.y }, MapColorsDim); - out.SetPixel({ center.x, center.y - AmLine8 }, MapColorsDim); - out.SetPixel({ center.x, center.y + AmLine8 }, MapColorsDim); - out.SetPixel({ center.x + AmLine8 - AmLine32, center.y + AmLine4 }, MapColorsDim); - out.SetPixel({ center.x - AmLine8 + AmLine32, center.y + AmLine4 }, MapColorsDim); - out.SetPixel({ center.x - AmLine16, center.y + AmLine8 }, MapColorsDim); - out.SetPixel({ center.x + AmLine16, center.y + AmLine8 }, MapColorsDim); - out.SetPixel({ center.x - AmLine8, center.y + AmLine16 - AmLine4 }, MapColorsDim); - out.SetPixel({ center.x + AmLine8, center.y + AmLine16 - AmLine4 }, MapColorsDim); - out.SetPixel({ center.x, center.y + AmLine16 }, MapColorsDim); + out.SetPixel(center, color); + out.SetPixel({ center.x - AmLine8, center.y - AmLine4 }, color); + out.SetPixel({ center.x - AmLine8, center.y + AmLine4 }, color); + out.SetPixel({ center.x + AmLine8, center.y - AmLine4 }, color); + out.SetPixel({ center.x + AmLine8, center.y + AmLine4 }, color); + out.SetPixel({ center.x - AmLine16, center.y }, color); + out.SetPixel({ center.x + AmLine16, center.y }, color); + out.SetPixel({ center.x, center.y - AmLine8 }, color); + out.SetPixel({ center.x, center.y + AmLine8 }, color); + out.SetPixel({ center.x + AmLine8 - AmLine32, center.y + AmLine4 }, color); + out.SetPixel({ center.x - AmLine8 + AmLine32, center.y + AmLine4 }, color); + out.SetPixel({ center.x - AmLine16, center.y + AmLine8 }, color); + out.SetPixel({ center.x + AmLine16, center.y + AmLine8 }, color); + out.SetPixel({ center.x - AmLine8, center.y + AmLine16 - AmLine4 }, color); + out.SetPixel({ center.x + AmLine8, center.y + AmLine16 - AmLine4 }, color); + out.SetPixel({ center.x, center.y + AmLine16 }, color); } -void DrawStairs(const Surface &out, Point center) +void DrawStairs(const Surface &out, Point center, uint8_t color) { constexpr int NumStairSteps = 4; const Displacement offset = { -AmLine8, AmLine4 }; Point p = { center.x - AmLine8, center.y - AmLine8 - AmLine4 }; for (int i = 0; i < NumStairSteps; ++i) { - DrawMapLineSE(out, p, AmLine16, MapColorsBright); + DrawMapLineSE(out, p, AmLine16, color); p += offset; } } @@ -144,113 +144,198 @@ void DrawStairs(const Surface &out, Point center) /** * Left-facing obstacle */ -void DrawHorizontal(const Surface &out, Point center, AutomapTile tile) +void DrawHorizontal(const Surface &out, Point center, AutomapTile tile, uint8_t colorBright, uint8_t colorDim) { if (!tile.HasFlag(AutomapTile::Flags::HorizontalPassage)) { - DrawMapLineSE(out, { center.x, center.y - AmLine16 }, AmLine16, MapColorsDim); + DrawMapLineSE(out, { center.x, center.y - AmLine16 }, AmLine16, colorDim); return; } if (tile.HasFlag(AutomapTile::Flags::HorizontalDoor)) { - DrawMapHorizontalDoor(out, { center.x + AmLine16, center.y - AmLine8 }); + DrawMapHorizontalDoor(out, { center.x + AmLine16, center.y - AmLine8 }, colorBright, colorDim); } if (tile.HasFlag(AutomapTile::Flags::HorizontalGrate)) { - DrawMapLineSE(out, { center.x + AmLine16, center.y - AmLine8 }, AmLine8, MapColorsDim); - DrawDiamond(out, { center.x, center.y - AmLine8 }, MapColorsDim); + DrawMapLineSE(out, { center.x + AmLine16, center.y - AmLine8 }, AmLine8, colorDim); + DrawDiamond(out, { center.x, center.y - AmLine8 }, colorDim); } else if (tile.HasFlag(AutomapTile::Flags::HorizontalArch)) { - DrawDiamond(out, { center.x, center.y - AmLine8 }, MapColorsDim); + DrawDiamond(out, { center.x, center.y - AmLine8 }, colorDim); } } /** * Right-facing obstacle */ -void DrawVertical(const Surface &out, Point center, AutomapTile tile) +void DrawVertical(const Surface &out, Point center, AutomapTile tile, uint8_t colorBright, uint8_t colorDim) { if (!tile.HasFlag(AutomapTile::Flags::VerticalPassage)) { - DrawMapLineNE(out, { center.x - AmLine32, center.y }, AmLine16, MapColorsDim); + DrawMapLineNE(out, { center.x - AmLine32, center.y }, AmLine16, colorDim); return; } if (tile.HasFlag(AutomapTile::Flags::VerticalDoor)) { // two wall segments with a door in the middle - DrawMapVerticalDoor(out, { center.x - AmLine16, center.y - AmLine8 }); + DrawMapVerticalDoor(out, { center.x - AmLine16, center.y - AmLine8 }, colorBright, colorDim); } if (tile.HasFlag(AutomapTile::Flags::VerticalGrate)) { // right-facing half-wall - DrawMapLineNE(out, { center.x - AmLine32, center.y }, AmLine8, MapColorsDim); - DrawDiamond(out, { center.x, center.y - AmLine8 }, MapColorsDim); + DrawMapLineNE(out, { center.x - AmLine32, center.y }, AmLine8, colorDim); + DrawDiamond(out, { center.x, center.y - AmLine8 }, colorDim); } else if (tile.HasFlag(AutomapTile::Flags::VerticalArch)) { // window or passable column - DrawDiamond(out, { center.x, center.y - AmLine8 }, MapColorsDim); + DrawDiamond(out, { center.x, center.y - AmLine8 }, colorDim); } } /** * For caves the horizontal/vertical flags are swapped */ -void DrawCaveHorizontal(const Surface &out, Point center, AutomapTile tile) +void DrawCaveHorizontal(const Surface &out, Point center, AutomapTile tile, uint8_t colorBright, uint8_t colorDim) { if (tile.HasFlag(AutomapTile::Flags::VerticalDoor)) { - DrawMapHorizontalDoor(out, { center.x - AmLine16, center.y + AmLine8 }); + DrawMapHorizontalDoor(out, { center.x - AmLine16, center.y + AmLine8 }, colorBright, colorDim); } else { - DrawMapLineSE(out, { center.x - AmLine32, center.y }, AmLine16, MapColorsDim); + DrawMapLineSE(out, { center.x - AmLine32, center.y }, AmLine16, colorDim); } } /** * For caves the horizontal/vertical flags are swapped */ -void DrawCaveVertical(const Surface &out, Point center, AutomapTile tile) +void DrawCaveVertical(const Surface &out, Point center, AutomapTile tile, uint8_t colorBright, uint8_t colorDim) { if (tile.HasFlag(AutomapTile::Flags::HorizontalDoor)) { - DrawMapVerticalDoor(out, { center.x + AmLine16, center.y + AmLine8 }); + DrawMapVerticalDoor(out, { center.x + AmLine16, center.y + AmLine8 }, colorBright, colorDim); } else { - DrawMapLineNE(out, { center.x, center.y + AmLine16 }, AmLine16, MapColorsDim); + DrawMapLineNE(out, { center.x, center.y + AmLine16 }, AmLine16, colorDim); } } +/** + * @brief Check if a given tile has the provided AutomapTile flag + */ +bool HasAutomapFlag(Point position, AutomapTile::Flags type) +{ + if (position.x < 0 || position.x >= DMAXX || position.y < 0 || position.y >= DMAXX) { + return false; + } + + return AutomapTypeTiles[dungeon[position.x][position.y]].HasFlag(type); +} + +/** + * @brief Returns the automap shape at the given coordinate. + */ +AutomapTile GetAutomapType(Point position) +{ + if (position.x < 0 || position.x >= DMAXX || position.y < 0 || position.y >= DMAXX) { + return {}; + } + + AutomapTile tile = AutomapTypeTiles[dungeon[position.x][position.y]]; + if (tile.type == AutomapTile::Types::Corner) { + if (HasAutomapFlag({ position.x - 1, position.y }, AutomapTile::Flags::HorizontalArch)) { + if (HasAutomapFlag({ position.x, position.y - 1 }, AutomapTile::Flags::VerticalArch)) { + tile.type = AutomapTile::Types::Diamond; + } + } + } + + return tile; +} + +/** + * @brief Returns the automap shape at the given coordinate. + */ +AutomapTile GetAutomapTypeView(Point map) +{ + if (map.x == -1 && map.y >= 0 && map.y < DMAXY && AutomapView[0][map.y] != MAP_EXP_NONE) { + if (HasAutomapFlag({ 0, map.y + 1 }, AutomapTile::Flags::Dirt) && HasAutomapFlag({ 0, map.y }, AutomapTile::Flags::Dirt) && HasAutomapFlag({ 0, map.y - 1 }, AutomapTile::Flags::Dirt)) { + return {}; + } + return { AutomapTile::Types::None, AutomapTile::Flags::Dirt }; + } + + if (map.y == -1 && map.x >= 0 && map.x < DMAXY && AutomapView[map.x][0] != MAP_EXP_NONE) { + if (HasAutomapFlag({ map.x + 1, 0 }, AutomapTile::Flags::Dirt) && HasAutomapFlag({ map.x, 0 }, AutomapTile::Flags::Dirt) && HasAutomapFlag({ map.x - 1, 0 }, AutomapTile::Flags::Dirt)) { + return {}; + } + return { AutomapTile::Types::None, AutomapTile::Flags::Dirt }; + } + + if (map.x < 0 || map.x >= DMAXX) { + return {}; + } + if (map.y < 0 || map.y >= DMAXX) { + return {}; + } + if (AutomapView[map.x][map.y] == MAP_EXP_NONE) { + return {}; + } + + return GetAutomapType(map); +} + /** * @brief Renders the given automap shape at the specified screen coordinates. */ -void DrawAutomapTile(const Surface &out, Point center, AutomapTile tile) +void DrawAutomapTile(const Surface &out, Point center, Point map) { + AutomapTile tile = GetAutomapTypeView(map); + uint8_t colorBright = MapColorsBright; + uint8_t colorDim = MapColorsDim; + MapExplorationType explorationType = static_cast(AutomapView[map.x][map.y]); + + switch (explorationType) { + case MAP_EXP_SHRINE: + colorDim = PAL16_GRAY + 11; + colorBright = PAL16_GRAY + 9; + break; + case MAP_EXP_OTHERS: + colorDim = PAL16_YELLOW + 11; + colorBright = PAL16_YELLOW + 9; + break; + case MAP_EXP_SELF: + case MAP_EXP_NONE: + case MAP_EXP_OLD: + break; + } + if (tile.HasFlag(AutomapTile::Flags::Dirt)) { - DrawDirt(out, center); + DrawDirt(out, center, colorDim); } if (tile.HasFlag(AutomapTile::Flags::Stairs)) { - DrawStairs(out, center); + DrawStairs(out, center, colorBright); } switch (tile.type) { case AutomapTile::Types::Diamond: // stand-alone column or other unpassable object - DrawDiamond(out, { center.x, center.y - AmLine8 }, MapColorsDim); + DrawDiamond(out, { center.x, center.y - AmLine8 }, colorDim); break; case AutomapTile::Types::Vertical: case AutomapTile::Types::FenceVertical: - DrawVertical(out, center, tile); + DrawVertical(out, center, tile, colorBright, colorDim); break; case AutomapTile::Types::Horizontal: case AutomapTile::Types::FenceHorizontal: - DrawHorizontal(out, center, tile); + DrawHorizontal(out, center, tile, colorBright, colorDim); break; case AutomapTile::Types::Cross: - DrawVertical(out, center, tile); - DrawHorizontal(out, center, tile); + DrawVertical(out, center, tile, colorBright, colorDim); + DrawHorizontal(out, center, tile, colorBright, colorDim); break; case AutomapTile::Types::CaveHorizontalCross: - DrawVertical(out, center, tile); - DrawCaveHorizontal(out, center, tile); + DrawVertical(out, center, tile, colorBright, colorDim); + DrawCaveHorizontal(out, center, tile, colorBright, colorDim); break; case AutomapTile::Types::CaveVerticalCross: - DrawHorizontal(out, center, tile); - DrawCaveVertical(out, center, tile); + DrawHorizontal(out, center, tile, colorBright, colorDim); + DrawCaveVertical(out, center, tile, colorBright, colorDim); break; case AutomapTile::Types::CaveHorizontal: - DrawCaveHorizontal(out, center, tile); + DrawCaveHorizontal(out, center, tile, colorBright, colorDim); break; case AutomapTile::Types::CaveVertical: - DrawCaveVertical(out, center, tile); + DrawCaveVertical(out, center, tile, colorBright, colorDim); break; case AutomapTile::Types::CaveCross: - DrawCaveHorizontal(out, center, tile); - DrawCaveVertical(out, center, tile); + DrawCaveHorizontal(out, center, tile, colorBright, colorDim); + DrawCaveVertical(out, center, tile, colorBright, colorDim); break; case AutomapTile::Types::Corner: case AutomapTile::Types::None: @@ -386,71 +471,6 @@ void DrawAutomapPlr(const Surface &out, const Displacement &myPlayerOffset, int } } -/** - * @brief Check if a given tile has the provided AutomapTile flag - */ -bool HasAutomapFlag(Point position, AutomapTile::Flags type) -{ - if (position.x < 0 || position.x >= DMAXX || position.y < 0 || position.y >= DMAXX) { - return false; - } - - return AutomapTypeTiles[dungeon[position.x][position.y]].HasFlag(type); -} - -/** - * @brief Returns the automap shape at the given coordinate. - */ -AutomapTile GetAutomapType(Point position) -{ - if (position.x < 0 || position.x >= DMAXX || position.y < 0 || position.y >= DMAXX) { - return {}; - } - - AutomapTile tile = AutomapTypeTiles[dungeon[position.x][position.y]]; - if (tile.type == AutomapTile::Types::Corner) { - if (HasAutomapFlag({ position.x - 1, position.y }, AutomapTile::Flags::HorizontalArch)) { - if (HasAutomapFlag({ position.x, position.y - 1 }, AutomapTile::Flags::VerticalArch)) { - tile.type = AutomapTile::Types::Diamond; - } - } - } - - return tile; -} - -/** - * @brief Returns the automap shape at the given coordinate. - */ -AutomapTile GetAutomapTypeView(Point map) -{ - if (map.x == -1 && map.y >= 0 && map.y < DMAXY && AutomapView[0][map.y]) { - if (HasAutomapFlag({ 0, map.y + 1 }, AutomapTile::Flags::Dirt) && HasAutomapFlag({ 0, map.y }, AutomapTile::Flags::Dirt) && HasAutomapFlag({ 0, map.y - 1 }, AutomapTile::Flags::Dirt)) { - return {}; - } - return { AutomapTile::Types::None, AutomapTile::Flags::Dirt }; - } - - if (map.y == -1 && map.x >= 0 && map.x < DMAXY && AutomapView[map.x][0]) { - if (HasAutomapFlag({ map.x + 1, 0 }, AutomapTile::Flags::Dirt) && HasAutomapFlag({ map.x, 0 }, AutomapTile::Flags::Dirt) && HasAutomapFlag({ map.x - 1, 0 }, AutomapTile::Flags::Dirt)) { - return {}; - } - return { AutomapTile::Types::None, AutomapTile::Flags::Dirt }; - } - - if (map.x < 0 || map.x >= DMAXX) { - return {}; - } - if (map.y < 0 || map.y >= DMAXX) { - return {}; - } - if (!AutomapView[map.x][map.y]) { - return {}; - } - - return GetAutomapType(map); -} - /** * @brief Renders game info, such as the name of the current level, and in multi player the name of the game and the game password. */ @@ -515,7 +535,7 @@ std::unique_ptr LoadAutomapData(size_t &tileCount) } // namespace bool AutomapActive; -bool AutomapView[DMAXX][DMAXY]; +uint8_t AutomapView[DMAXX][DMAXY]; int AutoMapScale; Displacement AutomapOffset; int AmLine64; @@ -677,14 +697,14 @@ void DrawAutomap(const Surface &out) for (int i = 0; i <= cells + 1; i++) { Point tile1 = screen; for (int j = 0; j < cells; j++) { - DrawAutomapTile(out, tile1, GetAutomapTypeView({ map.x + j, map.y - j })); + DrawAutomapTile(out, tile1, { map.x + j, map.y - j }); tile1.x += AmLine64; } map.y++; Point tile2 { screen.x - AmLine32, screen.y + AmLine16 }; for (int j = 0; j <= cells; j++) { - DrawAutomapTile(out, tile2, GetAutomapTypeView({ map.x + j, map.y - j })); + DrawAutomapTile(out, tile2, { map.x + j, map.y - j }); tile2.x += AmLine64; } map.x++; @@ -704,7 +724,13 @@ void DrawAutomap(const Surface &out) DrawAutomapText(out); } -void SetAutomapView(Point position) +void UpdateAutomapExplorer(Point map, MapExplorationType explorer) +{ + if (AutomapView[map.x][map.y] < explorer) + AutomapView[map.x][map.y] = explorer; +} + +void SetAutomapView(Point position, MapExplorationType explorer) { const Point map { (position.x - 16) / 2, (position.y - 16) / 2 }; @@ -712,7 +738,7 @@ void SetAutomapView(Point position) return; } - AutomapView[map.x][map.y] = true; + UpdateAutomapExplorer(map, explorer); AutomapTile tile = GetAutomapType(map); bool solid = tile.HasFlag(AutomapTile::Flags::Dirt); @@ -722,57 +748,57 @@ void SetAutomapView(Point position) if (solid) { auto tileSW = GetAutomapType({ map.x, map.y + 1 }); if (tileSW.type == AutomapTile::Types::Corner && tileSW.HasFlag(AutomapTile::Flags::Dirt)) - AutomapView[map.x][map.y + 1] = true; + UpdateAutomapExplorer({ map.x, map.y + 1 }, explorer); } else if (HasAutomapFlag({ map.x - 1, map.y }, AutomapTile::Flags::Dirt)) { - AutomapView[map.x - 1][map.y] = true; + UpdateAutomapExplorer({ map.x - 1, map.y }, explorer); } break; case AutomapTile::Types::Horizontal: if (solid) { auto tileSE = GetAutomapType({ map.x + 1, map.y }); if (tileSE.type == AutomapTile::Types::Corner && tileSE.HasFlag(AutomapTile::Flags::Dirt)) - AutomapView[map.x + 1][map.y] = true; + UpdateAutomapExplorer({ map.x + 1, map.y }, explorer); } else if (HasAutomapFlag({ map.x, map.y - 1 }, AutomapTile::Flags::Dirt)) { - AutomapView[map.x][map.y - 1] = true; + UpdateAutomapExplorer({ map.x, map.y - 1 }, explorer); } break; case AutomapTile::Types::Cross: if (solid) { auto tileSW = GetAutomapType({ map.x, map.y + 1 }); if (tileSW.type == AutomapTile::Types::Corner && tileSW.HasFlag(AutomapTile::Flags::Dirt)) - AutomapView[map.x][map.y + 1] = true; + UpdateAutomapExplorer({ map.x, map.y + 1 }, explorer); auto tileSE = GetAutomapType({ map.x + 1, map.y }); if (tileSE.type == AutomapTile::Types::Corner && tileSE.HasFlag(AutomapTile::Flags::Dirt)) - AutomapView[map.x + 1][map.y] = true; + UpdateAutomapExplorer({ map.x + 1, map.y }, explorer); } else { if (HasAutomapFlag({ map.x - 1, map.y }, AutomapTile::Flags::Dirt)) - AutomapView[map.x - 1][map.y] = true; + UpdateAutomapExplorer({ map.x - 1, map.y }, explorer); if (HasAutomapFlag({ map.x, map.y - 1 }, AutomapTile::Flags::Dirt)) - AutomapView[map.x][map.y - 1] = true; + UpdateAutomapExplorer({ map.x, map.y - 1 }, explorer); if (HasAutomapFlag({ map.x - 1, map.y - 1 }, AutomapTile::Flags::Dirt)) - AutomapView[map.x - 1][map.y - 1] = true; + UpdateAutomapExplorer({ map.x - 1, map.y - 1 }, explorer); } break; case AutomapTile::Types::FenceVertical: if (solid) { if (HasAutomapFlag({ map.x, map.y - 1 }, AutomapTile::Flags::Dirt)) - AutomapView[map.x][map.y - 1] = true; + UpdateAutomapExplorer({ map.x, map.y - 1 }, explorer); auto tileSW = GetAutomapType({ map.x, map.y + 1 }); if (tileSW.type == AutomapTile::Types::Corner && tileSW.HasFlag(AutomapTile::Flags::Dirt)) - AutomapView[map.x][map.y + 1] = true; + UpdateAutomapExplorer({ map.x, map.y + 1 }, explorer); } else if (HasAutomapFlag({ map.x - 1, map.y }, AutomapTile::Flags::Dirt)) { - AutomapView[map.x - 1][map.y] = true; + UpdateAutomapExplorer({ map.x - 1, map.y }, explorer); } break; case AutomapTile::Types::FenceHorizontal: if (solid) { if (HasAutomapFlag({ map.x - 1, map.y }, AutomapTile::Flags::Dirt)) - AutomapView[map.x - 1][map.y] = true; + UpdateAutomapExplorer({ map.x - 1, map.y }, explorer); auto tileSE = GetAutomapType({ map.x + 1, map.y }); if (tileSE.type == AutomapTile::Types::Corner && tileSE.HasFlag(AutomapTile::Flags::Dirt)) - AutomapView[map.x + 1][map.y] = true; + UpdateAutomapExplorer({ map.x + 1, map.y }, explorer); } else if (HasAutomapFlag({ map.x, map.y - 1 }, AutomapTile::Flags::Dirt)) { - AutomapView[map.x][map.y - 1] = true; + UpdateAutomapExplorer({ map.x, map.y - 1 }, explorer); } break; default: diff --git a/Source/automap.h b/Source/automap.h index ed893d299..2587987ae 100644 --- a/Source/automap.h +++ b/Source/automap.h @@ -14,10 +14,23 @@ namespace devilution { +enum MapExplorationType : uint8_t { + /** unexplored map tile */ + MAP_EXP_NONE, + /** map tile explored in vanilla - compatibility reasons */ + MAP_EXP_OLD, + /** map explored by a shrine */ + MAP_EXP_SHRINE, + /** map tile explored by someone else in multiplayer */ + MAP_EXP_OTHERS, + /** map tile explored by current player */ + MAP_EXP_SELF, +}; + /** Specifies whether the automap is enabled. */ extern bool AutomapActive; /** Tracks the explored areas of the map. */ -extern bool AutomapView[DMAXX][DMAXY]; +extern uint8_t AutomapView[DMAXX][DMAXY]; /** Specifies the scale of the automap. */ extern int AutoMapScale; extern Displacement AutomapOffset; @@ -77,10 +90,15 @@ void AutomapZoomOut(); */ void DrawAutomap(const Surface &out); +/** + * @brief Updates automap explorer at point if value is higher than existing. + */ +void UpdateAutomapExplorer(Point map, MapExplorationType explorer); + /** * @brief Marks the given coordinate as within view on the automap. */ -void SetAutomapView(Point tile); +void SetAutomapView(Point tile, MapExplorationType explorer); /** * @brief Resets the zoom level of the automap. diff --git a/Source/debug.cpp b/Source/debug.cpp index 14856c345..5e31919c4 100644 --- a/Source/debug.cpp +++ b/Source/debug.cpp @@ -333,13 +333,25 @@ std::string DebugCmdLighting(const string_view parameter) return "All raindrops are the same."; } -std::string DebugCmdMap(const string_view parameter) +std::string DebugCmdMapReveal(const string_view parameter) { - std::fill(&AutomapView[0][0], &AutomapView[DMAXX - 1][DMAXX - 1], true); + for (int x = 0; x < DMAXX; x++) + for (int y = 0; y < DMAXY; y++) + UpdateAutomapExplorer({ x, y }, MAP_EXP_SHRINE); return "The way is made clear when viewed from above"; } +std::string DebugCmdMapHide(const string_view parameter) +{ + for (int x = 0; x < DMAXX; x++) + for (int y = 0; y < DMAXY; y++) + if (AutomapView[x][y] == MAP_EXP_SHRINE) + AutomapView[x][y] = MAP_EXP_NONE; + + return "The way is made unclear when viewed from below"; +} + std::string DebugCmdVision(const string_view parameter) { DebugVision = !DebugVision; @@ -708,7 +720,8 @@ std::vector DebugCmdList = { { "setspells", "Set spell level to {level} for all spells.", "{level}", &DebugCmdSetSpellsLevel }, { "take gold", "Removes all gold from inventory.", "", &DebugCmdTakeGoldCheat }, { "give quest", "Enable a given quest.", "({id})", &DebugCmdQuest }, - { "give map", "Reveal the map.", "", &DebugCmdMap }, + { "give map", "Reveal the map.", "", &DebugCmdMapReveal }, + { "take map", "Hide the map.", "", &DebugCmdMapHide }, { "changelevel", "Moves to specifided {level} (use 0 for town).", "{level}", &DebugCmdWarpToLevel }, { "map", "Load a quest level {level}.", "{level}", &DebugCmdLoadMap }, { "visit", "Visit a towner.", "{towner}", &DebugCmdVisitTowner }, diff --git a/Source/lighting.cpp b/Source/lighting.cpp index fb627bc7d..231fbf9ed 100644 --- a/Source/lighting.cpp +++ b/Source/lighting.cpp @@ -645,13 +645,12 @@ void DoUnVision(Point position, int nRadius) } } -void DoVision(Point position, int nRadius, bool doautomap, bool visible) +void DoVision(Point position, int nRadius, MapExplorationType doautomap, bool visible) { - if (InDungeonBounds(position)) { - if (doautomap) { + if (doautomap != MAP_EXP_NONE) { if (dFlags[position.x][position.y] != 0) { - SetAutomapView(position); + SetAutomapView(position, doautomap); } dFlags[position.x][position.y] |= BFLAG_EXPLORED; } @@ -712,9 +711,9 @@ void DoVision(Point position, int nRadius, bool doautomap, bool visible) && !nBlockTable[dPiece[x1adj + nCrawlX][y1adj + nCrawlY]]) || (InDungeonBounds({ x2adj + nCrawlX, y2adj + nCrawlY }) && !nBlockTable[dPiece[x2adj + nCrawlX][y2adj + nCrawlY]])) { - if (doautomap) { + if (doautomap != MAP_EXP_NONE) { if (dFlags[nCrawlX][nCrawlY] != 0) { - SetAutomapView({ nCrawlX, nCrawlY }); + SetAutomapView({ nCrawlX, nCrawlY }, doautomap); } dFlags[nCrawlX][nCrawlY] |= BFLAG_EXPLORED; } @@ -1172,7 +1171,7 @@ void ProcessVisionList() DoVision( vision.position.tile, vision._lradius, - vision._lflags, + vision._lflags ? MAP_EXP_SELF : MAP_EXP_OTHERS, vision._lflags); } bool delflag; diff --git a/Source/lighting.h b/Source/lighting.h index 827987eab..b3ac76d77 100644 --- a/Source/lighting.h +++ b/Source/lighting.h @@ -7,6 +7,7 @@ #include +#include "automap.h" #include "engine.h" #include "engine/point.hpp" #include "miniwin/miniwin.h" @@ -49,7 +50,7 @@ extern bool UpdateLighting; void DoLighting(Point position, int nRadius, int Lnum); void DoUnVision(Point position, int nRadius); -void DoVision(Point position, int nRadius, bool doautomap, bool visible); +void DoVision(Point position, int nRadius, MapExplorationType doautomap, bool visible); void MakeLightTable(); #ifdef _DEBUG void ToggleLighting(); diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp index 85adf6854..35cb28044 100644 --- a/Source/loadsave.cpp +++ b/Source/loadsave.cpp @@ -1832,7 +1832,7 @@ void LoadGame(bool firstflag) } for (int j = 0; j < DMAXY; j++) { for (int i = 0; i < DMAXX; i++) // NOLINT(modernize-loop-convert) - AutomapView[i][j] = file.NextBool8(); + AutomapView[i][j] = file.NextLE(); } file.Skip(MAXDUNX * MAXDUNY); // dMissile } @@ -2026,7 +2026,7 @@ void SaveGameData() } for (int j = 0; j < DMAXY; j++) { for (int i = 0; i < DMAXX; i++) // NOLINT(modernize-loop-convert) - file.WriteLE(AutomapView[i][j] ? 1 : 0); + file.WriteLE(AutomapView[i][j]); } for (int j = 0; j < MAXDUNY; j++) { for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert) @@ -2125,7 +2125,7 @@ void SaveLevel() } for (int j = 0; j < DMAXY; j++) { for (int i = 0; i < DMAXX; i++) // NOLINT(modernize-loop-convert) - file.WriteLE(AutomapView[i][j] ? 1 : 0); + file.WriteLE(AutomapView[i][j]); } } @@ -2206,8 +2206,10 @@ void LoadLevel() dPreLight[i][j] = file.NextLE(); } for (int j = 0; j < DMAXY; j++) { - for (int i = 0; i < DMAXX; i++) // NOLINT(modernize-loop-convert) - AutomapView[i][j] = file.NextBool8(); + for (int i = 0; i < DMAXX; i++) { // NOLINT(modernize-loop-convert) + uint8_t automapView = file.NextLE(); + AutomapView[i][j] = automapView == MAP_EXP_OLD ? MAP_EXP_SELF : automapView; + } } } diff --git a/Source/monster.cpp b/Source/monster.cpp index 14ea27d7c..ee88c34c6 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -1073,7 +1073,7 @@ void DiabloDeath(Monster &diablo, bool sendmsg) dMonster[monster.position.tile.x][monster.position.tile.y] = k + 1; } AddLight(diablo.position.tile, 8); - DoVision(diablo.position.tile, 8, false, true); + DoVision(diablo.position.tile, 8, MAP_EXP_NONE, true); int dist = diablo.position.tile.WalkingDistance(ViewPosition); if (dist > 20) dist = 20; @@ -3809,7 +3809,7 @@ void InitMonsters() for (int i = 0; i < nt; i++) { for (int s = -2; s < 2; s++) { for (int t = -2; t < 2; t++) - DoVision(trigs[i].position + Displacement { s, t }, 15, false, false); + DoVision(trigs[i].position + Displacement { s, t }, 15, MAP_EXP_NONE, false); } } if (!gbIsSpawn) diff --git a/Source/objects.cpp b/Source/objects.cpp index 83cf299ce..8cb459986 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -3212,7 +3212,9 @@ bool OperateShrineSecluded(int pnum) if (pnum != MyPlayerId) return true; - std::fill(&AutomapView[0][0], &AutomapView[DMAXX - 1][DMAXX - 1], true); + for (int x = 0; x < DMAXX; x++) + for (int y = 0; y < DMAXY; y++) + UpdateAutomapExplorer({ x, y }, MAP_EXP_SHRINE); InitDiabloMsg(EMSG_SHRINE_SECLUDED);