Sharing automap exploration in multiplayer
This commit is contained in:
parent
588f1d796a
commit
e567953bc9
8 changed files with 228 additions and 167 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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…
Add table
Add a link
Reference in a new issue