/* * Copyright (c) 2014 tabletoptool.com team. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * * Contributors: * rptools.com team - initial implementation * tabletoptool.com team - further development */ package com.t3.model; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.awt.geom.Arc2D; import java.awt.geom.Area; import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; import com.t3.xstreamversioned.version.SerializationVersion; @SerializationVersion(0) public class SightType { private String name; private double multiplier; private LightSource personalLightSource; private ShapeType shape; private int arc = 0; private float distance = 0; private int offset = 0; public int getOffset() { return this.offset; } public void setOffset(int offset2) { this.offset = offset2; } public float getDistance() { return this.distance; } public void setDistance(float range) { this.distance = range; } public ShapeType getShape() { return shape != null ? shape : ShapeType.CIRCLE; } public void setShape(ShapeType shape) { this.shape = shape; } public SightType() { // For serialization } public SightType(String name, double multiplier, LightSource personalLightSource) { this(name, multiplier, personalLightSource, ShapeType.CIRCLE); } public SightType(String name, double multiplier, LightSource personalLightSource, ShapeType shape) { this.name = name; this.multiplier = multiplier; this.personalLightSource = personalLightSource; this.shape = shape; } public SightType(String name, double multiplier, LightSource personalLightSource, ShapeType shape, int arc) { this.name = name; this.multiplier = multiplier; this.personalLightSource = personalLightSource; this.shape = shape; this.arc = arc; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getMultiplier() { return multiplier; } public void setMultiplier(double multiplier) { this.multiplier = multiplier; } public boolean hasPersonalLightSource() { return personalLightSource != null; } public LightSource getPersonalLightSource() { return personalLightSource; } public void setPersonalLightSource(LightSource personalLightSource) { this.personalLightSource = personalLightSource; } public void setArc(int arc) { this.arc = arc; } public int getArc() { return arc; } public Area getVisionShape(Token token, Zone zone) { float visionRange = getDistance(); int visionDistance = zone.getTokenVisionInPixels(); Area visibleArea = new Area(); visionRange = (visionRange == 0) ? visionDistance : visionRange * zone.getGrid().getSize() / zone.getUnitsPerCell(); //now calculate the shape and return the shaped Area to the caller switch (getShape()) { case CIRCLE: visibleArea = new Area(new Ellipse2D.Double(-visionRange, -visionRange, visionRange * 2, visionRange * 2)); break; case SQUARE: visibleArea = new Area(new Rectangle2D.Double(-visionRange, -visionRange, visionRange * 2, visionRange * 2)); break; case CONE: if (token.getFacing() == null) { token.setFacing(0); } int offsetAngle = getOffset(); int arcAngle = getArc(); //TODO: confirm if we want the offset to be positive-counter-clockwise, negative-clockwise or vice versa //simply a matter of changing the sign on offsetAngle Area tempvisibleArea = new Area(new Arc2D.Double(-visionRange, -visionRange, visionRange * 2, visionRange * 2, 360.0 - (arcAngle / 2.0) + (offsetAngle * 1.0), arcAngle, Arc2D.PIE)); // Rotate tempvisibleArea = tempvisibleArea.createTransformedArea(AffineTransform.getRotateInstance(-Math.toRadians(token.getFacing()))); Rectangle footprint = token.getFootprint(zone.getGrid()).getBounds(zone.getGrid()); footprint.x = -footprint.width / 2; footprint.y = -footprint.height / 2; //footprint = footprint.createTransformedArea(AffineTransform.getTranslateInstance(-footprint.getBounds().getWidth() / 2, -footprint.getBounds().getHeight() / 2)); visibleArea.add(new Area(footprint)); visibleArea.add(tempvisibleArea); break; default: visibleArea = new Area(new Ellipse2D.Double(-visionRange, -visionRange, visionRange * 2, visionRange * 2)); break; } return visibleArea; } }