Browse Source

Sharing automap exploration in multiplayer

pull/3247/head
qndel 5 years ago committed by Anders Jenbo
parent
commit
e567953bc9
  1. 318
      Source/automap.cpp
  2. 22
      Source/automap.h
  3. 19
      Source/debug.cpp
  4. 13
      Source/lighting.cpp
  5. 3
      Source/lighting.h
  6. 12
      Source/loadsave.cpp
  7. 4
      Source/monster.cpp
  8. 4
      Source/objects.cpp

318
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<MapExplorationType>(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<AutomapTile[]> 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:

22
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.

19
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<DebugCmdItem> 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 },

13
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;

3
Source/lighting.h

@ -7,6 +7,7 @@
#include <array>
#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();

12
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<uint8_t>();
}
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<uint8_t>(AutomapView[i][j] ? 1 : 0);
file.WriteLE<uint8_t>(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<uint8_t>(AutomapView[i][j] ? 1 : 0);
file.WriteLE<uint8_t>(AutomapView[i][j]);
}
}
@ -2206,8 +2206,10 @@ void LoadLevel()
dPreLight[i][j] = file.NextLE<int8_t>();
}
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<uint8_t>();
AutomapView[i][j] = automapView == MAP_EXP_OLD ? MAP_EXP_SELF : automapView;
}
}
}

4
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)

4
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);

Loading…
Cancel
Save