getDisjointObscuredLumensLevels() {
if (disjointObscuredLumensLevels == null) {
diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/PlayerView.java b/src/main/java/net/rptools/maptool/client/ui/zone/PlayerView.java
index 91cbe979e4..1f3a6b6cb0 100644
--- a/src/main/java/net/rptools/maptool/client/ui/zone/PlayerView.java
+++ b/src/main/java/net/rptools/maptool/client/ui/zone/PlayerView.java
@@ -27,13 +27,31 @@ public class PlayerView {
// Optimization
private final String hash;
+ /**
+ * Creates a player view that does not use token views.
+ *
+ * Calling `isUsingTokenView()` on the new player view will return {@code false} and {@link
+ * #getTokens()} should not be called.
+ *
+ * @param role The player role for the view.
+ */
public PlayerView(Player.Role role) {
- this(role, null);
+ this.role = role;
+ this.tokens = null;
+ hash = calculateHashcode();
}
+ /**
+ * Creates a player view for a token view.
+ *
+ *
Calling `isUsingTokenView()` on the new player view will return {@code false} and {@link
+ * #getTokens()} can be called to retrieve the list of tokens.
+ *
+ * @param role The player role for the view.
+ */
public PlayerView(Player.Role role, List tokens) {
this.role = role;
- this.tokens = tokens != null && !tokens.isEmpty() ? tokens : null;
+ this.tokens = tokens;
hash = calculateHashcode();
}
@@ -45,6 +63,13 @@ public boolean isGMView() {
return role == Player.Role.GM;
}
+ /**
+ * Gets the tokens for this view.
+ *
+ * This method should only be used when {@link #isUsingTokenView()} returns {@code true}.
+ *
+ * @return The tokens for this view.
+ */
public List getTokens() {
return tokens;
}
@@ -74,6 +99,7 @@ private String calculateHashcode() {
StringBuilder builder = new StringBuilder();
builder.append(role);
if (tokens != null) {
+ builder.append('|'); // Distinguishes null and empty case.
for (Token token : tokens) {
builder.append(token.getId());
}
diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/ZoneRenderer.java b/src/main/java/net/rptools/maptool/client/ui/zone/ZoneRenderer.java
index bc3691e25c..59e5706f02 100644
--- a/src/main/java/net/rptools/maptool/client/ui/zone/ZoneRenderer.java
+++ b/src/main/java/net/rptools/maptool/client/ui/zone/ZoneRenderer.java
@@ -880,6 +880,10 @@ public PlayerView getPlayerView(Player.Role role, boolean selected) {
? zone.getOwnedTokensWithSight(MapTool.getPlayer())
: zone.getPlayerTokensWithSight();
}
+ if (selectedTokens == null || selectedTokens.isEmpty()) {
+ return new PlayerView(role);
+ }
+
return new PlayerView(role, selectedTokens);
}
@@ -1512,9 +1516,6 @@ private void renderLumensOverlay(
timer.stop("renderLumensOverlay:setTransform");
timer.start("renderLumensOverlay:drawLumens");
- // Lumens are ordered to be weak to strong. That works for us as we will draw the stronger
- // areas overtop the weaker areas using `AlphaComposite.Src` to make sure the stronger one
- // "wins".
for (final var lumensLevel : disjointLumensLevels) {
final var lumensStrength = lumensLevel.lumensStrength();
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 2c84f3e29c..8b0bf21273 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
@@ -549,7 +549,7 @@ public Illumination getIllumination(PlayerView view) {
*
* @param view
* @return The various lumens levels, with any stronger lumens areas being subtracted from weaker
- * lumens areas.
+ * lumens areas and ordered from strong to weak lumens.
*/
public List getDisjointObscuredLumensLevels(PlayerView view) {
final var illumination = getIllumination(view);
diff --git a/src/main/java/net/rptools/maptool/util/FunctionUtil.java b/src/main/java/net/rptools/maptool/util/FunctionUtil.java
index 27e5bacab8..ea589ccee3 100644
--- a/src/main/java/net/rptools/maptool/util/FunctionUtil.java
+++ b/src/main/java/net/rptools/maptool/util/FunctionUtil.java
@@ -203,6 +203,9 @@ public static Token getTokenFromParam(
ZoneRenderer zoneRenderer;
if (map == null) {
zoneRenderer = MapTool.getFrame().getCurrentZoneRenderer();
+ if (zoneRenderer == null) {
+ throw new ParserException(I18N.getText("macro.function.map.none", functionName));
+ }
} else {
zoneRenderer = getZoneRenderer(functionName, map);
}