static int ShroudedEdges(Shroud s, CPos p, bool useExtendedIndex) { if (!s.IsExplored(p.X, p.Y)) { return(15); } // If a side is shrouded then we also count the corners var u = 0; if (!s.IsExplored(p.X, p.Y - 1)) { u |= 0x13; } if (!s.IsExplored(p.X + 1, p.Y)) { u |= 0x26; } if (!s.IsExplored(p.X, p.Y + 1)) { u |= 0x4C; } if (!s.IsExplored(p.X - 1, p.Y)) { u |= 0x89; } var uside = u & 0x0F; if (!s.IsExplored(p.X - 1, p.Y - 1)) { u |= 0x01; } if (!s.IsExplored(p.X + 1, p.Y - 1)) { u |= 0x02; } if (!s.IsExplored(p.X + 1, p.Y + 1)) { u |= 0x04; } if (!s.IsExplored(p.X - 1, p.Y + 1)) { u |= 0x08; } // RA provides a set of frames for tiles with shrouded // corners but unshrouded edges. We want to detect this // situation without breaking the edge -> corner enabling // in other combinations. The XOR turns off the corner // bits that are enabled twice, which gives the behavior // we want here. return(useExtendedIndex ? u ^ uside : u& 0x0F); }
Sprite ChooseShroud(Shroud s, int i, int j) { if (!s.IsExplored(i, j)) { return(shadowBits[0xf]); } // bits are for unexploredness: up, right, down, left var v = 0; // bits are for unexploredness: TL, TR, BR, BL var u = 0; if (!s.IsExplored(i, j - 1)) { v |= 1; u |= 3; } if (!s.IsExplored(i + 1, j)) { v |= 2; u |= 6; } if (!s.IsExplored(i, j + 1)) { v |= 4; u |= 12; } if (!s.IsExplored(i - 1, j)) { v |= 8; u |= 9; } var uSides = u; if (!s.IsExplored(i - 1, j - 1)) { u |= 1; } if (!s.IsExplored(i + 1, j - 1)) { u |= 2; } if (!s.IsExplored(i + 1, j + 1)) { u |= 4; } if (!s.IsExplored(i - 1, j + 1)) { u |= 8; } return(shadowBits[SpecialShroudTiles[u ^ uSides][v]]); }
public static bool AnyExplored(this Shroud shroud, OccupiedCells cells) { foreach (var cell in cells) { if (shroud.IsExplored(cell.First)) { return(true); } } return(false); }
public static bool AnyExplored(this Shroud shroud, PPos[] puvs) { // PERF: Avoid LINQ. foreach (var puv in puvs) { if (shroud.IsExplored(puv)) { return(true); } } return(false); }
public static bool AnyExplored(this Shroud shroud, Pair <CPos, SubCell>[] cells) { // PERF: Avoid LINQ. foreach (var cell in cells) { if (shroud.IsExplored(cell.First)) { return(true); } } return(false); }
public void RenderShroud(Shroud shroud, WorldRenderer wr) { if (currentShroud != shroud) { if (currentShroud != null) { currentShroud.CellsChanged -= DirtyCells; } if (shroud != null) { shroud.CellsChanged += DirtyCells; } // Needs the anonymous function to ensure the correct overload is chosen if (shroud != null) { visibleUnderShroud = puv => currentShroud.IsExplored(puv); } else { visibleUnderShroud = puv => map.Contains(puv); } if (shroud != null) { visibleUnderFog = puv => currentShroud.IsVisible(puv); } else { visibleUnderFog = puv => map.Contains(puv); } currentShroud = shroud; DirtyCells(map.ProjectedCellBounds); } // We need to update newly dirtied areas of the shroud. // Expand the dirty area to cover the neighboring cells, since shroud is affected by neighboring cells. foreach (var uv in cellsDirty) { cellsAndNeighborsDirty.Add(uv); var cell = ((MPos)uv).ToCPos(map); foreach (var direction in CVec.Directions) { cellsAndNeighborsDirty.Add((PPos)(cell + direction).ToMPos(map)); } } foreach (var puv in cellsAndNeighborsDirty) { var uv = (MPos)puv; if (!tileInfos.Contains(uv)) { continue; } var tileInfo = tileInfos[uv]; var shroudSprite = GetSprite(shroudSprites, GetEdges(puv, visibleUnderShroud), tileInfo.Variant); var shroudPos = tileInfo.ScreenPosition; if (shroudSprite != null) { shroudPos += shroudSprite.Offset - 0.5f * shroudSprite.Size; } var fogSprite = GetSprite(fogSprites, GetEdges(puv, visibleUnderFog), tileInfo.Variant); var fogPos = tileInfo.ScreenPosition; if (fogSprite != null) { fogPos += fogSprite.Offset - 0.5f * fogSprite.Size; } shroudLayer.Update(uv, shroudSprite, shroudPos); fogLayer.Update(uv, fogSprite, fogPos); } cellsDirty.Clear(); cellsAndNeighborsDirty.Clear(); fogLayer.Draw(wr.Viewport); shroudLayer.Draw(wr.Viewport); }