diff --git a/src/main/java/net/rptools/maptool/client/ServerCommandClientImpl.java b/src/main/java/net/rptools/maptool/client/ServerCommandClientImpl.java index 282a553ef4..0f83ff82f1 100644 --- a/src/main/java/net/rptools/maptool/client/ServerCommandClientImpl.java +++ b/src/main/java/net/rptools/maptool/client/ServerCommandClientImpl.java @@ -674,16 +674,18 @@ public void updateTokenProperty(Token token, Token.Update update, String value) @Override public void updateTokenProperty(Token token, Token.Update update, LightSource value) { - if (update == Token.Update.createUniqueLightSource) { - // This case requires sending the full light source definition. - updateTokenProperty( - token, update, TokenPropertyValueDto.newBuilder().setLightSource(value.toDto()).build()); - } else { - updateTokenProperty( - token, - update, - TokenPropertyValueDto.newBuilder().setLightSourceId(value.getId().toString()).build()); - } + updateTokenProperty( + token, update, TokenPropertyValueDto.newBuilder().setLightSource(value.toDto()).build()); + } + + @Override + public void updateTokenProperty( + Token token, Token.Update update, LightSource value1, String value2) { + updateTokenProperty( + token, + update, + TokenPropertyValueDto.newBuilder().setLightSource(value1.toDto()).build(), + TokenPropertyValueDto.newBuilder().setStringValue(value2).build()); } @Override diff --git a/src/main/java/net/rptools/maptool/client/functions/TokenLightFunctions.java b/src/main/java/net/rptools/maptool/client/functions/TokenLightFunctions.java index fcf295768d..5a1f8dda96 100644 --- a/src/main/java/net/rptools/maptool/client/functions/TokenLightFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/TokenLightFunctions.java @@ -15,19 +15,14 @@ package net.rptools.maptool.client.functions; import com.google.gson.JsonArray; -import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; -import java.awt.Color; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Objects; -import java.util.Optional; import net.rptools.maptool.client.MapTool; import net.rptools.maptool.language.I18N; import net.rptools.maptool.model.*; -import net.rptools.maptool.model.drawing.DrawableColorPaint; import net.rptools.maptool.util.FunctionUtil; import net.rptools.parser.Parser; import net.rptools.parser.ParserException; @@ -37,22 +32,8 @@ public class TokenLightFunctions extends AbstractFunction { private static final TokenLightFunctions instance = new TokenLightFunctions(); - private static final String TOKEN_CATEGORY = "$unique"; - private TokenLightFunctions() { - super( - 0, - 5, - "hasLightSource", - "clearLights", - "setLight", - "getLights", - "createUniqueLightSource", - "updateUniqueLightSource", - "deleteUniqueLightSource", - "getUniqueLightSource", - "getUniqueLightSources", - "getUniqueLightSourceNames"); + super(0, 5, "hasLightSource", "clearLights", "setLight", "getLights"); } public static TokenLightFunctions getInstance() { @@ -95,49 +76,6 @@ public Object childEvaluate( Token token = FunctionUtil.getTokenFromParam(resolver, functionName, parameters, 2, 3); return getLights(token, type, delim); } - if (functionName.equalsIgnoreCase("createUniqueLightSource")) { - FunctionUtil.blockUntrustedMacro(functionName); - FunctionUtil.checkNumberParam(functionName, parameters, 1, 3); - - JsonObject lightSource = FunctionUtil.paramAsJsonObject(functionName, parameters, 0); - Token token = FunctionUtil.getTokenFromParam(resolver, functionName, parameters, 1, 2); - return createUniqueLightSource(lightSource, token, false).getName(); - } - if (functionName.equalsIgnoreCase("updateUniqueLightSource")) { - FunctionUtil.blockUntrustedMacro(functionName); - FunctionUtil.checkNumberParam(functionName, parameters, 1, 3); - - JsonObject lightSource = FunctionUtil.paramAsJsonObject(functionName, parameters, 0); - Token token = FunctionUtil.getTokenFromParam(resolver, functionName, parameters, 1, 2); - return createUniqueLightSource(lightSource, token, true).getName(); - } - if (functionName.equalsIgnoreCase("deleteUniqueLightSource")) { - FunctionUtil.checkNumberParam(functionName, parameters, 1, 3); - - String name = parameters.get(0).toString(); - Token token = FunctionUtil.getTokenFromParam(resolver, functionName, parameters, 1, 2); - deleteUniqueLightSource(name, token); - return ""; - } - if (functionName.equalsIgnoreCase("getUniqueLightSource")) { - FunctionUtil.checkNumberParam(functionName, parameters, 1, 3); - - String name = parameters.get(0).toString(); - Token token = FunctionUtil.getTokenFromParam(resolver, functionName, parameters, 1, 2); - return Objects.requireNonNullElse(getUniqueLightSource(name, token), ""); - } - if (functionName.equalsIgnoreCase("getUniqueLightSources")) { - FunctionUtil.checkNumberParam(functionName, parameters, 0, 2); - - Token token = FunctionUtil.getTokenFromParam(resolver, functionName, parameters, 0, 1); - return getUniqueLightSources(token); - } - if (functionName.equalsIgnoreCase("getUniqueLightSourceNames")) { - FunctionUtil.checkNumberParam(functionName, parameters, 0, 2); - - Token token = FunctionUtil.getTokenFromParam(resolver, functionName, parameters, 0, 1); - return getUniqueLightSourceNames(token); - } return null; } @@ -145,9 +83,8 @@ public Object childEvaluate( * Gets the names of the light sources that are on. * * @param token The token to get the light sources for. - * @param category The category to get the light sources for. If "*" then the light sources for - * all categories will be returned. If "$unique" then the light sources defined on the token - * will be returned. + * @param category The category to get the light sources for, if null then the light sources for + * all categories will be returned. * @param delim the delimiter for the list. * @return a string list containing the lights that are on. * @throws ParserException if the light type can't be found. @@ -158,13 +95,7 @@ private static String getLights(Token token, String category, String delim) Map> lightSourcesMap = MapTool.getCampaign().getLightSourcesMap(); - if (category.equals("*")) { - // Look up on both token and campaign. - for (LightSource ls : token.getUniqueLightSources()) { - if (token.hasLightSource(ls)) { - lightList.add(ls.getName()); - } - } + if (category == null || category.equals("*")) { for (Map lsMap : lightSourcesMap.values()) { for (LightSource ls : lsMap.values()) { if (token.hasLightSource(ls)) { @@ -172,23 +103,18 @@ private static String getLights(Token token, String category, String delim) } } } - } else if (TOKEN_CATEGORY.equals(category)) { - for (LightSource ls : token.getUniqueLightSources()) { - if (token.hasLightSource(ls)) { - lightList.add(ls.getName()); - } - } - } else if (lightSourcesMap.containsKey(category)) { - for (LightSource ls : lightSourcesMap.get(category).values()) { - if (token.hasLightSource(ls)) { - lightList.add(ls.getName()); + } else { + if (lightSourcesMap.containsKey(category)) { + for (LightSource ls : lightSourcesMap.get(category).values()) { + if (token.hasLightSource(ls)) { + lightList.add(ls.getName()); + } } + } else { + throw new ParserException( + I18N.getText("macro.function.tokenLight.unknownLightType", "getLights", category)); } - } else { - throw new ParserException( - I18N.getText("macro.function.tokenLight.unknownLightType", "getLights", category)); } - if ("json".equals(delim)) { JsonArray jarr = new JsonArray(); lightList.forEach(l -> jarr.add(new JsonPrimitive(l))); @@ -202,8 +128,7 @@ private static String getLights(Token token, String category, String delim) * Sets the light value for a token. * * @param token the token to set the light for. - * @param category the category of the light source. Use "$unique" for light sources defined on - * the token. + * @param category the category of the light source. * @param name the name of the light source. * @param val the value to set for the light source, 0 for off non 0 for on. * @return 0 if the light was not found, otherwise 1; @@ -215,25 +140,21 @@ private static BigDecimal setLight(Token token, String category, String name, Bi Map> lightSourcesMap = MapTool.getCampaign().getLightSourcesMap(); - Iterable sources; - if (TOKEN_CATEGORY.equals(category)) { - sources = token.getUniqueLightSources(); - } else if (lightSourcesMap.containsKey(category)) { - sources = lightSourcesMap.get(category).values(); + if (lightSourcesMap.containsKey(category)) { + for (LightSource ls : lightSourcesMap.get(category).values()) { + if (ls.getName().equals(name)) { + found = true; + if (val.equals(BigDecimal.ZERO)) { + MapTool.serverCommand().updateTokenProperty(token, Token.Update.removeLightSource, ls); + } else { + MapTool.serverCommand().updateTokenProperty(token, Token.Update.addLightSource, ls); + } + } + } } else { throw new ParserException( I18N.getText("macro.function.tokenLight.unknownLightType", "setLights", category)); } - - final var updateAction = - BigDecimal.ZERO.equals(val) ? Token.Update.removeLightSource : Token.Update.addLightSource; - for (LightSource ls : sources) { - if (name.equals(ls.getName())) { - found = true; - MapTool.serverCommand().updateTokenProperty(token, updateAction, ls); - } - } - return found ? BigDecimal.ONE : BigDecimal.ZERO; } @@ -241,7 +162,6 @@ private static BigDecimal setLight(Token token, String category, String name, Bi * Checks to see if the token has a light source. The token is checked to see if it has a light * source with the name in the second parameter from the category in the first parameter. A "*" * for category indicates all categories are checked; a "*" for name indicates all names are - * checked. The "$unique" category indicates that only light sources defined on the token are * checked. * * @param token the token to check. @@ -260,12 +180,6 @@ public static boolean hasLightSource(Token token, String category, String name) MapTool.getCampaign().getLightSourcesMap(); if ("*".equals(category)) { - // Look up on both token and campaign. - for (LightSource ls : token.getUniqueLightSources()) { - if (ls.getName().equals(name) && token.hasLightSource(ls)) { - return true; - } - } for (Map lsMap : lightSourcesMap.values()) { for (LightSource ls : lsMap.values()) { if (ls.getName().equals(name) && token.hasLightSource(ls)) { @@ -273,218 +187,21 @@ public static boolean hasLightSource(Token token, String category, String name) } } } - } else if (TOKEN_CATEGORY.equals(category)) { - for (LightSource ls : token.getUniqueLightSources()) { - if ((ls.getName().equals(name) || "*".equals(name)) && token.hasLightSource(ls)) { - return true; - } - } - } else if (lightSourcesMap.containsKey(category)) { - for (LightSource ls : lightSourcesMap.get(category).values()) { - if ((ls.getName().equals(name) || "*".equals(name)) && token.hasLightSource(ls)) { - return true; - } - } } else { - throw new ParserException( - I18N.getText("macro.function.tokenLight.unknownLightType", "hasLightSource", category)); - } - - return false; - } - - private static LightSource createUniqueLightSource( - JsonObject lightSourceDef, Token token, boolean isUpdate) throws ParserException { - if (!lightSourceDef.has("name")) { - throw new ParserException(I18N.getText("The light source must have a name.")); - } - final String name = lightSourceDef.get("name").getAsString(); - - // Modifications require the light source to exist. Creation requires it to not exists. - final Optional existingSource = - token.getUniqueLightSources().stream() - .filter(source -> name.equals(source.getName())) - .findFirst(); - if (isUpdate && existingSource.isEmpty()) { - throw new ParserException( - I18N.getText( - "Light source %s is not defined for token %s", name, token.getId().toString())); - } - if (!isUpdate && existingSource.isPresent()) { - throw new ParserException( - I18N.getText( - "Light source %s is already defined for token %s", name, token.getId().toString())); - } - - final LightSource.Type type = - lightSourceDef.has("type") - ? LightSource.Type.valueOf(lightSourceDef.get("type").getAsString().toUpperCase()) - : LightSource.Type.NORMAL; - final boolean scaleWithToken = - lightSourceDef.has("scale") ? lightSourceDef.get("scale").getAsBoolean() : false; - final JsonArray lightDefs = - lightSourceDef.has("lights") ? lightSourceDef.getAsJsonArray("lights") : new JsonArray(); - - final var lights = new ArrayList(); - for (final var light : lightDefs) { - lights.add(parseLightJson(light.getAsJsonObject(), type)); - } - - final var lightSource = - LightSource.createRegular( - name, - existingSource.isPresent() ? existingSource.get().getId() : new GUID(), - type, - scaleWithToken, - lights); - token.addUniqueLightSource(lightSource); - MapTool.serverCommand() - .updateTokenProperty(token, Token.Update.createUniqueLightSource, lightSource); - return lightSource; - } - - private static void deleteUniqueLightSource(String name, Token token) { - final var sourcesToRemove = new ArrayList(); - for (final LightSource source : token.getUniqueLightSources()) { - if (name.equals(source.getName())) { - sourcesToRemove.add(source); - } - } - - for (final LightSource source : sourcesToRemove) { - token.removeUniqueLightSource(source.getId()); - MapTool.serverCommand() - .updateTokenProperty(token, Token.Update.deleteUniqueLightSource, source); - } - } - - private static JsonObject getUniqueLightSource(String name, Token token) { - for (final LightSource source : token.getUniqueLightSources()) { - if (name.equals(source.getName())) { - return lightSourceToJson(source); - } - } - - return null; - } - - private static JsonArray getUniqueLightSources(Token token) { - final var result = new JsonArray(); - - for (final LightSource source : token.getUniqueLightSources()) { - result.add(lightSourceToJson(source)); - } - - return result; - } - - private static JsonArray getUniqueLightSourceNames(Token token) { - final var result = new JsonArray(); - - for (final LightSource source : token.getUniqueLightSources()) { - result.add(source.getName()); - } - - return result; - } - - private static Light parseLightJson(JsonObject lightDef, LightSource.Type lightSourceType) - throws ParserException { - if (!lightDef.has("range")) { - throw new ParserException(I18N.getText("A range must be provided for each light")); - } - final var range = lightDef.get("range").getAsDouble(); - - final var shape = - lightDef.has("shape") - ? ShapeType.valueOf(lightDef.get("shape").getAsString()) - : ShapeType.CIRCLE; - // Cones permit the fields arc and offset, but no other shape accepts them. - if (shape != ShapeType.CONE) { - if (lightDef.has("offset")) { - throw new ParserException( - I18N.getText("Facing offset provided but the shape is not a cone")); - } - if (lightDef.has("arc")) { - throw new ParserException(I18N.getText("Arc provided but the shape is not a cone")); - } - } - final var offset = lightDef.has("offset") ? lightDef.get("offset").getAsDouble() : 0; - final var arc = lightDef.has("arc") ? lightDef.get("arc").getAsDouble() : 0; - - // Auras permit the gmOnly and ownerOnly flags, but no other type accepts them. - if (lightSourceType != LightSource.Type.AURA) { - if (lightDef.has("gmOnly")) { - throw new ParserException(I18N.getText("gmOnly flag provided but the type is not an aura")); - } - if (lightDef.has("ownerOnly")) { + if (lightSourcesMap.containsKey(category)) { + for (LightSource ls : lightSourcesMap.get(category).values()) { + if (ls.getName().equals(name) || "*".equals(name)) { + if (token.hasLightSource(ls)) { + return true; + } + } + } + } else { throw new ParserException( - I18N.getText("ownerOnly flag provided but the type is not an aura")); + I18N.getText("macro.function.tokenLight.unknownLightType", "hasLightSource", category)); } } - final var gmOnly = lightDef.has("gmOnly") ? !lightDef.get("gmOnly").getAsBoolean() : false; - final var ownerOnly = - lightDef.has("ownerOnly") ? !lightDef.get("ownerOnly").getAsBoolean() : false; - - final DrawableColorPaint colorPaint; - if (lightDef.has("color")) { - var colorString = lightDef.get("color").getAsString(); - if (!colorString.startsWith("#")) { - // Make sure it is parsed as a hex color string, not something else. - colorString = "#" + colorString; - } - - colorPaint = new DrawableColorPaint(Color.decode(colorString)); - } else { - colorPaint = null; - } - - final var lumens = lightDef.has("lumens") ? lightDef.get("lumens").getAsInt() : 100; - if (lumens == 0) { - throw new ParserException(I18N.getText("Lumens must be non-zero.")); - } - - return new Light(shape, offset, range, arc, colorPaint, lumens, gmOnly, ownerOnly); - } - - private static JsonObject lightSourceToJson(LightSource source) { - final var lightSourceDef = new JsonObject(); - lightSourceDef.addProperty("name", source.getName()); - lightSourceDef.addProperty("type", source.getType().toString()); - lightSourceDef.addProperty("scale", source.isScaleWithToken()); - - final var lightDefs = new JsonArray(); - for (final Light light : source.getLightList()) { - lightDefs.add(lightToJson(source, light)); - } - lightSourceDef.add("lights", lightDefs); - return lightSourceDef; - } - - private static JsonObject lightToJson(LightSource source, Light light) { - final var lightDef = new JsonObject(); - lightDef.addProperty("shape", light.getShape().toString()); - - if (light.getShape() == ShapeType.CONE) { - lightDef.addProperty("offset", light.getFacingOffset()); - lightDef.addProperty("arc", light.getArcAngle()); - } - if (source.getType() == LightSource.Type.AURA) { - lightDef.addProperty("gmOnly", light.isGM()); - lightDef.addProperty("ownerOnly", light.isOwnerOnly()); - } - - lightDef.addProperty("range", light.getRadius()); - if (light.getPaint() instanceof DrawableColorPaint paint) { - lightDef.addProperty("color", toHex(paint.getColor())); - } - lightDef.addProperty("lumens", light.getLumens()); - - return lightDef; - } - - private static String toHex(int rgb) { - return String.format("#%06X", rgb & 0x00FFFFFF); + return false; } } diff --git a/src/main/java/net/rptools/maptool/client/ui/AbstractTokenPopupMenu.java b/src/main/java/net/rptools/maptool/client/ui/AbstractTokenPopupMenu.java index 05376b49da..8cab678f65 100644 --- a/src/main/java/net/rptools/maptool/client/ui/AbstractTokenPopupMenu.java +++ b/src/main/java/net/rptools/maptool/client/ui/AbstractTokenPopupMenu.java @@ -22,8 +22,7 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -144,46 +143,31 @@ protected JMenu createLightSourceMenu() { } menu.addSeparator(); } - - // Add unique light sources for the token. - { - JMenu subMenu = createLightCategoryMenu("Unique", tokenUnderMouse.getUniqueLightSources()); - if (subMenu.getItemCount() != 0) { - menu.add(subMenu); - menu.addSeparator(); - } - } - for (Entry> entry : MapTool.getCampaign().getLightSourcesMap().entrySet()) { - JMenu subMenu = createLightCategoryMenu(entry.getKey(), entry.getValue().values()); - if (subMenu.getItemCount() != 0) { - menu.add(subMenu); - } - } - return menu; - } - - protected JMenu createLightCategoryMenu(String categoryName, Collection sources) { - JMenu subMenu = new JMenu(categoryName); - - List lightSources = new ArrayList<>(sources); - Collections.sort(lightSources); - - for (LightSource lightSource : lightSources) { - // Don't include light sources that don't have lights visible to the player. Note that the - // player must be an owner to use the popup, so don't bother checking `::isOwner()`. - boolean include = - MapTool.getPlayer().isGM() || !lightSource.getLightList().stream().allMatch(Light::isGM); - if (include) { + JMenu subMenu = new JMenu(entry.getKey()); + + List lightSources = new ArrayList(entry.getValue().values()); + LightSource[] lightSourceList = new LightSource[entry.getValue().size()]; + lightSources.toArray(lightSourceList); + Arrays.sort(lightSourceList); + LIGHTSOURCES: + for (LightSource lightSource : lightSourceList) { + for (Light light : lightSource.getLightList()) { + if (light.isGM() && !MapTool.getPlayer().isGM()) { + continue LIGHTSOURCES; + } + } JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(new ToggleLightSourceAction(lightSource)); menuItem.setSelected(tokenUnderMouse.hasLightSource(lightSource)); subMenu.add(menuItem); } + if (subMenu.getItemCount() != 0) { + menu.add(subMenu); + } } - - return subMenu; + return menu; } protected Token getTokenUnderMouse() { @@ -482,9 +466,9 @@ public void actionPerformed(ActionEvent e) { continue; } if (token.hasLightSource(lightSource)) { - token.removeLightSource(lightSource.getId()); + token.removeLightSource(lightSource); } else { - token.addLightSource(lightSource.getId()); + token.addLightSource(lightSource); } MapTool.serverCommand().putToken(renderer.getZone().getId(), token); diff --git a/src/main/java/net/rptools/maptool/client/ui/campaignproperties/CampaignPropertiesDialog.java b/src/main/java/net/rptools/maptool/client/ui/campaignproperties/CampaignPropertiesDialog.java index f143c3ea49..f968d99e4a 100644 --- a/src/main/java/net/rptools/maptool/client/ui/campaignproperties/CampaignPropertiesDialog.java +++ b/src/main/java/net/rptools/maptool/client/ui/campaignproperties/CampaignPropertiesDialog.java @@ -24,7 +24,6 @@ import java.io.LineNumberReader; import java.io.StringReader; import java.text.ParseException; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -489,8 +488,7 @@ private void commitSightMap(final String text) { } // Parse Details double magnifier = 1; - // If null, no personal light has been defined. - List personalLightLights = null; + LightSource personalLight = null; String[] args = value.split("\\s+"); ShapeType shape = ShapeType.CIRCLE; @@ -545,10 +543,11 @@ private void commitSightMap(final String text) { } } - if (personalLightLights == null) { - personalLightLights = new ArrayList<>(); + if (personalLight == null) { + personalLight = new LightSource(); + personalLight.setType(LightSource.Type.NORMAL); } - personalLightLights.add( + personalLight.add( new Light( shape, 0, @@ -560,6 +559,7 @@ private void commitSightMap(final String text) { perRangeLumens, false, false)); + personalLight.setScaleWithToken(scaleWithToken); } else { throw new ParseException( String.format("Unrecognized personal light syntax: %s", arg), 0); @@ -588,11 +588,6 @@ private void commitSightMap(final String text) { errlog.add(I18N.getText(errmsg, reader.getLineNumber(), toBeParsed)); } } - - LightSource personalLight = - personalLightLights == null - ? null - : LightSource.createPersonal(scaleWithToken, personalLightLights); SightType sight = new SightType(label, magnifier, personalLight, shape, arc, scaleWithToken); sight.setDistance(range); @@ -675,22 +670,14 @@ private Map> commitLightMap( continue; } - // region Light source properties. String name = line.substring(0, split).trim(); - GUID id = new GUID(); - LightSource.Type type = LightSource.Type.NORMAL; - boolean scaleWithToken = false; - List lights = new ArrayList<>(); - // endregion - // region Individual light properties + LightSource lightSource = new LightSource(name); ShapeType shape = ShapeType.CIRCLE; // TODO: Make a preference for default shape double arc = 0; double offset = 0; boolean gmOnly = false; boolean owner = false; String distance = null; - // endregion - for (String arg : line.substring(split + 1).split("\\s+")) { arg = arg.trim(); if (arg.length() == 0) { @@ -708,7 +695,7 @@ private Map> commitLightMap( } // Scale with token designation if (arg.equalsIgnoreCase("SCALE")) { - scaleWithToken = true; + lightSource.setScaleWithToken(true); continue; } // Shape designation ? @@ -721,7 +708,8 @@ private Map> commitLightMap( // Type designation ? try { - type = LightSource.Type.valueOf(arg.toUpperCase()); + LightSource.Type type = LightSource.Type.valueOf(arg.toUpperCase()); + lightSource.setType(type); continue; } catch (IllegalArgumentException iae) { // Expected when not defining a shape @@ -782,7 +770,7 @@ private Map> commitLightMap( } } - boolean isAura = type == LightSource.Type.AURA; + boolean isAura = lightSource.getType() == LightSource.Type.AURA; if (!isAura && (gmOnly || owner)) { errlog.add(I18N.getText("msg.error.mtprops.light.gmOrOwner", reader.getLineNumber())); gmOnly = false; @@ -800,26 +788,24 @@ private Map> commitLightMap( perRangeLumens, gmOnly, owner); - lights.add(t); + lightSource.add(t); } catch (ParseException pe) { errlog.add( I18N.getText("msg.error.mtprops.light.distance", reader.getLineNumber(), distance)); } } - // Keep ID the same if modifying existing light. This avoids tokens losing their lights when - // the light definition is modified. + // Keep ID the same if modifying existing light + // TODO FJE Why? Is there some benefit to doing so? Changes to light sources require the map + // to be re-rendered anyway, don't they? if (originalLightSourcesMap.containsKey(currentGroupName)) { for (LightSource ls : originalLightSourcesMap.get(currentGroupName).values()) { if (ls.getName().equalsIgnoreCase(name)) { - assert ls.getId() != null; - id = ls.getId(); + lightSource.setId(ls.getId()); break; } } } - - final var source = LightSource.createRegular(name, id, type, scaleWithToken, lights); - lightSourceMap.put(source.getId(), source); + lightSourceMap.put(lightSource.getId(), lightSource); } // Last group if (currentGroupName != null) { diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/LightSourceIconOverlay.java b/src/main/java/net/rptools/maptool/client/ui/zone/LightSourceIconOverlay.java index c1aed770f3..6561151fcd 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/LightSourceIconOverlay.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/LightSourceIconOverlay.java @@ -34,7 +34,8 @@ public void paintOverlay(ZoneRenderer renderer, Graphics2D g) { if (token.hasLightSources()) { boolean foundNormalLight = false; for (AttachedLightSource attachedLightSource : token.getLightSources()) { - LightSource lightSource = attachedLightSource.resolve(token, MapTool.getCampaign()); + LightSource lightSource = + MapTool.getCampaign().getLightSource(attachedLightSource.getLightSourceId()); if (lightSource != null && lightSource.getType() == LightSource.Type.NORMAL) { foundNormalLight = true; break; 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 e1ebef3454..b3c728bd56 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 @@ -295,7 +295,7 @@ private List calculateLitAreas(Token lightSourceToken, double for (final var attachedLightSource : lightSourceToken.getLightSources()) { LightSource lightSource = - attachedLightSource.resolve(lightSourceToken, MapTool.getCampaign()); + MapTool.getCampaign().getLightSource(attachedLightSource.getLightSourceId()); if (lightSource == null) { continue; } @@ -653,7 +653,7 @@ public List getDrawableAuras() { Point p = FogUtil.calculateVisionCenter(token, zone); for (AttachedLightSource als : token.getLightSources()) { - LightSource lightSource = als.resolve(token, MapTool.getCampaign()); + LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); if (lightSource == null) { continue; } @@ -721,7 +721,7 @@ private void findLightSources() { if (token.hasLightSources() && token.isVisible()) { if (!token.isVisibleOnlyToOwner() || AppUtil.playerOwns(token)) { for (AttachedLightSource als : token.getLightSources()) { - LightSource lightSource = als.resolve(token, MapTool.getCampaign()); + LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); if (lightSource == null) { continue; } @@ -911,7 +911,7 @@ private void onTokensRemoved(TokensRemoved event) { for (Token token : event.tokens()) { if (token.hasAnyTopology()) tokenChangedTopology = true; for (AttachedLightSource als : token.getLightSources()) { - LightSource lightSource = als.resolve(token, MapTool.getCampaign()); + LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); if (lightSource == null) { continue; } @@ -966,7 +966,7 @@ private boolean processTokenAddChangeEvent(List tokens) { token.hasLightSources() && (token.isVisible() || MapTool.getPlayer().isEffectiveGM()); if (token.hasAnyTopology()) hasTopology = true; for (AttachedLightSource als : token.getLightSources()) { - LightSource lightSource = als.resolve(token, c); + LightSource lightSource = c.getLightSource(als.getLightSourceId()); if (lightSource != null) { Set lightSet = lightSourceMap.get(lightSource.getType()); if (hasLightSource) { diff --git a/src/main/java/net/rptools/maptool/model/AttachedLightSource.java b/src/main/java/net/rptools/maptool/model/AttachedLightSource.java index 03568e342b..3502c4f681 100644 --- a/src/main/java/net/rptools/maptool/model/AttachedLightSource.java +++ b/src/main/java/net/rptools/maptool/model/AttachedLightSource.java @@ -14,51 +14,26 @@ */ package net.rptools.maptool.model; -import java.util.Map; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import net.rptools.maptool.server.proto.AttachedLightSourceDto; -public final class AttachedLightSource { +public class AttachedLightSource { - private final @Nonnull GUID lightSourceId; + private GUID lightSourceId; - public AttachedLightSource(@Nonnull GUID lightSourceId) { - this.lightSourceId = lightSourceId; + public AttachedLightSource() { + // for serialization } - /** - * Obtain the attached {@code LightSource} from the token or campaign. - * - * @param token The token in which to look up light source IDs. - * @param campaign The campaign in which to look up light source IDs. - * @return The {@code LightSource} referenced by this {@code AttachedLightSource}, or {@code null} - * if no such light source exists. - */ - public @Nullable LightSource resolve(Token token, Campaign campaign) { - final var uniqueLightSource = token.getUniqueLightSource(lightSourceId); - if (uniqueLightSource != null) { - return uniqueLightSource; - } - - for (Map map : campaign.getLightSourcesMap().values()) { - if (map.containsKey(lightSourceId)) { - return map.get(lightSourceId); - } - } + private AttachedLightSource(GUID lightSourceId) { + this.lightSourceId = lightSourceId; + } - return null; + public AttachedLightSource(LightSource source) { + lightSourceId = source.getId(); } - /** - * Check if this {@code AttachedLightSource} references a {@code LightSource} with a matching ID. - * - * @param lightSourceId The ID of the light source to match against. - * @return {@code true} If {@code lightSourceId} is the same as the ID of the attached light - * source. - */ - public boolean matches(@Nonnull GUID lightSourceId) { - return lightSourceId.equals(this.lightSourceId); + public GUID getLightSourceId() { + return lightSourceId; } public static AttachedLightSource fromDto(AttachedLightSourceDto dto) { @@ -67,7 +42,7 @@ public static AttachedLightSource fromDto(AttachedLightSourceDto dto) { public AttachedLightSourceDto toDto() { var dto = AttachedLightSourceDto.newBuilder(); - dto.setLightSourceId(lightSourceId.toString()); + dto.setLightSourceId(getLightSourceId().toString()); return dto.build(); } } diff --git a/src/main/java/net/rptools/maptool/model/Campaign.java b/src/main/java/net/rptools/maptool/model/Campaign.java index 805f477471..a48ac05501 100644 --- a/src/main/java/net/rptools/maptool/model/Campaign.java +++ b/src/main/java/net/rptools/maptool/model/Campaign.java @@ -328,6 +328,23 @@ public List getLookupTables() { return list; } + /** + * Convenience method that iterates through {@link #getLightSourcesMap()} and returns the value + * for the key lightSourceId. + * + * @param lightSourceId the id to look for + * @return the {@link LightSource} or null if not found + */ + public LightSource getLightSource(GUID lightSourceId) { + + for (Map map : getLightSourcesMap().values()) { + if (map.containsKey(lightSourceId)) { + return map.get(lightSourceId); + } + } + return null; + } + /** * Stub that calls campaignProperties.getLightSourcesMap(). * diff --git a/src/main/java/net/rptools/maptool/model/Light.java b/src/main/java/net/rptools/maptool/model/Light.java index 95315a87a3..67981b9dce 100644 --- a/src/main/java/net/rptools/maptool/model/Light.java +++ b/src/main/java/net/rptools/maptool/model/Light.java @@ -23,7 +23,7 @@ import net.rptools.maptool.server.proto.LightDto; import net.rptools.maptool.server.proto.ShapeTypeDto; -public final class Light implements Serializable { +public class Light implements Serializable { private final @Nonnull ShapeType shape; private final double facingOffset; private final double radius; diff --git a/src/main/java/net/rptools/maptool/model/LightSource.java b/src/main/java/net/rptools/maptool/model/LightSource.java index 0da670d38e..a633a70e99 100644 --- a/src/main/java/net/rptools/maptool/model/LightSource.java +++ b/src/main/java/net/rptools/maptool/model/LightSource.java @@ -14,7 +14,6 @@ */ package net.rptools.maptool.model; -import com.google.common.collect.ImmutableList; import com.google.protobuf.StringValue; import java.awt.geom.Area; import java.io.IOException; @@ -23,6 +22,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -33,35 +33,16 @@ import net.rptools.maptool.server.proto.LightSourceDto; import org.apache.commons.lang.math.NumberUtils; -/** - * Represents a light source that can be attached to tokens. - * - *

This class is immutable. - */ -public final class LightSource implements Comparable, Serializable { +public class LightSource implements Comparable, Serializable { public enum Type { NORMAL, AURA } - private final @Nullable String name; - private final @Nullable GUID id; - private final @Nonnull Type type; - private final boolean scaleWithToken; - - /** - * This light segments that make up the light source. - * - *

In practice this will be an {@code ImmutableList} during runtime. However, previously - * serialized {@code LightSource} instances may have specified that it must be a {@code - * LinkedList} or other specific {@code List} implementation. So we need to keep this as a {@code - * List} in order to deserialize those. - * - *

There is also one case where it won't be an {@code ImmutableList}, and that is during - * serialization. At such a time, a temporary {@code LightSource} is created with an {@code - * ArrayList} instead. (see {@link #writeReplace()}) so that the XML does not depend on the use of - * {@code ImmutableList} or any other particular {@code List} implementation. - */ + private @Nullable String name; + private @Nullable GUID id; + private @Nonnull Type type; + private boolean scaleWithToken; private final @Nonnull List lightList; // Lumens are now in the individual Lights. This field is only here for backwards compatibility @@ -73,32 +54,21 @@ public enum Type { * *

Since a personal light source is directly attached to a specific sight type, they do not * need (or have) names and GUIDs. - * - * @param scaleWithToken if {@code true}, the size of the lights will scale with the token size. - * @param lights The set of lights that constitute the personal light source. */ - public static LightSource createPersonal(boolean scaleWithToken, Collection lights) { - return new LightSource(null, null, Type.NORMAL, scaleWithToken, ImmutableList.copyOf(lights)); + public LightSource() { + this(null, null, Type.NORMAL, false, Collections.emptyList()); } /** * Constructs a non-personal light source. * - *

These light sources are referenced both by name and GUID, and thus need both. + *

These light sources are referenced both by name and GUID, and thus need both. A new GUID + * will be created automatically. * * @param name The name of the light source. - * @param id The unique ID of the light source. - * @param type The type of light, whether a normal light or an aura. - * @param scaleWithToken if {@code true}, the size of the lights will scale with the token size. - * @param lights The set of lights that constitute the personal light source. */ - public static LightSource createRegular( - @Nonnull String name, - @Nonnull GUID id, - @Nonnull Type type, - boolean scaleWithToken, - @Nonnull Collection lights) { - return new LightSource(name, id, type, scaleWithToken, ImmutableList.copyOf(lights)); + public LightSource(@Nonnull String name) { + this(name, new GUID(), Type.NORMAL, false, Collections.emptyList()); } private LightSource( @@ -106,19 +76,14 @@ private LightSource( @Nullable GUID id, @Nonnull Type type, boolean scaleWithToken, - @Nonnull List lights) { + @Nonnull Collection lights) { this.name = name; this.id = id; this.type = type; this.scaleWithToken = scaleWithToken; - this.lightList = lights; - } - @Serial - public Object writeReplace() { - // Make sure XStream keeps the serialization nice. We don't need the XML to contain - // implementation details of the ImmutableList in use. - return new LightSource(name, id, type, scaleWithToken, new ArrayList<>(lightList)); + this.lightList = new LinkedList<>(); + this.lightList.addAll(lights); } @SuppressWarnings("ConstantConditions") @@ -128,7 +93,7 @@ public Object writeReplace() { Objects.requireNonNullElse(lightList, Collections.emptyList()); final List lights; if (lumens == Integer.MIN_VALUE) { - // This is an up-to-date LightSource with lumens already stored in the Lights. + // This is an up-to-date Lightsource with lumens already stored in the Lights. lights = originalLights; } else { // This is an old light source with a lumens value that needs to be pushed into the individual @@ -155,7 +120,7 @@ public Object writeReplace() { this.id, Objects.requireNonNullElse(this.type, Type.NORMAL), this.scaleWithToken, - ImmutableList.copyOf(lights)); + lights); } @Override @@ -179,6 +144,10 @@ public int hashCode() { return Objects.hashCode(id); } + public void setId(@Nonnull GUID id) { + this.id = id; + } + public @Nullable GUID getId() { return id; } @@ -187,17 +156,37 @@ public int hashCode() { return name; } + public void setName(@Nonnull String name) { + this.name = name; + } + + public void add(@Nonnull Light source) { + lightList.add(source); + } + + public void remove(@Nonnull Light source) { + lightList.remove(source); + } + /** - * @return A read-only list of lights belonging to this LightSource + * @return the lights belonging to this LightSource. */ public @Nonnull List getLightList() { - return lightList; + return Collections.unmodifiableList(lightList); } public @Nonnull Type getType() { return type; } + public void setType(@Nonnull Type type) { + this.type = type; + } + + public void setScaleWithToken(boolean scaleWithToken) { + this.scaleWithToken = scaleWithToken; + } + public boolean isScaleWithToken() { return scaleWithToken; } @@ -266,7 +255,7 @@ public int compareTo(@Nonnull LightSource o) { dto.hasId() ? GUID.valueOf(dto.getId().getValue()) : null, Type.valueOf(dto.getType().name()), dto.getScaleWithToken(), - dto.getLightsList().stream().map(Light::fromDto).collect(ImmutableList.toImmutableList())); + dto.getLightsList().stream().map(Light::fromDto).toList()); } public @Nonnull LightSourceDto toDto() { diff --git a/src/main/java/net/rptools/maptool/model/SightType.java b/src/main/java/net/rptools/maptool/model/SightType.java index 083d1db9e5..42abf38eab 100644 --- a/src/main/java/net/rptools/maptool/model/SightType.java +++ b/src/main/java/net/rptools/maptool/model/SightType.java @@ -15,7 +15,6 @@ package net.rptools.maptool.model; import java.awt.geom.Area; -import javax.annotation.Nullable; import net.rptools.maptool.server.proto.ShapeTypeDto; import net.rptools.maptool.server.proto.SightTypeDto; @@ -65,12 +64,12 @@ public SightType() { // For serialization } - public SightType(String name, double multiplier, @Nullable LightSource personalLightSource) { + public SightType(String name, double multiplier, LightSource personalLightSource) { this(name, multiplier, personalLightSource, ShapeType.CIRCLE); } public SightType( - String name, double multiplier, @Nullable LightSource personalLightSource, ShapeType shape) { + String name, double multiplier, LightSource personalLightSource, ShapeType shape) { this.name = name; this.multiplier = multiplier; this.personalLightSource = personalLightSource; diff --git a/src/main/java/net/rptools/maptool/model/Token.java b/src/main/java/net/rptools/maptool/model/Token.java index d0ba4bd371..778474a986 100644 --- a/src/main/java/net/rptools/maptool/model/Token.java +++ b/src/main/java/net/rptools/maptool/model/Token.java @@ -211,8 +211,6 @@ public enum Update { setPortraitImage, setCharsheetImage, setLayout, - createUniqueLightSource, - deleteUniqueLightSource, clearLightSources, removeLightSource, addLightSource, @@ -337,7 +335,6 @@ public String toString() { private MD5Key charsheetImage; private MD5Key portraitImage; - private Map uniqueLightSources = new LinkedHashMap<>(); private List lightSourceList = new ArrayList<>(); private String sightType; private boolean hasSight; @@ -476,10 +473,7 @@ public Token(Token token) { ownerType = token.ownerType; ownerList.addAll(token.ownerList); - - uniqueLightSources.putAll(token.uniqueLightSources); lightSourceList.addAll(token.lightSourceList); - state.putAll(token.state); getPropertyMap().clear(); getPropertyMap().putAll(token.propertyMapCI); @@ -924,30 +918,14 @@ public String getImageTableName() { return imageTableName; } - public @Nonnull Collection getUniqueLightSources() { - return uniqueLightSources.values(); - } - - public @Nullable LightSource getUniqueLightSource(GUID lightSourceId) { - return uniqueLightSources.getOrDefault(lightSourceId, null); - } - - public void addUniqueLightSource(LightSource source) { - uniqueLightSources.put(source.getId(), source); - } - - public void removeUniqueLightSource(GUID lightSourceId) { - uniqueLightSources.remove(lightSourceId); - } - - public void addLightSource(GUID lightSourceId) { - lightSourceList.add(new AttachedLightSource(lightSourceId)); + public void addLightSource(LightSource source) { + lightSourceList.add(new AttachedLightSource(source)); } public void removeLightSourceType(LightSource.Type lightType) { for (ListIterator i = lightSourceList.listIterator(); i.hasNext(); ) { AttachedLightSource als = i.next(); - LightSource lightSource = als.resolve(this, MapTool.getCampaign()); + LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); if (lightSource != null && lightSource.getType() == lightType) { i.remove(); } @@ -957,7 +935,7 @@ public void removeLightSourceType(LightSource.Type lightType) { public void removeGMAuras() { for (ListIterator i = lightSourceList.listIterator(); i.hasNext(); ) { AttachedLightSource als = i.next(); - LightSource lightSource = als.resolve(this, MapTool.getCampaign()); + LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); if (lightSource != null) { List lights = lightSource.getLightList(); for (Light light : lights) { @@ -972,7 +950,7 @@ public void removeGMAuras() { public void removeOwnerOnlyAuras() { for (ListIterator i = lightSourceList.listIterator(); i.hasNext(); ) { AttachedLightSource als = i.next(); - LightSource lightSource = als.resolve(this, MapTool.getCampaign()); + LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); if (lightSource != null) { List lights = lightSource.getLightList(); for (Light light : lights) { @@ -986,7 +964,7 @@ public void removeOwnerOnlyAuras() { public boolean hasOwnerOnlyAuras() { for (AttachedLightSource als : lightSourceList) { - LightSource lightSource = als.resolve(this, MapTool.getCampaign()); + LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); if (lightSource != null) { List lights = lightSource.getLightList(); for (Light light : lights) { @@ -1001,7 +979,7 @@ public boolean hasOwnerOnlyAuras() { public boolean hasGMAuras() { for (AttachedLightSource als : lightSourceList) { - LightSource lightSource = als.resolve(this, MapTool.getCampaign()); + LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); if (lightSource != null) { List lights = lightSource.getLightList(); for (Light light : lights) { @@ -1016,7 +994,7 @@ public boolean hasGMAuras() { public boolean hasLightSourceType(LightSource.Type lightType) { for (AttachedLightSource als : lightSourceList) { - LightSource lightSource = als.resolve(this, MapTool.getCampaign()); + LightSource lightSource = MapTool.getCampaign().getLightSource(als.getLightSourceId()); if (lightSource != null && lightSource.getType() == lightType) { return true; } @@ -1024,8 +1002,12 @@ public boolean hasLightSourceType(LightSource.Type lightType) { return false; } - public void removeLightSource(GUID lightSourceId) { - lightSourceList.removeIf(als -> als.matches(lightSourceId)); + public void removeLightSource(LightSource source) { + lightSourceList.removeIf( + als -> + als != null + && als.getLightSourceId() != null + && als.getLightSourceId().equals(source.getId())); } /** Clear the lightSourceList */ @@ -1034,13 +1016,13 @@ public void clearLightSources() { } public boolean hasLightSource(LightSource source) { - if (source.getId() == null) { - // Shouldn't happen as this method should only be used with non-personal lights. + if (lightSourceList.size() == 0) { return false; } - for (AttachedLightSource als : lightSourceList) { - if (als.matches(source.getId())) { + if (als != null + && als.getLightSourceId() != null + && als.getLightSourceId().equals(source.getId())) { return true; } } @@ -2522,16 +2504,9 @@ protected Object readResolve() { if (ownerList == null) { ownerList = new HashSet<>(); } - if (uniqueLightSources == null) { - uniqueLightSources = new LinkedHashMap<>(); - } if (lightSourceList == null) { lightSourceList = new ArrayList<>(); } - // There used to be checks elsewhere that elements were not null. In case those were legitimate, - // let's filter them out here instead. - lightSourceList.removeIf(Objects::isNull); - if (macroPropertiesMap == null) { macroPropertiesMap = new HashMap<>(); } @@ -2838,14 +2813,6 @@ public void updateProperty(Zone zone, Update update, List setSizeScale(parameters.get(0).getDoubleValue()); setAnchor(parameters.get(1).getIntValue(), parameters.get(2).getIntValue()); break; - case createUniqueLightSource: - lightChanged = true; - addUniqueLightSource(LightSource.fromDto(parameters.get(0).getLightSource())); - break; - case deleteUniqueLightSource: - lightChanged = true; - removeUniqueLightSource(GUID.valueOf(parameters.get(0).getLightSourceId())); - break; case clearLightSources: if (hasLightSources()) { lightChanged = true; @@ -2856,11 +2823,11 @@ public void updateProperty(Zone zone, Update update, List if (hasLightSources()) { lightChanged = true; } - removeLightSource(GUID.valueOf(parameters.get(0).getLightSourceId())); + removeLightSource(LightSource.fromDto(parameters.get(0).getLightSource())); break; case addLightSource: lightChanged = true; - addLightSource(GUID.valueOf(parameters.get(0).getLightSourceId())); + addLightSource(LightSource.fromDto(parameters.get(0).getLightSource())); break; case setHasSight: if (hasLightSources()) { @@ -2979,10 +2946,6 @@ public static Token fromDto(TokenDto dto) { dto.hasCharsheetImage() ? new MD5Key(dto.getCharsheetImage().getValue()) : null; token.portraitImage = dto.hasPortraitImage() ? new MD5Key(dto.getPortraitImage().getValue()) : null; - - dto.getUniqueLightSourcesList().stream() - .map(LightSource::fromDto) - .forEach(source -> token.uniqueLightSources.put(source.getId(), source)); token.lightSourceList.addAll( dto.getLightSourcesList().stream() .map(AttachedLightSource::fromDto) @@ -3110,8 +3073,6 @@ public TokenDto toDto() { if (portraitImage != null) { dto.setPortraitImage(StringValue.of(portraitImage.toString())); } - dto.addAllUniqueLightSources( - uniqueLightSources.values().stream().map(LightSource::toDto).collect(Collectors.toList())); dto.addAllLightSources( lightSourceList.stream().map(AttachedLightSource::toDto).collect(Collectors.toList())); if (sightType != null) { diff --git a/src/main/java/net/rptools/maptool/server/ServerCommand.java b/src/main/java/net/rptools/maptool/server/ServerCommand.java index 7edec64833..ae411df169 100644 --- a/src/main/java/net/rptools/maptool/server/ServerCommand.java +++ b/src/main/java/net/rptools/maptool/server/ServerCommand.java @@ -204,6 +204,8 @@ void updateTokenProperty( void updateTokenProperty(Token token, Token.Update update, LightSource value); + void updateTokenProperty(Token token, Token.Update update, LightSource value1, String value2); + void updateTokenProperty(Token token, Token.Update update, int value1, int value2); void updateTokenProperty(Token token, Token.Update update, boolean value); diff --git a/src/main/java/net/rptools/maptool/tool/LightSourceCreator.java b/src/main/java/net/rptools/maptool/tool/LightSourceCreator.java index 0379f1eb29..a6d2fe74bf 100644 --- a/src/main/java/net/rptools/maptool/tool/LightSourceCreator.java +++ b/src/main/java/net/rptools/maptool/tool/LightSourceCreator.java @@ -21,7 +21,6 @@ import java.util.List; import java.util.Map; import net.rptools.lib.FileUtil; -import net.rptools.maptool.model.GUID; import net.rptools.maptool.model.Light; import net.rptools.maptool.model.LightSource; import net.rptools.maptool.model.ShapeType; @@ -58,30 +57,28 @@ public static void main(String[] args) { } private static LightSource createLightSource(String name, double radius, double arcAngle) { - return LightSource.createRegular( - name, - new GUID(), - LightSource.Type.NORMAL, - false, - List.of(new Light(ShapeType.CIRCLE, 0, radius, arcAngle, null, 100, false, false))); + LightSource source = new LightSource(name); + // source.add(new Light(0, 5, arcAngle, new DrawableColorPaint(new Color(255, 255, 0, 50)))); + source.add(new Light(ShapeType.CIRCLE, 0, radius, arcAngle, null, 100, false, false)); + return source; } private static LightSource createD20LightSource(String name, double radius, double arcAngle) { - return LightSource.createRegular( - name, - new GUID(), - LightSource.Type.NORMAL, - false, - List.of( - new Light(ShapeType.CIRCLE, 0, radius, arcAngle, null, 100, false, false), - new Light( - ShapeType.CIRCLE, - 0, - radius * 2, - arcAngle, - new DrawableColorPaint(new Color(0, 0, 0, 100)), - 100, - false, - false))); + LightSource source = new LightSource(name); + + // source.add(new Light(0, 5, arcAngle, new DrawableColorPaint(new Color(255, 255, 0, 50)))); + source.add(new Light(ShapeType.CIRCLE, 0, radius, arcAngle, null, 100, false, false)); + source.add( + new Light( + ShapeType.CIRCLE, + 0, + radius * 2, + arcAngle, + new DrawableColorPaint(new Color(0, 0, 0, 100)), + 100, + false, + false)); + + return source; } } diff --git a/src/main/proto/data_transfer_objects.proto b/src/main/proto/data_transfer_objects.proto index bf17d44571..ab95750696 100644 --- a/src/main/proto/data_transfer_objects.proto +++ b/src/main/proto/data_transfer_objects.proto @@ -342,7 +342,6 @@ message TokenDto { bool is_flipped_iso = 47; google.protobuf.StringValue charsheet_image = 48; google.protobuf.StringValue portrait_image = 49; - repeated LightSourceDto unique_light_sources = 72; repeated AttachedLightSourceDto light_sources = 50; google.protobuf.StringValue sight_type = 51; bool has_sight = 52; @@ -645,18 +644,16 @@ enum TokenUpdateDto { setPortraitImage = 43; setCharsheetImage = 44; setLayout = 45; - createUniqueLightSource = 46; - deleteUniqueLightSource = 47; - clearLightSources = 48; - removeLightSource = 49; - addLightSource = 50; - setHasSight = 51; - setSightType = 52; - flipX = 53; - flipY = 54; - flipIso = 55; - setSpeechName = 56; - removeFacing = 57; + clearLightSources = 46; + removeLightSource = 47; + addLightSource = 48; + setHasSight = 49; + setSightType = 50; + flipX = 51; + flipY = 52; + flipIso = 53; + setSpeechName = 54; + removeFacing = 55; } message AssetTransferHeaderDto { @@ -677,13 +674,12 @@ message TokenPropertyValueDto { string string_value = 3; double double_value = 4; MacroButtonPropertiesListDto macros = 5; - string light_source_id = 6; - LightSourceDto light_source = 7; - AreaDto area = 8; - StringListDto string_values = 9; - GridDto grid = 10; - TokenFootPrintDto token_foot_print = 11; - string topology_type = 12; + LightSourceDto light_source = 6; + AreaDto area = 7; + StringListDto string_values = 8; + GridDto grid = 9; + TokenFootPrintDto token_foot_print = 10; + string topology_type = 11; } }