diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/ZoneView.java b/src/main/java/net/rptools/maptool/client/ui/zone/ZoneView.java index 1c458c70e3..1ffa4bc088 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/ZoneView.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/ZoneView.java @@ -114,7 +114,7 @@ private record IlluminationKey(double multiplier) {} private final Map exposedAreaMap = new HashMap<>(); /** Map the PlayerView to its visible area. */ - private final Map visibleAreaMap = new HashMap<>(); + private final Map visibleAreaMap = new HashMap<>(); // endregion @@ -176,14 +176,22 @@ public Area getExposedArea(PlayerView view) { /** * Calculate the visible area of the view, cache it in visibleAreaMap, and return it * + *

The visible area is calculated for each token in the view. The token's visible area is its + * vision obstructed by topology and restricted to the illuminated portions of the map. + * * @param view the PlayerView * @return the visible area */ public Area getVisibleArea(PlayerView view) { - calculateVisibleArea(view); - ZoneView.VisibleAreaMeta visible = visibleAreaMap.get(view); - - return visible != null ? visible.visibleArea : new Area(); + return visibleAreaMap.computeIfAbsent( + view, + view2 -> { + final var visibleArea = new Area(); + getTokensForView(view2) + .map(token -> this.getVisibleArea(token, view2)) + .forEach(visibleArea::add); + return visibleArea; + }); } /** @@ -836,24 +844,6 @@ public void flush(Token token) { } } - /** - * Construct the {@link #visibleAreaMap} entry for a player view. - * - * @param view the player view. - */ - private void calculateVisibleArea(PlayerView view) { - if (visibleAreaMap.get(view) != null && !visibleAreaMap.get(view).visibleArea.isEmpty()) { - return; - } - // Cache it - final var illumination = getIllumination(view); - // We _could_ instead union up all the individual token's areas, but we already have the same - // result via the view's illumination. - VisibleAreaMeta meta = new VisibleAreaMeta(); - meta.visibleArea = illumination.getVisibleArea(); - visibleAreaMap.put(view, meta); - } - @Subscribe private void onTopologyChanged(TopologyChanged event) { if (event.zone() != this.zone) { @@ -986,9 +976,4 @@ private boolean processTokenAddChangeEvent(List tokens) { return hasTopology; } - - /** Has a single field: the visibleArea area */ - private static class VisibleAreaMeta { - Area visibleArea; - } }