Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for visible area being confused with illuminated area #4044

Merged
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
41 changes: 13 additions & 28 deletions src/main/java/net/rptools/maptool/client/ui/zone/ZoneView.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ private record IlluminationKey(double multiplier) {}
private final Map<PlayerView, Area> exposedAreaMap = new HashMap<>();

/** Map the PlayerView to its visible area. */
private final Map<PlayerView, VisibleAreaMeta> visibleAreaMap = new HashMap<>();
private final Map<PlayerView, Area> visibleAreaMap = new HashMap<>();

// endregion

Expand Down Expand Up @@ -176,14 +176,22 @@ public Area getExposedArea(PlayerView view) {
/**
* Calculate the visible area of the view, cache it in visibleAreaMap, and return it
*
* <p>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;
});
}

/**
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -986,9 +976,4 @@ private boolean processTokenAddChangeEvent(List<Token> tokens) {

return hasTopology;
}

/** Has a single field: the visibleArea area */
private static class VisibleAreaMeta {
Area visibleArea;
}
}