From f752cd68feba2a5562069a7ff0e819c6b5121902 Mon Sep 17 00:00:00 2001 From: bubblobill <45483160+bubblobill@users.noreply.github.com> Date: Wed, 22 Nov 2023 01:33:50 +0800 Subject: [PATCH 1/2] All this in order to introduce ShapeType.LINE --- .../client/functions/TokenLightFunctions.java | 7 +- .../CampaignPropertiesDialog.java | 16 +++- .../java/net/rptools/maptool/model/Grid.java | 48 +++++----- .../net/rptools/maptool/model/ShapeType.java | 5 +- .../maptool/tool/LightSourceCreator.java | 47 +++++++--- src/main/proto/data_transfer_objects.proto | 1 + .../rptools/maptool/language/i18n.properties | 77 +++++++++++++--- .../maptool/language/i18n_en_au.properties | 85 ++++++++++++++---- .../maptool/language/i18n_en_gb.properties | 87 +++++++++++++++---- 9 files changed, 289 insertions(+), 84 deletions(-) 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..2fd5ee2528 100644 --- a/src/main/java/net/rptools/maptool/client/functions/TokenLightFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/TokenLightFunctions.java @@ -400,7 +400,7 @@ private static Light parseLightJson(JsonObject lightDef, LightSource.Type lightS ? 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 (shape != ShapeType.CONE && shape != ShapeType.LINE) { if (lightDef.has("offset")) { throw new ParserException( I18N.getText("Facing offset provided but the shape is not a cone")); @@ -465,6 +465,11 @@ private static JsonObject lightToJson(LightSource source, Light light) { final var lightDef = new JsonObject(); lightDef.addProperty("shape", light.getShape().toString()); + if (light.getShape() == ShapeType.LINE) { + lightDef.addProperty("offset", light.getFacingOffset()); + lightDef.addProperty("arc", light.getArcAngle()); + } + if (light.getShape() == ShapeType.CONE) { lightDef.addProperty("offset", light.getFacingOffset()); lightDef.addProperty("arc", light.getArcAngle()); 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 63bf6fcb29..678b790b08 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 @@ -373,6 +373,17 @@ private String updateLightPanel(Map> lightSources // TODO: Make this a preference shape = light.getShape().toString().toLowerCase(); break; + case LINE: + { + lastArc = light.getArcAngle(); + shape = "line arc=" + StringUtil.formatDecimal(lastArc); + if (light.getFacingOffset() != 0) + builder + .append(" offset=") + .append(StringUtil.formatDecimal(light.getFacingOffset())) + .append(' '); + } + break; case CONE: // if (light.getArcAngle() != 0 && light.getArcAngle() != 90 && light.getArcAngle() // != lastArc) @@ -748,7 +759,10 @@ private Map> commitLightMap( if ("arc".equalsIgnoreCase(key)) { try { arc = StringUtil.parseDecimal(value); - shape = ShapeType.CONE; // If the user specifies an arc, force the shape to CONE + shape = + (shape != ShapeType.CONE && shape != ShapeType.LINE) + ? ShapeType.CONE + : shape; // If the user specifies an arc, force the shape to CONE } catch (ParseException pe) { errlog.add( I18N.getText("msg.error.mtprops.light.arc", reader.getLineNumber(), value)); diff --git a/src/main/java/net/rptools/maptool/model/Grid.java b/src/main/java/net/rptools/maptool/model/Grid.java index b53e8f9457..4ab1764f60 100644 --- a/src/main/java/net/rptools/maptool/model/Grid.java +++ b/src/main/java/net/rptools/maptool/model/Grid.java @@ -14,17 +14,8 @@ */ package net.rptools.maptool.model; -import com.google.common.base.Stopwatch; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.geom.AffineTransform; -import java.awt.geom.Arc2D; -import java.awt.geom.Area; -import java.awt.geom.GeneralPath; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; +import java.awt.*; +import java.awt.geom.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.HashSet; @@ -32,7 +23,6 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; import javax.swing.Action; import javax.swing.KeyStroke; import net.rptools.lib.FileUtil; @@ -352,7 +342,7 @@ public void setSize(int size) { /** * Called by SightType and Light class to return a vision area based upon a specified distance * - * @param shape CIRCLE, GRID, SQUARE or CONE + * @param shape CIRCLE, GRID, SQUARE, CONE or LINE * @param token Used to position the shape and to provide footprint * @param range As specified in the vision or light definition * @param arcAngle Only used by cone @@ -404,6 +394,24 @@ public Area getShapedArea( new Rectangle2D.Double( -visionRange, -visionRange, visionRange * 2, visionRange * 2)); break; + case LINE: + if (token.getFacing() == null) { + token.setFacing(0); + } + Shape lineShape = + new Rectangle2D.Double( + 0, + getSize() / -2d * Math.sin(Math.toRadians(arcAngle / 2d)), + visionRange, + getSize() * Math.sin(Math.toRadians(arcAngle / 2d))); + Shape visibleShape = new GeneralPath(lineShape); + + visibleArea = + new Area( + AffineTransform.getRotateInstance( + Math.toRadians(offsetAngle) - Math.toRadians(token.getFacing())) + .createTransformedShape(visibleShape)); + break; case CONE: if (token.getFacing() == null) { token.setFacing(0); @@ -749,7 +757,7 @@ protected Area getGridArea( final Area visibleArea; if (range > 0) { - final Stopwatch stopwatch = Stopwatch.createStarted(); + // final Stopwatch stopwatch = Stopwatch.createStarted(); final int gridRadius = (int) (range / getZone().getUnitsPerCell()); if (scaleWithToken) { @@ -758,12 +766,12 @@ protected Area getGridArea( visibleArea = getGridAreaFromCache(gridRadius).createTransformedArea(getGridOffset(token)); } - if (stopwatch.elapsed(TimeUnit.MILLISECONDS) > 50) { - log.debug( - "Excessive time to generate {}r grid light, took {}ms", - gridRadius, - stopwatch.elapsed(TimeUnit.MILLISECONDS)); - } + // if (stopwatch.elapsed(TimeUnit.MILLISECONDS) > 50) { + // log.debug( + // "Excessive time to generate {}r grid light, took {}ms", + // gridRadius, + // stopwatch.elapsed(TimeUnit.MILLISECONDS)); + // } } else { // Fall back to regular circle in daylight, etc. visibleArea = diff --git a/src/main/java/net/rptools/maptool/model/ShapeType.java b/src/main/java/net/rptools/maptool/model/ShapeType.java index 4e85f16e2f..ac6e58a3b8 100644 --- a/src/main/java/net/rptools/maptool/model/ShapeType.java +++ b/src/main/java/net/rptools/maptool/model/ShapeType.java @@ -15,9 +15,10 @@ package net.rptools.maptool.model; public enum ShapeType { - SQUARE, CIRCLE, CONE, + GRID, HEX, - GRID + LINE, + SQUARE } diff --git a/src/main/java/net/rptools/maptool/tool/LightSourceCreator.java b/src/main/java/net/rptools/maptool/tool/LightSourceCreator.java index 0379f1eb29..dcee535bb4 100644 --- a/src/main/java/net/rptools/maptool/tool/LightSourceCreator.java +++ b/src/main/java/net/rptools/maptool/tool/LightSourceCreator.java @@ -26,8 +26,23 @@ import net.rptools.maptool.model.LightSource; import net.rptools.maptool.model.ShapeType; import net.rptools.maptool.model.drawing.DrawableColorPaint; +import net.rptools.maptool.model.drawing.DrawablePaint; public class LightSourceCreator { + private static Light createLight( + ShapeType shape, + double radius, + double arcAngle, + double offset, + DrawablePaint paint, + int lumens, + boolean isGM, + boolean ownerOnly) { + if (arcAngle == 0) arcAngle = 360; + shape = shape == null ? ShapeType.CIRCLE : shape; + return new Light(shape, offset, radius, arcAngle, paint, lumens, isGM, ownerOnly); + } + public static void main(String[] args) { Map> lightSourcesMap = new HashMap>(); @@ -44,26 +59,34 @@ public static void main(String[] args) { lightSourceList = new ArrayList(); - lightSourceList.add(createLightSource("5", 5, 360)); - lightSourceList.add(createLightSource("15", 15, 360)); - lightSourceList.add(createLightSource("20", 20, 360)); - lightSourceList.add(createLightSource("30", 30, 360)); - lightSourceList.add(createLightSource("40", 40, 360)); - lightSourceList.add(createLightSource("60", 60, 360)); + lightSourceList.add(createCircleLightSource("5", 5, 360)); + lightSourceList.add(createCircleLightSource("15", 15, 360)); + lightSourceList.add(createCircleLightSource("20", 20, 360)); + lightSourceList.add(createCircleLightSource("30", 30, 360)); + lightSourceList.add(createCircleLightSource("40", 40, 360)); + lightSourceList.add(createCircleLightSource("60", 60, 360)); lightSourcesMap.put("Generic", lightSourceList); + // lightSourceList = new ArrayList(); + // + // lightSourceList.add(createLightSource("Front", 5, 360)); + // + // lightSourcesMap.put("Auras", lightSourceList); + XStream xstream = FileUtil.getConfiguredXStream(); System.out.println(xstream.toXML(lightSourcesMap)); } - private static LightSource createLightSource(String name, double radius, double arcAngle) { + // private static LightSource createLightSource(String name, double radius, double arcAngle) { + // } + private static LightSource createCircleLightSource(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))); + List.of(createLight(ShapeType.CIRCLE, radius, arcAngle, 0d, null, 100, false, false))); } private static LightSource createD20LightSource(String name, double radius, double arcAngle) { @@ -73,12 +96,12 @@ private static LightSource createD20LightSource(String name, double radius, doub LightSource.Type.NORMAL, false, List.of( - new Light(ShapeType.CIRCLE, 0, radius, arcAngle, null, 100, false, false), - new Light( + createLight(ShapeType.CIRCLE, radius, arcAngle, 0d, null, 100, false, false), + createLight( ShapeType.CIRCLE, - 0, - radius * 2, + 2 * radius, arcAngle, + 0d, new DrawableColorPaint(new Color(0, 0, 0, 100)), 100, false, diff --git a/src/main/proto/data_transfer_objects.proto b/src/main/proto/data_transfer_objects.proto index 8241614bca..66e7104a3f 100644 --- a/src/main/proto/data_transfer_objects.proto +++ b/src/main/proto/data_transfer_objects.proto @@ -83,6 +83,7 @@ enum ShapeTypeDto { CONE = 2; HEX = 3; GRID = 4; + LINE = 5; } message LightDto { diff --git a/src/main/resources/net/rptools/maptool/language/i18n.properties b/src/main/resources/net/rptools/maptool/language/i18n.properties index 4d85811bc1..4e4c025dd5 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n.properties @@ -845,12 +845,13 @@ CampaignPropertiesDialog.label.sight = \ defaults for all values (e.g. Normal vision).

\

Options:

\
\ -
shape
shape may be circle, square, hex, grid or cone
\ -
distance=y
Distance is the range at which this vision type ends. Can be a decimal value. Ex: distance=10
\ +
shape
shape may be circle, square, hex, grid, cone or line
\ +
distance=y
Distance is the range at which this vision type ends. Can be a decimal value, e.g. distance=10.5
\
scale
An optional keyword that adds the token's footprint (size) to the distance so vision starts at token's edge vs the token's center
\ -
arc=y
When used with the cone shape, it signifies how large a field of vision the token has. Can be an interger value. Ex: arc=120
\ -
offset=y
When used with the cone shape, it signifies how much offset the cone begins from the center of the tokens facing. Can be an integer value. Ex: offset=120
\ -
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value. Ex: x2
\ +
arc=y

When used with the cone shape, it signifies how large a field of vision the token has. Can be an integer value. e,g, arc=120

\ +

When used with the line shape, it determines how wide the line will be. Can be an integer value from 0 to 180, e.g. arc=4

\ +
offset=y
When used with the cone or line shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\ +
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value, e.g. x2.5
\
r#

Range of personal light. The token will have a light source centered on them that only they can see with a radius of this value. You can define multiple personal lights per sight type.

\

Can have an optional #rrggbb hex color component appended to it as per typical CSS rules.

\

Can also have an optional +x lumens value. Lumens defaults to 100, meaning it will see through any darkness with a lumens value from -1 to -99. See discussion of lumens on the Light tab for more info.

\ @@ -870,11 +871,38 @@ the token's popup menu under the Light Sources element, and \ individual light source definitions become sub-entries. Group names are \ displayed in sorted order, and the sub-entries are alphabetically sorted \ as well.

\ +
\ +
name
A user-visible name for light definition.
\ +
type
An optional type for the light. Currently only aura is valid. (See below for a description of auras.)
\ +
shape
shape may be circle, square, hex, grid, cone or line
\ +
distance=y
Distance is the range at which this vision type ends. Can be a decimal value, e.g. distance=10.5
\ +
scale
An optional keyword that adds the token's footprint (size) to the distance so vision starts at token's edge vs the token's center
\ +
arc=y

When used with the cone shape, it signifies how large a field of vision the token has. Can be an integer value. e,g, arc=120

\ +

When used with the line shape, it determines how wide the line will be. Can be an integer value from 0 to 180, e.g. arc=4

\ +
offset=y
When used with the cone or line shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\ +
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value, e.g. x2.5
\ +
r#

Range of personal light. The token will have a light source centered on them that only they can see with a radius of this value. You can define multiple personal lights per sight type.

\ +

Can have an optional #rrggbb hex color component appended to it as per typical CSS rules.

\ +

Can also have an optional +x lumens value. Lumens defaults to 100, meaning it will see through any darkness with a lumens value from -1 to -99. See discussion of lumens on the Light tab for more info.

\ +

Ex: r60#bb0000+120

\ +
\ +Format: \ +
Group name
\ +----------
\ +name: type shape OPTIONS scale range#rrggbb+x
\ +

Define groups of light types with a line of text to indicate the group \ +name followed by one or more name definitions. End a group with a \ +blank line. All text is case-insensitive. Lines that start with a "-" are \ +considered comments and are ignored. The group name becomes an entry on \ +the token's popup menu under the Light Sources element, and \ +individual light source definitions become sub-entries. Group names are \ +displayed in sorted order, and the sub-entries are alphabetically sorted \ +as well.

\
\
name
A user-visible name for light definition.
\
type
An optional type for the light. Currently only aura is valid. (See below for a description of auras.)
\
shape
An optional shape for the light emanation. Can be circle (default), \ - square, cone (cones also have arc=angle and \ + square, cone, line (lines and cones also have arc=angle and \ offset=y fields) or grid (for systems like Pathfinder if \ you want to see exactly which grid cells are affected by a Light/Aura). Shapes \ apply from the point they are included in the definition until the end of the \ @@ -902,7 +930,7 @@ as well.

\
\

Example:

\
\
-Sample Lights - 5' square grid 
\ +Sample Lights - 5' grid
\ ----
\ Candle - 5 : 7.5 12.5#000000
\ Lamp - 15 : 17.5 32.5#000000
\ @@ -923,16 +951,16 @@ Darkness - 20 (CL4): circle 22.5-40
\

To create an aura, put the keyword aura at the beginning of the \ definition. Auras radiate a colored area and interact with the vision \ blocking layer (i.e. are blocked by VBL), but do not actually cast any \ -visible light and therefore do not expose any fog-of-war. GM-only auras \ -are only visible by clients logged into the server as GM. They remain \ -visible even when the map is in Show As Player mode. Owner-only \ -auras are only visible to the player(s) who owns the token they are \ -attached to and are always visible to the GM. See examples, below.

\ +visible light and do not expose any fog-of-war. GM-only auras are only \ +visible by clients logged into the server as GM. They remain visible \ +even when the map is in Show As Player mode. Owner-only auras are\ +only visible to the player(s) who owns the token. They are always visible\ +to the GM. See examples, below.

\

In the following example, the GM-only auras are red, the owner-only \ auras are green, and the player auras are blue. You can of course define \ your own colors.

\
\
-Sample Auras - 5" square grid
\ +Sample Auras: 5' grid
\ ----
\ Aura red 5 : aura square GM 2.5#ff0000
\ Aura red 10 : aura GM 7.5#ff0000
\ @@ -940,12 +968,35 @@ Aura Owner Also 5 : aura square owner 2.5#00ff00
\ Aura Owner Also 10 : aura owner 7.5#00ff00
\ Aura Player Also 5 : aura square 2.5#0000ff
\ Aura Player Also 10 : aura 7.5#0000ff
\ +\
\

The first line creates a square GM-only aura in red that is 5-feet across. \ The second creates a round GM-only aura in red with a 15-foot diameter. \ Lines three and four do the same thing, but with a green aura that is only \ visible to players who own the token with the aura attached to it. Lines \ five and six are visible to all players and are in blue.

\ +
\
+New Interesting Auras: 5' grid
\ +----
\ +Side Fields - 12.5: aura cone arc=90 12.5#6666ff offset=90 12.5#aadd00 offset=-90 12.5#aadd00 offset=180 12.5#bb00aa +Doughnut Hole - 40: aura circle 20 40#ffff00
\ +Doughnut Cone - 20: aura cone arc=30 20#ffff00
\ +Range Circles 30/60/90: aura circle 30.5 30.9#000000 60.5 60.9#000000 90.5 90.9#000000
\ +Range Arcs 30/60/90: aura cone arc=135 30.5 30.9#000000 60.5 60.9#000000 90.5 90.9#000000
\ +Line - 50: aura line arc=4 150#ffff00
\ +
\ +
\ +
Side fields
4 cones with an arc of 90 degrees and range of 12.5.\ +Each one offset to cover a different region.
\ +
Doughnut Hole
This one hides a secret. If you have a range with\ +no colour it becomes the range the light source begins. In this case the light\ +begins at 20 and ends at 40.
\ +
Doughnut Cone
The same trick done with a cone.
\ +
Range Circles
A series of circles starting every\ +30 ft and ending 0.4 ft later.
\ +
Range Arcs
Another repeat, this one using cones.
\ +
Line
A line 150 ft long. The arc determines its width\ +and is 4 degrees. At 180 degrees it would be as wide as the token.
\ CampaignPropertiesDialog.label.title = Campaign Properties CampaignPropertiesDialog.label.group = Group: diff --git a/src/main/resources/net/rptools/maptool/language/i18n_en_au.properties b/src/main/resources/net/rptools/maptool/language/i18n_en_au.properties index 09270fc578..a6ae6341e4 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_en_au.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_en_au.properties @@ -847,14 +847,15 @@ CampaignPropertiesDialog.label.sight = \ defaults for all values (e.g. Normal vision).

\

Options:

\
\ -
shape
shape may be circle, square, hex, grid or cone
\ -
distance=y
Distance is the range at which this vision type ends. Can be a decimal value. Ex: distance=10
\ +
shape
shape may be circle, square, hex, grid, cone or line
\ +
distance=y
Distance is the range at which this vision type ends. Can be a decimal value, e.g. distance=10.5
\
scale
An optional keyword that adds the token's footprint (size) to the distance so vision starts at token's edge vs the token's center
\ -
arc=y
When used with the cone shape, it signifies how large a field of vision the token has. Can be an interger value. Ex: arc=120
\ -
offset=y
When used with the cone shape, it signifies how much offset the cone begins from the center of the tokens facing. Can be an integer value. Ex: offset=120
\ -
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value. Ex: x2
\ +
arc=y

When used with the cone shape, it signifies how large a field of vision the token has. Can be an integer value. e,g, arc=120

\ +

When used with the line shape, it determines how wide the line will be. Can be an integer value from 0 to 180, e.g. arc=4

\ +
offset=y
When used with the cone or line shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\ +
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value, e.g. x2.5
\
r#

Range of personal light. The token will have a light source centered on them that only they can see with a radius of this value. You can define multiple personal lights per sight type.

\ -

Can have an optional #rrggbb hex colour component appended to it as per typical CSS rules.

\ +

Can have an optional #rrggbb hex color component appended to it as per typical CSS rules.

\

Can also have an optional +x lumens value. Lumens defaults to 100, meaning it will see through any darkness with a lumens value from -1 to -99. See discussion of lumens on the Light tab for more info.

\

Ex: r60#bb0000+120

\
\ @@ -872,11 +873,38 @@ the token's popup menu under the Light Sources element, and \ individual light source definitions become sub-entries. Group names are \ displayed in sorted order, and the sub-entries are alphabetically sorted \ as well.

\ +
\ +
name
A user-visible name for light definition.
\ +
type
An optional type for the light. Currently only aura is valid. (See below for a description of auras.)
\ +
shape
shape may be circle, square, hex, grid, cone or line
\ +
distance=y
Distance is the range at which this vision type ends. Can be a decimal value, e.g. distance=10.5
\ +
scale
An optional keyword that adds the token's footprint (size) to the distance so vision starts at token's edge vs the token's center
\ +
arc=y

When used with the cone shape, it signifies how large a field of vision the token has. Can be an integer value. e,g, arc=120

\ +

When used with the line shape, it determines how wide the line will be. Can be an integer value from 0 to 180, e.g. arc=4

\ +
offset=y
When used with the cone or line shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\ +
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value, e.g. x2.5
\ +
r#

Range of personal light. The token will have a light source centered on them that only they can see with a radius of this value. You can define multiple personal lights per sight type.

\ +

Can have an optional #rrggbb hex color component appended to it as per typical CSS rules.

\ +

Can also have an optional +x lumens value. Lumens defaults to 100, meaning it will see through any darkness with a lumens value from -1 to -99. See discussion of lumens on the Light tab for more info.

\ +

Ex: r60#bb0000+120

\ +
\ +Format: \ +
Group name
\ +----------
\ +name: type shape OPTIONS scale range#rrggbb+x
\ +

Define groups of light types with a line of text to indicate the group \ +name followed by one or more name definitions. End a group with a \ +blank line. All text is case-insensitive. Lines that start with a "-" are \ +considered comments and are ignored. The group name becomes an entry on \ +the token's popup menu under the Light Sources element, and \ +individual light source definitions become sub-entries. Group names are \ +displayed in sorted order, and the sub-entries are alphabetically sorted \ +as well.

\
\
name
A user-visible name for light definition.
\
type
An optional type for the light. Currently only aura is valid. (See below for a description of auras.)
\
shape
An optional shape for the light emanation. Can be circle (default), \ - square, cone (cones also have arc=angle and \ + square, cone, line (lines and cones also have arc=angle and \ offset=y fields) or grid (for systems like Pathfinder if \ you want to see exactly which grid cells are affected by a Light/Aura). Shapes \ apply from the point they are included in the definition until the end of the \ @@ -886,7 +914,7 @@ as well.

\
range

A distance measured in map units (defined when the map is created). Units are \ measured from the centerpoint of the grid cell, hence the extra 2 ½ feet \ added in the below example to make neat squares.

\ -

Can have an optional #rrggbb hex colour component appended to it as per \ +

Can have an optional #rrggbb hex color component appended to it as per \ typical CSS rules.

\

Can have an optional +x lumens value, with x equaling an integer \ (-x can instead be used to provide a negative lumens value). If not \ @@ -904,7 +932,7 @@ as well.

\
\

Example:

\
\
-Sample Lights - 5' square grid 
\ +Sample Lights - 5' grid
\ ----
\ Candle - 5 : 7.5 12.5#000000
\ Lamp - 15 : 17.5 32.5#000000
\ @@ -923,18 +951,18 @@ Darkness - 20 (CL4): circle 22.5-40
\
\

Auras:

\

To create an aura, put the keyword aura at the beginning of the \ -definition. Auras radiate a coloured area and interact with the vision \ +definition. Auras radiate a colored area and interact with the vision \ blocking layer (i.e. are blocked by VBL), but do not actually cast any \ -visible light and therefore do not expose any fog-of-war. GM-only auras \ -are only visible by clients logged into the server as GM. They remain \ -visible even when the map is in Show As Player mode. Owner-only \ -auras are only visible to the player(s) who owns the token they are \ -attached to and are always visible to the GM. See examples, below.

\ +visible light and do not expose any fog-of-war. GM-only auras are only \ +visible by clients logged into the server as GM. They remain visible \ +even when the map is in Show As Player mode. Owner-only auras are\ +only visible to the player(s) who owns the token. They are always visible\ +to the GM. See examples, below.

\

In the following example, the GM-only auras are red, the owner-only \ auras are green, and the player auras are blue. You can of course define \ -your own colours.

\ +your own colors.

\
\
-Sample Auras - 5" square grid
\ +Sample Auras: 5' grid
\ ----
\ Aura red 5 : aura square GM 2.5#ff0000
\ Aura red 10 : aura GM 7.5#ff0000
\ @@ -942,12 +970,35 @@ Aura Owner Also 5 : aura square owner 2.5#00ff00
\ Aura Owner Also 10 : aura owner 7.5#00ff00
\ Aura Player Also 5 : aura square 2.5#0000ff
\ Aura Player Also 10 : aura 7.5#0000ff
\ +\
\

The first line creates a square GM-only aura in red that is 5-feet across. \ The second creates a round GM-only aura in red with a 15-foot diameter. \ Lines three and four do the same thing, but with a green aura that is only \ visible to players who own the token with the aura attached to it. Lines \ five and six are visible to all players and are in blue.

\ +
\
+New Interesting Auras: 5' grid
\ +----
\ +Side Fields - 12.5: aura cone arc=90 12.5#6666ff offset=90 12.5#aadd00 offset=-90 12.5#aadd00 offset=180 12.5#bb00aa
\ +Doughnut Hole - 40: aura circle 20 40#ffff00
\ +Doughnut Cone - 20: aura cone arc=30 20#ffff00
\ +Range Circles 30/60/90: aura circle 30.5 30.9#000000 60.5 60.9#000000 90.5 90.9#000000
\ +Range Arcs 30/60/90: aura cone arc=135 30.5 30.9#000000 60.5 60.9#000000 90.5 90.9#000000
\ +Line - 50: aura line arc=4 150#ffff00
\ +
\ +
\ +
Side fields
4 cones with an arc of 90 degrees and range of 12.5.\ +Each one offset to cover a different region.
\ +
Doughnut Hole
This one hides a secret. If you have a range with\ +no colour it becomes the range the light source begins. In this case the light\ +begins at 20 and ends at 40.
\ +
Doughnut Cone
The same trick done with a cone.
\ +
Range Circles
A series of circles starting every\ +30 ft and ending 0.4 ft later.
\ +
Range Arcs
Another repeat, this one using cones.
\ +
Line
A line 150 ft long. The arc determines its width\ +and is 4 degrees. At 180 degrees it would be as wide as the token.
\ CampaignPropertiesDialog.label.title = Campaign Properties CampaignPropertiesDialog.label.group = Group: diff --git a/src/main/resources/net/rptools/maptool/language/i18n_en_gb.properties b/src/main/resources/net/rptools/maptool/language/i18n_en_gb.properties index 09270fc578..d8bae8d21f 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_en_gb.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_en_gb.properties @@ -847,19 +847,47 @@ CampaignPropertiesDialog.label.sight = \ defaults for all values (e.g. Normal vision).

\

Options:

\
\ -
shape
shape may be circle, square, hex, grid or cone
\ -
distance=y
Distance is the range at which this vision type ends. Can be a decimal value. Ex: distance=10
\ +
shape
shape may be circle, square, hex, grid, cone or line
\ +
distance=y
Distance is the range at which this vision type ends. Can be a decimal value, e.g. distance=10.5
\
scale
An optional keyword that adds the token's footprint (size) to the distance so vision starts at token's edge vs the token's center
\ -
arc=y
When used with the cone shape, it signifies how large a field of vision the token has. Can be an interger value. Ex: arc=120
\ -
offset=y
When used with the cone shape, it signifies how much offset the cone begins from the center of the tokens facing. Can be an integer value. Ex: offset=120
\ -
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value. Ex: x2
\ +
arc=y

When used with the cone shape, it signifies how large a field of vision the token has. Can be an integer value. e,g, arc=120

\ +

When used with the line shape, it determines how wide the line will be. Can be an integer value from 0 to 180, e.g. arc=4

\ +
offset=y
When used with the cone or line shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\ +
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value, e.g. x2.5
\
r#

Range of personal light. The token will have a light source centered on them that only they can see with a radius of this value. You can define multiple personal lights per sight type.

\ -

Can have an optional #rrggbb hex colour component appended to it as per typical CSS rules.

\ +

Can have an optional #rrggbb hex color component appended to it as per typical CSS rules.

\

Can also have an optional +x lumens value. Lumens defaults to 100, meaning it will see through any darkness with a lumens value from -1 to -99. See discussion of lumens on the Light tab for more info.

\

Ex: r60#bb0000+120

\
\ -CampaignPropertiesDialog.label.light = \ +CampaignPropertiesDialog.label.light = \\ +Format: \ +
Group name
\ +----------
\ +name: type shape OPTIONS scale range#rrggbb+x
\ +

Define groups of light types with a line of text to indicate the group \ +name followed by one or more name definitions. End a group with a \ +blank line. All text is case-insensitive. Lines that start with a "-" are \ +considered comments and are ignored. The group name becomes an entry on \ +the token's popup menu under the Light Sources element, and \ +individual light source definitions become sub-entries. Group names are \ +displayed in sorted order, and the sub-entries are alphabetically sorted \ +as well.

\ +
\ +
name
A user-visible name for light definition.
\ +
type
An optional type for the light. Currently only aura is valid. (See below for a description of auras.)
\ +
shape
shape may be circle, square, hex, grid, cone or line
\ +
distance=y
Distance is the range at which this vision type ends. Can be a decimal value, e.g. distance=10.5
\ +
scale
An optional keyword that adds the token's footprint (size) to the distance so vision starts at token's edge vs the token's center
\ +
arc=y

When used with the cone shape, it signifies how large a field of vision the token has. Can be an integer value. e,g, arc=120

\ +

When used with the line shape, it determines how wide the line will be. Can be an integer value from 0 to 180, e.g. arc=4

\ +
offset=y
When used with the cone or line shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\ +
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value, e.g. x2.5
\ +
r#

Range of personal light. The token will have a light source centered on them that only they can see with a radius of this value. You can define multiple personal lights per sight type.

\ +

Can have an optional #rrggbb hex color component appended to it as per typical CSS rules.

\ +

Can also have an optional +x lumens value. Lumens defaults to 100, meaning it will see through any darkness with a lumens value from -1 to -99. See discussion of lumens on the Light tab for more info.

\ +

Ex: r60#bb0000+120

\ +
\ Format: \
Group name
\ ----------
\ @@ -876,7 +904,7 @@ as well.

\
name
A user-visible name for light definition.
\
type
An optional type for the light. Currently only aura is valid. (See below for a description of auras.)
\
shape
An optional shape for the light emanation. Can be circle (default), \ - square, cone (cones also have arc=angle and \ + square, cone, line (lines and cones also have arc=angle and \ offset=y fields) or grid (for systems like Pathfinder if \ you want to see exactly which grid cells are affected by a Light/Aura). Shapes \ apply from the point they are included in the definition until the end of the \ @@ -886,7 +914,7 @@ as well.

\
range

A distance measured in map units (defined when the map is created). Units are \ measured from the centerpoint of the grid cell, hence the extra 2 ½ feet \ added in the below example to make neat squares.

\ -

Can have an optional #rrggbb hex colour component appended to it as per \ +

Can have an optional #rrggbb hex color component appended to it as per \ typical CSS rules.

\

Can have an optional +x lumens value, with x equaling an integer \ (-x can instead be used to provide a negative lumens value). If not \ @@ -904,7 +932,7 @@ as well.

\
\

Example:

\
\
-Sample Lights - 5' square grid 
\ +Sample Lights - 5' grid
\ ----
\ Candle - 5 : 7.5 12.5#000000
\ Lamp - 15 : 17.5 32.5#000000
\ @@ -923,18 +951,18 @@ Darkness - 20 (CL4): circle 22.5-40
\
\

Auras:

\

To create an aura, put the keyword aura at the beginning of the \ -definition. Auras radiate a coloured area and interact with the vision \ +definition. Auras radiate a colored area and interact with the vision \ blocking layer (i.e. are blocked by VBL), but do not actually cast any \ -visible light and therefore do not expose any fog-of-war. GM-only auras \ -are only visible by clients logged into the server as GM. They remain \ -visible even when the map is in Show As Player mode. Owner-only \ -auras are only visible to the player(s) who owns the token they are \ -attached to and are always visible to the GM. See examples, below.

\ +visible light and do not expose any fog-of-war. GM-only auras are only \ +visible by clients logged into the server as GM. They remain visible \ +even when the map is in Show As Player mode. Owner-only auras are\ +only visible to the player(s) who owns the token. They are always visible\ +to the GM. See examples, below.

\

In the following example, the GM-only auras are red, the owner-only \ auras are green, and the player auras are blue. You can of course define \ -your own colours.

\ +your own colors.

\
\
-Sample Auras - 5" square grid
\ +Sample Auras: 5' grid
\ ----
\ Aura red 5 : aura square GM 2.5#ff0000
\ Aura red 10 : aura GM 7.5#ff0000
\ @@ -942,12 +970,35 @@ Aura Owner Also 5 : aura square owner 2.5#00ff00
\ Aura Owner Also 10 : aura owner 7.5#00ff00
\ Aura Player Also 5 : aura square 2.5#0000ff
\ Aura Player Also 10 : aura 7.5#0000ff
\ +\
\

The first line creates a square GM-only aura in red that is 5-feet across. \ The second creates a round GM-only aura in red with a 15-foot diameter. \ Lines three and four do the same thing, but with a green aura that is only \ visible to players who own the token with the aura attached to it. Lines \ five and six are visible to all players and are in blue.

\ +
\
+New Interesting Auras: 5' grid
\ +----
\ +Side Fields - 12.5: aura cone arc=90 12.5#6666ff offset=90 12.5#aadd00 offset=-90 12.5#aadd00 offset=180 12.5#bb00aa
\ +Doughnut Hole - 40: aura circle 20 40#ffff00
\ +Doughnut Cone - 20: aura cone arc=30 20#ffff00
\ +Range Circles 30/60/90: aura circle 30.5 30.9#000000 60.5 60.9#000000 90.5 90.9#000000
\ +Range Arcs 30/60/90: aura cone arc=135 30.5 30.9#000000 60.5 60.9#000000 90.5 90.9#000000
\ +Line - 50: aura line arc=4 150#ffff00
\ +
\ +
\ +
Side fields
4 cones with an arc of 90 degrees and range of 12.5.\ +Each one offset to cover a different region.
\ +
Doughnut Hole
This one hides a secret. If you have a range with\ +no colour it becomes the range the light source begins. In this case the light\ +begins at 20 and ends at 40.
\ +
Doughnut Cone
The same trick done with a cone.
\ +
Range Circles
A series of circles starting every\ +30 ft and ending 0.4 ft later.
\ +
Range Arcs
Another repeat, this one using cones.
\ +
Line
A line 150 ft long. The arc determines its width\ +and is 4 degrees. At 180 degrees it would be as wide as the token.
\ CampaignPropertiesDialog.label.title = Campaign Properties CampaignPropertiesDialog.label.group = Group: From c5a41413bb58e77276bd3f8969a6da251e3b7c96 Mon Sep 17 00:00:00 2001 From: bubblobill <45483160+bubblobill@users.noreply.github.com> Date: Wed, 22 Nov 2023 23:04:44 +0800 Subject: [PATCH 2/2] Refactored LINE to BEAM Undid unnecessary changes to LightSourceCreator Added BEAM to getShapedArea in IsometricGrid Removed commenting on some code in Grid Fixed issue with BEAM not being parsed for sight in Campaign Properties. --- .../client/functions/TokenLightFunctions.java | 4 +- .../CampaignPropertiesDialog.java | 26 ++++++++-- .../java/net/rptools/maptool/model/Grid.java | 18 +++---- .../rptools/maptool/model/IsometricGrid.java | 34 +++++++++++--- .../net/rptools/maptool/model/ShapeType.java | 2 +- .../maptool/tool/LightSourceCreator.java | 47 +++++-------------- src/main/proto/data_transfer_objects.proto | 2 +- .../rptools/maptool/language/i18n.properties | 20 ++++---- .../maptool/language/i18n_en_au.properties | 22 ++++----- .../maptool/language/i18n_en_gb.properties | 24 +++++----- 10 files changed, 110 insertions(+), 89 deletions(-) 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 2fd5ee2528..e4351e7e76 100644 --- a/src/main/java/net/rptools/maptool/client/functions/TokenLightFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/TokenLightFunctions.java @@ -400,7 +400,7 @@ private static Light parseLightJson(JsonObject lightDef, LightSource.Type lightS ? 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 && shape != ShapeType.LINE) { + if (shape != ShapeType.CONE && shape != ShapeType.BEAM) { if (lightDef.has("offset")) { throw new ParserException( I18N.getText("Facing offset provided but the shape is not a cone")); @@ -465,7 +465,7 @@ private static JsonObject lightToJson(LightSource source, Light light) { final var lightDef = new JsonObject(); lightDef.addProperty("shape", light.getShape().toString()); - if (light.getShape() == ShapeType.LINE) { + if (light.getShape() == ShapeType.BEAM) { lightDef.addProperty("offset", light.getFacingOffset()); lightDef.addProperty("arc", light.getArcAngle()); } 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 678b790b08..0d896a959a 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 @@ -277,6 +277,24 @@ private String updateSightPanel(Map sightTypeMap) { .append(StringUtil.formatDecimal(sight.getDistance())) .append(' '); break; + case BEAM: + builder.append("beam "); + if (sight.getArc() != 0) { + builder.append("arc=").append(StringUtil.formatDecimal(sight.getArc())).append(' '); + } else { + builder.append("arc=4").append(StringUtil.formatDecimal(sight.getArc())).append(' '); + } + if (sight.getOffset() != 0) + builder + .append("offset=") + .append(StringUtil.formatDecimal(sight.getOffset())) + .append(' '); + if (sight.getDistance() != 0) + builder + .append("distance=") + .append(StringUtil.formatDecimal(sight.getDistance())) + .append(' '); + break; case CONE: builder.append("cone "); if (sight.getArc() != 0) @@ -373,10 +391,10 @@ private String updateLightPanel(Map> lightSources // TODO: Make this a preference shape = light.getShape().toString().toLowerCase(); break; - case LINE: + case BEAM: { lastArc = light.getArcAngle(); - shape = "line arc=" + StringUtil.formatDecimal(lastArc); + shape = "beam arc=" + StringUtil.formatDecimal(lastArc); if (light.getFacingOffset() != 0) builder .append(" offset=") @@ -515,6 +533,7 @@ private void commitSightMap(final String text) { assert arg.length() > 0; // The split() uses "one or more spaces", removing empty strings try { shape = ShapeType.valueOf(arg.toUpperCase()); + arc = shape == ShapeType.BEAM ? 4 : arc; continue; } catch (IllegalArgumentException iae) { // Expected when not defining a shape @@ -725,6 +744,7 @@ private Map> commitLightMap( // Shape designation ? try { shape = ShapeType.valueOf(arg.toUpperCase()); + arc = shape == ShapeType.BEAM ? 4 : arc; continue; } catch (IllegalArgumentException iae) { // Expected when not defining a shape @@ -760,7 +780,7 @@ private Map> commitLightMap( try { arc = StringUtil.parseDecimal(value); shape = - (shape != ShapeType.CONE && shape != ShapeType.LINE) + (shape != ShapeType.CONE && shape != ShapeType.BEAM) ? ShapeType.CONE : shape; // If the user specifies an arc, force the shape to CONE } catch (ParseException pe) { diff --git a/src/main/java/net/rptools/maptool/model/Grid.java b/src/main/java/net/rptools/maptool/model/Grid.java index 4ab1764f60..2e07c2eef8 100644 --- a/src/main/java/net/rptools/maptool/model/Grid.java +++ b/src/main/java/net/rptools/maptool/model/Grid.java @@ -14,6 +14,7 @@ */ package net.rptools.maptool.model; +import com.google.common.base.Stopwatch; import java.awt.*; import java.awt.geom.*; import java.awt.image.BufferedImage; @@ -23,6 +24,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; import javax.swing.Action; import javax.swing.KeyStroke; import net.rptools.lib.FileUtil; @@ -394,7 +396,7 @@ public Area getShapedArea( new Rectangle2D.Double( -visionRange, -visionRange, visionRange * 2, visionRange * 2)); break; - case LINE: + case BEAM: if (token.getFacing() == null) { token.setFacing(0); } @@ -757,7 +759,7 @@ protected Area getGridArea( final Area visibleArea; if (range > 0) { - // final Stopwatch stopwatch = Stopwatch.createStarted(); + final Stopwatch stopwatch = Stopwatch.createStarted(); final int gridRadius = (int) (range / getZone().getUnitsPerCell()); if (scaleWithToken) { @@ -766,12 +768,12 @@ protected Area getGridArea( visibleArea = getGridAreaFromCache(gridRadius).createTransformedArea(getGridOffset(token)); } - // if (stopwatch.elapsed(TimeUnit.MILLISECONDS) > 50) { - // log.debug( - // "Excessive time to generate {}r grid light, took {}ms", - // gridRadius, - // stopwatch.elapsed(TimeUnit.MILLISECONDS)); - // } + if (stopwatch.elapsed(TimeUnit.MILLISECONDS) > 50) { + log.debug( + "Excessive time to generate {}r grid light, took {}ms", + gridRadius, + stopwatch.elapsed(TimeUnit.MILLISECONDS)); + } } else { // Fall back to regular circle in daylight, etc. visibleArea = diff --git a/src/main/java/net/rptools/maptool/model/IsometricGrid.java b/src/main/java/net/rptools/maptool/model/IsometricGrid.java index c1078ac9ed..0d1a408c90 100644 --- a/src/main/java/net/rptools/maptool/model/IsometricGrid.java +++ b/src/main/java/net/rptools/maptool/model/IsometricGrid.java @@ -14,12 +14,7 @@ */ package net.rptools.maptool.model; -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Polygon; -import java.awt.Rectangle; +import java.awt.*; import java.awt.event.KeyEvent; import java.awt.geom.*; import java.awt.image.BufferedImage; @@ -349,6 +344,33 @@ public Area getShapedArea( int x[] = {0, (int) visionRange * 2, 0, (int) -visionRange * 2}; int y[] = {(int) -visionRange, 0, (int) visionRange, 0}; visibleArea = new Area(new Polygon(x, y, 4)); + break; + case BEAM: + if (token.getFacing() == null) { + token.setFacing(0); + } + Shape visibleShape = + new Rectangle2D.Double( + 0, + getSize() / -2d * Math.sin(Math.toRadians(arcAngle / 2.0)), + visionRange, + getSize() * Math.sin(Math.toRadians(arcAngle / 2.0))); + + // new angle, corrected for isometric view + double theta = Math.toRadians(offsetAngle) + Math.toRadians(token.getFacing()); + Point2D angleVector = new Point2D.Double(Math.cos(theta), Math.sin(theta)); + AffineTransform at = new AffineTransform(); + at.rotate(Math.PI / 4); + at.scale(1.0, 0.5); + at.deltaTransform(angleVector, angleVector); + + theta = -Math.atan2(angleVector.getY(), angleVector.getX()); + + visibleArea = + new Area( + AffineTransform.getRotateInstance(theta + Math.toRadians(45)) + .createTransformedShape(visibleShape)); + break; case CONE: if (token.getFacing() == null) { diff --git a/src/main/java/net/rptools/maptool/model/ShapeType.java b/src/main/java/net/rptools/maptool/model/ShapeType.java index ac6e58a3b8..df27b886da 100644 --- a/src/main/java/net/rptools/maptool/model/ShapeType.java +++ b/src/main/java/net/rptools/maptool/model/ShapeType.java @@ -19,6 +19,6 @@ public enum ShapeType { CONE, GRID, HEX, - LINE, + BEAM, SQUARE } diff --git a/src/main/java/net/rptools/maptool/tool/LightSourceCreator.java b/src/main/java/net/rptools/maptool/tool/LightSourceCreator.java index dcee535bb4..0379f1eb29 100644 --- a/src/main/java/net/rptools/maptool/tool/LightSourceCreator.java +++ b/src/main/java/net/rptools/maptool/tool/LightSourceCreator.java @@ -26,23 +26,8 @@ import net.rptools.maptool.model.LightSource; import net.rptools.maptool.model.ShapeType; import net.rptools.maptool.model.drawing.DrawableColorPaint; -import net.rptools.maptool.model.drawing.DrawablePaint; public class LightSourceCreator { - private static Light createLight( - ShapeType shape, - double radius, - double arcAngle, - double offset, - DrawablePaint paint, - int lumens, - boolean isGM, - boolean ownerOnly) { - if (arcAngle == 0) arcAngle = 360; - shape = shape == null ? ShapeType.CIRCLE : shape; - return new Light(shape, offset, radius, arcAngle, paint, lumens, isGM, ownerOnly); - } - public static void main(String[] args) { Map> lightSourcesMap = new HashMap>(); @@ -59,34 +44,26 @@ public static void main(String[] args) { lightSourceList = new ArrayList(); - lightSourceList.add(createCircleLightSource("5", 5, 360)); - lightSourceList.add(createCircleLightSource("15", 15, 360)); - lightSourceList.add(createCircleLightSource("20", 20, 360)); - lightSourceList.add(createCircleLightSource("30", 30, 360)); - lightSourceList.add(createCircleLightSource("40", 40, 360)); - lightSourceList.add(createCircleLightSource("60", 60, 360)); + lightSourceList.add(createLightSource("5", 5, 360)); + lightSourceList.add(createLightSource("15", 15, 360)); + lightSourceList.add(createLightSource("20", 20, 360)); + lightSourceList.add(createLightSource("30", 30, 360)); + lightSourceList.add(createLightSource("40", 40, 360)); + lightSourceList.add(createLightSource("60", 60, 360)); lightSourcesMap.put("Generic", lightSourceList); - // lightSourceList = new ArrayList(); - // - // lightSourceList.add(createLightSource("Front", 5, 360)); - // - // lightSourcesMap.put("Auras", lightSourceList); - XStream xstream = FileUtil.getConfiguredXStream(); System.out.println(xstream.toXML(lightSourcesMap)); } - // private static LightSource createLightSource(String name, double radius, double arcAngle) { - // } - private static LightSource createCircleLightSource(String name, double radius, double arcAngle) { + private static LightSource createLightSource(String name, double radius, double arcAngle) { return LightSource.createRegular( name, new GUID(), LightSource.Type.NORMAL, false, - List.of(createLight(ShapeType.CIRCLE, radius, arcAngle, 0d, null, 100, false, false))); + List.of(new Light(ShapeType.CIRCLE, 0, radius, arcAngle, null, 100, false, false))); } private static LightSource createD20LightSource(String name, double radius, double arcAngle) { @@ -96,12 +73,12 @@ private static LightSource createD20LightSource(String name, double radius, doub LightSource.Type.NORMAL, false, List.of( - createLight(ShapeType.CIRCLE, radius, arcAngle, 0d, null, 100, false, false), - createLight( + new Light(ShapeType.CIRCLE, 0, radius, arcAngle, null, 100, false, false), + new Light( ShapeType.CIRCLE, - 2 * radius, + 0, + radius * 2, arcAngle, - 0d, new DrawableColorPaint(new Color(0, 0, 0, 100)), 100, false, diff --git a/src/main/proto/data_transfer_objects.proto b/src/main/proto/data_transfer_objects.proto index 66e7104a3f..6aefd9ad58 100644 --- a/src/main/proto/data_transfer_objects.proto +++ b/src/main/proto/data_transfer_objects.proto @@ -83,7 +83,7 @@ enum ShapeTypeDto { CONE = 2; HEX = 3; GRID = 4; - LINE = 5; + BEAM = 5; } message LightDto { diff --git a/src/main/resources/net/rptools/maptool/language/i18n.properties b/src/main/resources/net/rptools/maptool/language/i18n.properties index 4e4c025dd5..fcea8ea3e2 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n.properties @@ -845,12 +845,12 @@ CampaignPropertiesDialog.label.sight = \ defaults for all values (e.g. Normal vision).

\

Options:

\
\ -
shape
shape may be circle, square, hex, grid, cone or line
\ +
shape
shape may be circle, square, hex, grid, cone or beam
\
distance=y
Distance is the range at which this vision type ends. Can be a decimal value, e.g. distance=10.5
\
scale
An optional keyword that adds the token's footprint (size) to the distance so vision starts at token's edge vs the token's center
\ -
arc=y

When used with the cone shape, it signifies how large a field of vision the token has. Can be an integer value. e,g, arc=120

\ -

When used with the line shape, it determines how wide the line will be. Can be an integer value from 0 to 180, e.g. arc=4

\ -
offset=y
When used with the cone or line shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\ +
arc=y

When used with the cone shape, it signifies how wide a field of vision the token has. Can be an integer value. e,g, arc=120

\ +

When used with the beam shape, it determines how wide the beam will be. Can be an integer value from 0 to 180, e.g. arc=4

\ +
offset=y
When used with the cone or beam shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value, e.g. x2.5
\
r#

Range of personal light. The token will have a light source centered on them that only they can see with a radius of this value. You can define multiple personal lights per sight type.

\

Can have an optional #rrggbb hex color component appended to it as per typical CSS rules.

\ @@ -874,12 +874,12 @@ as well.

\
\
name
A user-visible name for light definition.
\
type
An optional type for the light. Currently only aura is valid. (See below for a description of auras.)
\ -
shape
shape may be circle, square, hex, grid, cone or line
\ +
shape
shape may be circle, square, hex, grid, cone or beam
\
distance=y
Distance is the range at which this vision type ends. Can be a decimal value, e.g. distance=10.5
\
scale
An optional keyword that adds the token's footprint (size) to the distance so vision starts at token's edge vs the token's center
\
arc=y

When used with the cone shape, it signifies how large a field of vision the token has. Can be an integer value. e,g, arc=120

\ -

When used with the line shape, it determines how wide the line will be. Can be an integer value from 0 to 180, e.g. arc=4

\ -
offset=y
When used with the cone or line shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\ +

When used with the beam shape, it determines how wide the beam will be. Can be an integer value from 0 to 180, e.g. arc=4

\ +
offset=y
When used with the cone or beam shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value, e.g. x2.5
\
r#

Range of personal light. The token will have a light source centered on them that only they can see with a radius of this value. You can define multiple personal lights per sight type.

\

Can have an optional #rrggbb hex color component appended to it as per typical CSS rules.

\ @@ -902,7 +902,7 @@ as well.

\
name
A user-visible name for light definition.
\
type
An optional type for the light. Currently only aura is valid. (See below for a description of auras.)
\
shape
An optional shape for the light emanation. Can be circle (default), \ - square, cone, line (lines and cones also have arc=angle and \ + square, cone, beam (beams and cones also have arc=angle and \ offset=y fields) or grid (for systems like Pathfinder if \ you want to see exactly which grid cells are affected by a Light/Aura). Shapes \ apply from the point they are included in the definition until the end of the \ @@ -983,7 +983,7 @@ Doughnut Hole - 40: aura circle 20 40#ffff00
\ Doughnut Cone - 20: aura cone arc=30 20#ffff00
\ Range Circles 30/60/90: aura circle 30.5 30.9#000000 60.5 60.9#000000 90.5 90.9#000000
\ Range Arcs 30/60/90: aura cone arc=135 30.5 30.9#000000 60.5 60.9#000000 90.5 90.9#000000
\ -Line - 50: aura line arc=4 150#ffff00
\ +Beam - 50: aura beam arc=4 150#ffff00
\
\
\
Side fields
4 cones with an arc of 90 degrees and range of 12.5.\ @@ -995,7 +995,7 @@ begins at 20 and ends at 40.
\
Range Circles
A series of circles starting every\ 30 ft and ending 0.4 ft later.
\
Range Arcs
Another repeat, this one using cones.
\ -
Line
A line 150 ft long. The arc determines its width\ +
Beam
A beam 150 ft long. The arc determines its width\ and is 4 degrees. At 180 degrees it would be as wide as the token.
\ CampaignPropertiesDialog.label.title = Campaign Properties diff --git a/src/main/resources/net/rptools/maptool/language/i18n_en_au.properties b/src/main/resources/net/rptools/maptool/language/i18n_en_au.properties index a6ae6341e4..db666a5a81 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_en_au.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_en_au.properties @@ -847,12 +847,12 @@ CampaignPropertiesDialog.label.sight = \ defaults for all values (e.g. Normal vision).

\

Options:

\
\ -
shape
shape may be circle, square, hex, grid, cone or line
\ +
shape
shape may be circle, square, hex, grid, cone or beam
\
distance=y
Distance is the range at which this vision type ends. Can be a decimal value, e.g. distance=10.5
\
scale
An optional keyword that adds the token's footprint (size) to the distance so vision starts at token's edge vs the token's center
\ -
arc=y

When used with the cone shape, it signifies how large a field of vision the token has. Can be an integer value. e,g, arc=120

\ -

When used with the line shape, it determines how wide the line will be. Can be an integer value from 0 to 180, e.g. arc=4

\ -
offset=y
When used with the cone or line shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\ +
arc=y

When used with the cone shape, it signifies how wide a field of vision the token has. Can be an integer value. e,g, arc=120

\ +

When used with the beam shape, it determines how wide the beam will be. Can be an integer value from 0 to 180, e.g. arc=4

\ +
offset=y
When used with the cone or beam shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value, e.g. x2.5
\
r#

Range of personal light. The token will have a light source centered on them that only they can see with a radius of this value. You can define multiple personal lights per sight type.

\

Can have an optional #rrggbb hex color component appended to it as per typical CSS rules.

\ @@ -876,12 +876,12 @@ as well.

\
\
name
A user-visible name for light definition.
\
type
An optional type for the light. Currently only aura is valid. (See below for a description of auras.)
\ -
shape
shape may be circle, square, hex, grid, cone or line
\ +
shape
shape may be circle, square, hex, grid, cone or beam
\
distance=y
Distance is the range at which this vision type ends. Can be a decimal value, e.g. distance=10.5
\
scale
An optional keyword that adds the token's footprint (size) to the distance so vision starts at token's edge vs the token's center
\
arc=y

When used with the cone shape, it signifies how large a field of vision the token has. Can be an integer value. e,g, arc=120

\ -

When used with the line shape, it determines how wide the line will be. Can be an integer value from 0 to 180, e.g. arc=4

\ -
offset=y
When used with the cone or line shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\ +

When used with the beam shape, it determines how wide the beam will be. Can be an integer value from 0 to 180, e.g. arc=4

\ +
offset=y
When used with the cone or beam shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value, e.g. x2.5
\
r#

Range of personal light. The token will have a light source centered on them that only they can see with a radius of this value. You can define multiple personal lights per sight type.

\

Can have an optional #rrggbb hex color component appended to it as per typical CSS rules.

\ @@ -904,7 +904,7 @@ as well.

\
name
A user-visible name for light definition.
\
type
An optional type for the light. Currently only aura is valid. (See below for a description of auras.)
\
shape
An optional shape for the light emanation. Can be circle (default), \ - square, cone, line (lines and cones also have arc=angle and \ + square, cone, beam (beams and cones also have arc=angle and \ offset=y fields) or grid (for systems like Pathfinder if \ you want to see exactly which grid cells are affected by a Light/Aura). Shapes \ apply from the point they are included in the definition until the end of the \ @@ -980,12 +980,12 @@ five and six are visible to all players and are in blue.

\
\
 New Interesting Auras: 5' grid
\ ----
\ -Side Fields - 12.5: aura cone arc=90 12.5#6666ff offset=90 12.5#aadd00 offset=-90 12.5#aadd00 offset=180 12.5#bb00aa
\ +Side Fields - 12.5: aura cone arc=90 12.5#6666ff offset=90 12.5#aadd00 offset=-90 12.5#aadd00 offset=180 12.5#bb00aa Doughnut Hole - 40: aura circle 20 40#ffff00
\ Doughnut Cone - 20: aura cone arc=30 20#ffff00
\ Range Circles 30/60/90: aura circle 30.5 30.9#000000 60.5 60.9#000000 90.5 90.9#000000
\ Range Arcs 30/60/90: aura cone arc=135 30.5 30.9#000000 60.5 60.9#000000 90.5 90.9#000000
\ -Line - 50: aura line arc=4 150#ffff00
\ +Beam - 50: aura beam arc=4 150#ffff00
\
\
\
Side fields
4 cones with an arc of 90 degrees and range of 12.5.\ @@ -997,7 +997,7 @@ begins at 20 and ends at 40.
\
Range Circles
A series of circles starting every\ 30 ft and ending 0.4 ft later.
\
Range Arcs
Another repeat, this one using cones.
\ -
Line
A line 150 ft long. The arc determines its width\ +
Beam
A beam 150 ft long. The arc determines its width\ and is 4 degrees. At 180 degrees it would be as wide as the token.
\ CampaignPropertiesDialog.label.title = Campaign Properties diff --git a/src/main/resources/net/rptools/maptool/language/i18n_en_gb.properties b/src/main/resources/net/rptools/maptool/language/i18n_en_gb.properties index d8bae8d21f..db666a5a81 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n_en_gb.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n_en_gb.properties @@ -847,12 +847,12 @@ CampaignPropertiesDialog.label.sight = \ defaults for all values (e.g. Normal vision).

\

Options:

\
\ -
shape
shape may be circle, square, hex, grid, cone or line
\ +
shape
shape may be circle, square, hex, grid, cone or beam
\
distance=y
Distance is the range at which this vision type ends. Can be a decimal value, e.g. distance=10.5
\
scale
An optional keyword that adds the token's footprint (size) to the distance so vision starts at token's edge vs the token's center
\ -
arc=y

When used with the cone shape, it signifies how large a field of vision the token has. Can be an integer value. e,g, arc=120

\ -

When used with the line shape, it determines how wide the line will be. Can be an integer value from 0 to 180, e.g. arc=4

\ -
offset=y
When used with the cone or line shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\ +
arc=y

When used with the cone shape, it signifies how wide a field of vision the token has. Can be an integer value. e,g, arc=120

\ +

When used with the beam shape, it determines how wide the beam will be. Can be an integer value from 0 to 180, e.g. arc=4

\ +
offset=y
When used with the cone or beam shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value, e.g. x2.5
\
r#

Range of personal light. The token will have a light source centered on them that only they can see with a radius of this value. You can define multiple personal lights per sight type.

\

Can have an optional #rrggbb hex color component appended to it as per typical CSS rules.

\ @@ -860,7 +860,7 @@ CampaignPropertiesDialog.label.sight = \

Ex: r60#bb0000+120

\
\ -CampaignPropertiesDialog.label.light = \\ +CampaignPropertiesDialog.label.light = \ Format: \
Group name
\ ----------
\ @@ -876,12 +876,12 @@ as well.

\
\
name
A user-visible name for light definition.
\
type
An optional type for the light. Currently only aura is valid. (See below for a description of auras.)
\ -
shape
shape may be circle, square, hex, grid, cone or line
\ +
shape
shape may be circle, square, hex, grid, cone or beam
\
distance=y
Distance is the range at which this vision type ends. Can be a decimal value, e.g. distance=10.5
\
scale
An optional keyword that adds the token's footprint (size) to the distance so vision starts at token's edge vs the token's center
\
arc=y

When used with the cone shape, it signifies how large a field of vision the token has. Can be an integer value. e,g, arc=120

\ -

When used with the line shape, it determines how wide the line will be. Can be an integer value from 0 to 180, e.g. arc=4

\ -
offset=y
When used with the cone or line shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\ +

When used with the beam shape, it determines how wide the beam will be. Can be an integer value from 0 to 180, e.g. arc=4

\ +
offset=y
When used with the cone or beam shape, it signifies how many degrees off centre the shape begins. Can be an integer value. e.g. offset=120
\
x#
Magnifier, multiplies each light source radius by this value. Can be a decimal value, e.g. x2.5
\
r#

Range of personal light. The token will have a light source centered on them that only they can see with a radius of this value. You can define multiple personal lights per sight type.

\

Can have an optional #rrggbb hex color component appended to it as per typical CSS rules.

\ @@ -904,7 +904,7 @@ as well.

\
name
A user-visible name for light definition.
\
type
An optional type for the light. Currently only aura is valid. (See below for a description of auras.)
\
shape
An optional shape for the light emanation. Can be circle (default), \ - square, cone, line (lines and cones also have arc=angle and \ + square, cone, beam (beams and cones also have arc=angle and \ offset=y fields) or grid (for systems like Pathfinder if \ you want to see exactly which grid cells are affected by a Light/Aura). Shapes \ apply from the point they are included in the definition until the end of the \ @@ -980,12 +980,12 @@ five and six are visible to all players and are in blue.

\
\
 New Interesting Auras: 5' grid
\ ----
\ -Side Fields - 12.5: aura cone arc=90 12.5#6666ff offset=90 12.5#aadd00 offset=-90 12.5#aadd00 offset=180 12.5#bb00aa
\ +Side Fields - 12.5: aura cone arc=90 12.5#6666ff offset=90 12.5#aadd00 offset=-90 12.5#aadd00 offset=180 12.5#bb00aa Doughnut Hole - 40: aura circle 20 40#ffff00
\ Doughnut Cone - 20: aura cone arc=30 20#ffff00
\ Range Circles 30/60/90: aura circle 30.5 30.9#000000 60.5 60.9#000000 90.5 90.9#000000
\ Range Arcs 30/60/90: aura cone arc=135 30.5 30.9#000000 60.5 60.9#000000 90.5 90.9#000000
\ -Line - 50: aura line arc=4 150#ffff00
\ +Beam - 50: aura beam arc=4 150#ffff00
\
\
\
Side fields
4 cones with an arc of 90 degrees and range of 12.5.\ @@ -997,7 +997,7 @@ begins at 20 and ends at 40.
\
Range Circles
A series of circles starting every\ 30 ft and ending 0.4 ft later.
\
Range Arcs
Another repeat, this one using cones.
\ -
Line
A line 150 ft long. The arc determines its width\ +
Beam
A beam 150 ft long. The arc determines its width\ and is 4 degrees. At 180 degrees it would be as wide as the token.
\ CampaignPropertiesDialog.label.title = Campaign Properties