Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Magnify light source radius rather than shape #4803

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 7 additions & 31 deletions src/main/java/net/rptools/maptool/client/ui/zone/ZoneView.java
Original file line number Diff line number Diff line change
Expand Up @@ -336,14 +336,9 @@ private List<ContributedLight> calculateLitAreaForLightSource(

final var p = FogUtil.calculateVisionCenter(lightSourceToken, zone);
final var translateTransform = AffineTransform.getTranslateInstance(p.x, p.y);
final var magnifyTransform = AffineTransform.getScaleInstance(multiplier, multiplier);

final var lightSourceArea = lightSource.getArea(lightSourceToken, zone);
// Calculate exposed area
// Jamz: OK, let not have lowlight vision type multiply darkness radius
if (multiplier != 1 && lightSource.getType() == LightSource.Type.NORMAL) {
lightSourceArea.transform(magnifyTransform);
}
final var lightSourceArea = lightSource.getArea(lightSourceToken, zone, multiplier);
lightSourceArea.transform(translateTransform);

Area lightSourceVisibleArea = lightSourceArea;
Expand All @@ -365,35 +360,16 @@ private List<ContributedLight> calculateLitAreaForLightSource(

final var litAreas = new ArrayList<ContributedLight>();

// Tracks the cummulative inner ranges of light sources so that we can cut them out of the
// outer ranges and end up with disjoint sets, even when magnifying.
// Note that this "hole punching" has nothing to do with lumen strength, it's just a way of
// making smaller ranges act as lower bounds for larger ranges.
final var cummulativeNotTransformedArea = new Area();
for (final var light : lightSource.getLightList()) {
final var notScaledLightArea =
light.getArea(lightSourceToken, zone, lightSource.isScaleWithToken());
if (notScaledLightArea == null) {
continue;
}
final var lightArea = new Area(notScaledLightArea);

// Lowlight vision does not magnify darkness.
if (multiplier != 1
&& lightSource.getType() == LightSource.Type.NORMAL
&& light.getLumens() >= 0) {
lightArea.transform(magnifyTransform);
}
for (final var lightArea : lightSource.getLightAreas(lightSourceToken, zone, multiplier)) {
var area = lightArea.area();
var light = lightArea.light();

lightArea.subtract(cummulativeNotTransformedArea);
lightArea.transform(translateTransform);
lightArea.intersect(lightSourceVisibleArea);
area.transform(translateTransform);
area.intersect(lightSourceVisibleArea);

litAreas.add(
new ContributedLight(
new LitArea(light.getLumens(), lightArea), new LightInfo(lightSource, light)));

cummulativeNotTransformedArea.add(notScaledLightArea);
new LitArea(light.getLumens(), area), new LightInfo(lightSource, light)));
}

// Magnification can cause different ranges for a single light source to overlap. This is not
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ public void render(Graphics2D g, PlayerView view, Token tokenUnderMouse) {

private void renderWorld(Graphics2D worldG, PlayerView view, Token token) {
// The vision of the token is not necessarily related to the current view.
// final var tokenView = view.derive(Collections.singleton(token));
final var tokenView = new PlayerView(view.getRole(), List.of(token));

Area currentTokenVisionArea = zoneView.getVisibleArea(token, tokenView);
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/net/rptools/maptool/model/Grid.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import javax.swing.Action;
import javax.swing.KeyStroke;
import net.rptools.lib.FileUtil;
Expand Down Expand Up @@ -352,7 +353,7 @@ public void setSize(int size) {
* @param scaleWithToken used to increase the area based on token footprint
* @return Area
*/
public Area getShapedArea(
public @Nonnull Area getShapedArea(
ShapeType shape,
Token token,
double range,
Expand Down
14 changes: 12 additions & 2 deletions src/main/java/net/rptools/maptool/model/Light.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,28 @@ public double getArcAngle() {
return shape;
}

public @Nonnull Area getArea(@Nonnull Token token, @Nonnull Zone zone, boolean scaleWithToken) {
public @Nonnull Area getArea(
@Nonnull Token token, @Nonnull Zone zone, double multiplier, boolean scaleWithToken) {
var radius = getRadius();
// Darkness does not get magnified.
if (lumens >= 0) {
radius *= multiplier;
}
return zone.getGrid()
.getShapedArea(
getShape(),
token,
getRadius(),
radius,
getWidth(),
getArcAngle(),
(int) getFacingOffset(),
scaleWithToken);
}

public @Nonnull Area getArea(@Nonnull Token token, @Nonnull Zone zone, boolean scaleWithToken) {
return getArea(token, zone, 1.0, scaleWithToken);
}

public boolean isGM() {
return isGM;
}
Expand Down
51 changes: 45 additions & 6 deletions src/main/java/net/rptools/maptool/model/LightSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,50 @@ public boolean isIgnoresVBL() {
return ignoresVBL;
}

public record LightArea(Light light, Area area) {}

public @Nonnull List<LightArea> getLightAreas(
@Nonnull Token token, @Nonnull Zone zone, double multiplier) {
// Tracks the cumulative inner ranges of light sources so that we can cut them out of the
// outer ranges and end up with disjoint sets, even when magnifying.
// Note that this "hole punching" has nothing to do with lumen strength, it's just a way of
// making smaller ranges act as lower bounds for larger ranges.

// Auras do not get magnified.
if (type != Type.NORMAL) {
multiplier = 1.0;
}

final var result = new ArrayList<LightArea>();
final var cummulativeNotTransformedArea = new Area();

for (final var light : lightList) {
final var notScaledLightArea = light.getArea(token, zone, scaleWithToken);

final var lightArea = light.getArea(token, zone, multiplier, scaleWithToken);
lightArea.subtract(cummulativeNotTransformedArea);
result.add(new LightArea(light, lightArea));

cummulativeNotTransformedArea.add(notScaledLightArea);
}
return result;
}

/* Area for all lights combined */
public @Nonnull Area getArea(@Nonnull Token token, @Nonnull Zone zone, double multiplier) {
// Auras do not get magnified.
if (type != Type.NORMAL) {
multiplier = 1.0;
}

Area area = new Area();
for (Light light : lightList) {
area.add(light.getArea(token, zone, multiplier, isScaleWithToken()));
}

return area;
}

/*
* Area for a single light, subtracting any previous lights
*/
Expand All @@ -232,12 +276,7 @@ public boolean isIgnoresVBL() {

/* Area for all lights combined */
public @Nonnull Area getArea(@Nonnull Token token, @Nonnull Zone zone) {
Area area = new Area();
for (Light light : lightList) {
area.add(light.getArea(token, zone, isScaleWithToken()));
}

return area;
return getArea(token, zone, 1.0);
}

@SuppressWarnings("unchecked")
Expand Down
Loading