Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 27 additions & 24 deletions code/display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2986,41 +2986,44 @@ void DisplayClass::Encroach_Fog(void)
/// <param name="cell">The cell that the fog is to be regrown upon.</param>
void DisplayClass::Fog_Cell(Cell const & cell)
{
if (!In_Radar(cell)) return;
// An explicit queue avoids running the stack out on a cascade that spans most of the map.
std::vector<Cell> pending;
pending.push_back(cell);

CellClass * cellptr = &(*this)[cell];
bool fog = false;
while (!pending.empty()) {
Cell current = pending.back();
pending.pop_back();

if (cellptr->IsFogMapped || cellptr->IsFogVisible) {
fog = true;
}
if (!In_Radar(current)) continue;

cellptr->IsFogMapped = false;
cellptr->IsFogVisible = false;
cellptr->FogFrame = -2;
CellClass * cellptr = &(*this)[current];
bool fog = cellptr->IsFogMapped || cellptr->IsFogVisible;

if (cellptr->IsMapped) {
TacticalMap->Flag_Cell(*cellptr);
}
cellptr->IsFogMapped = false;
cellptr->IsFogVisible = false;
cellptr->FogFrame = -2;

for (FacingType dir = FACING_FIRST; dir < FACING_COUNT; dir++) {
Cell c = Adjacent_Cell(cell, dir);
CellClass * cptr = &(*this)[c];
int fog = TacticalMap->Cell_Shadow(cptr->Fetch_CellID(), true);
if (cellptr->IsMapped) {
TacticalMap->Flag_Cell(*cellptr);
}

if (fog == -2 && cptr->FogFrame != -2) {
Fog_Cell(c);
} else {
if ((cptr->IsFogVisible || fog != cptr->FogFrame) && fog >= 0 && cptr->FogFrame >= -1) {
cptr->FogFrame = fog;
for (FacingType dir = FACING_FIRST; dir < FACING_COUNT; dir++) {
Cell c = Adjacent_Cell(current, dir);
CellClass * cptr = &(*this)[c];
int fogshape = TacticalMap->Cell_Shadow(cptr->Fetch_CellID(), true);

if (fogshape == -2 && cptr->FogFrame != -2) {
pending.push_back(c);
} else if ((cptr->IsFogVisible || fogshape != cptr->FogFrame) && fogshape >= 0 && cptr->FogFrame >= -1) {
cptr->FogFrame = fogshape;
cptr->IsFogMapped = true;
cptr->IsFogVisible = false;
TacticalMap->Flag_Cell(*cptr);
}
}
}
if (fog) {
cellptr->Fog_Cell();
if (fog) {
cellptr->Fog_Cell();
}
}
}

Expand Down
10 changes: 9 additions & 1 deletion code/mainloop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "ipxmgr.h"
#include "language/language.h"
#include "logic.h"
#include "map.h"
#include "misc.h"
#include "mpscore.h"
#include "msgbox.h"
Expand Down Expand Up @@ -540,7 +541,14 @@ void Keyboard_Process(KeyNumType & input)
if ((Debug_Flag || Debug_Playtest) && plain == KN_F4) {
if (Session.Type == GAME_NORMAL) {
Debug_Unshroud = (Debug_Unshroud == false);
Map.Flag_To_Redraw(GS_REDRAW_ALL);

// The same pair the reveal and blackout crates use, so turning this off
// leaves normal vision to re-explore the map rather than leaving it dark.
if (Debug_Unshroud) {
Map.Reveal_The_Map(true);
} else {
Map.Shroud_The_Map();
}
}
}

Expand Down
41 changes: 22 additions & 19 deletions code/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11640,29 +11640,32 @@ bool MapClass::Is_Something_Nearby(Cell const & cell, int radius)
/// <summary>
/// Determines if a coordinate is still under the shroud.
/// Which cell a coordinate appears over depends on how high it is, so the height is folded
/// into the lookup before the shroud is consulted.
/// into the lookup before the shroud is consulted. The map debugger's unshroud toggle sees
/// through it, and nothing is reported as hidden while that is active.
/// </summary>
/// <returns>bool; Is the coordinate still shrouded?</returns>
bool MapClass::Is_Shrouded(Coord const & coord)
{
int level_height = coord.Z / LEVEL_LEPTON_H;
if ((level_height & 1) != 0) {
int offset = level_height / 2 + 1;
Cell cell = coord.As_Cell();
CellClass * cptr = &Map[Cell(cell.X - offset, cell.Y - offset)];
if (cptr->IsMapped) {
return(false);
}
cptr = &cptr->Adjacent_Cell(FACING_SE);
if (!cptr->IsMapped) {
return(true);
}
} else {
int offset = level_height / 2;
Cell cell = coord.As_Cell();
CellClass * cptr = &Map[Cell(cell.X - offset, cell.Y - offset)];
if (!cptr->IsMapped) {
return(true);
if (!Debug_Unshroud) {
int level_height = coord.Z / LEVEL_LEPTON_H;
if ((level_height & 1) != 0) {
int offset = level_height / 2 + 1;
Cell cell = coord.As_Cell();
CellClass * cptr = &Map[Cell(cell.X - offset, cell.Y - offset)];
if (cptr->IsMapped) {
return(false);
}
cptr = &cptr->Adjacent_Cell(FACING_SE);
if (!cptr->IsMapped) {
return(true);
}
} else {
int offset = level_height / 2;
Cell cell = coord.As_Cell();
CellClass * cptr = &Map[Cell(cell.X - offset, cell.Y - offset)];
if (!cptr->IsMapped) {
return(true);
}
}
}
return(false);
Expand Down
17 changes: 17 additions & 0 deletions manual/changes/f4-debug-unshroud-toggle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: Fix the F4 playtest shroud toggle doing nothing
category: fix
release: 0.2.0
targets:
- type: command
id: fixed:debug-unshroud
effect: changed
credit:
- torradmin
---

Pressing F4 flagged the whole tactical view for redraw but never touched the shroud data
itself, so the map stayed exactly as shrouded as before. F4 now reveals the map when
turning the toggle on and reshrouds it when turning the toggle off, the same pair the
reveal-the-map and blackout crates use, and coordinate shroud checks now see through an
active toggle instead of only the redraw seeing it.
17 changes: 17 additions & 0 deletions manual/changes/stack-overflow-on-mass-shroud-unshroud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: Fix crash when large fog changes unwound recursively
category: fix
release: 0.2.0
targets:
- type: system
id: map-visibility
effect: changed
credit:
- torradmin
---

Regrowing fog over a cell recursed into every neighbor that also needed to regrow, so
shrouding or unshrouding a large connected area — a big map, a reveal-the-map crate, or the
[map shroud toggle](/commands/fixed-debug-unshroud/) — could recurse deeply enough to
overflow the stack and crash. Fog regrowth now walks an explicit queue instead, so the
depth of a shroud change no longer bounds how much fog can change at once.