Skip to content

Rework regions to use SportBukkit math features, implement point regions #3

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.bukkit.block.Block;

import java.util.Collection;
import java.util.Random;

@Getter
@Setter(AccessLevel.PROTECTED)
Expand All @@ -42,4 +43,6 @@ public abstract class AbstractRegion implements Region {

private Collection<Block> blocks;

private Random random = new Random();

}
35 changes: 15 additions & 20 deletions src/main/java/in/twizmwaz/cardinal/module/region/RegionBounds.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@
import com.google.common.collect.ImmutableSet;
import in.twizmwaz.cardinal.match.Match;
import in.twizmwaz.cardinal.module.region.type.BlockRegion;
import in.twizmwaz.cardinal.util.Vectors;
import in.twizmwaz.cardinal.util.Geometry;
import lombok.Data;
import org.bukkit.block.Block;
import org.bukkit.util.Cuboid;
import org.bukkit.util.Vector;

import java.util.Collection;
Expand All @@ -44,19 +45,18 @@
public class RegionBounds {

private final Match match;
private final Vector min;
private final Vector max;
private final Cuboid cuboid;

public static RegionBounds empty(Match match) {
return new RegionBounds(match, Vectors.max(), Vectors.min());
return new RegionBounds(match, Cuboid.empty());
}

public static RegionBounds unbounded(Match match) {
return new RegionBounds(match, Vectors.min(), Vectors.max());
return new RegionBounds(match, Cuboid.unbounded());
}

public RegionBounds translate(Vector offset) {
return new RegionBounds(match, min.plus(offset), max.plus(offset));
return new RegionBounds(match, cuboid.translate(offset));
}

/**
Expand All @@ -67,9 +67,9 @@ public RegionBounds translate(Vector offset) {
* @return The mirrored region bounds.
*/
public RegionBounds mirror(Vector origin, Vector normal) {
return new RegionBounds(match,
Vectors.getMirroredVector(min, origin, normal),
Vectors.getMirroredVector(max, origin, normal));
return new RegionBounds(match, Cuboid.between(
Geometry.getMirrored(cuboid.minimum(), origin, normal),
Geometry.getMirrored(cuboid.maximum(), origin, normal)));
}

/**
Expand All @@ -78,16 +78,11 @@ public RegionBounds mirror(Vector origin, Vector normal) {
* @return If the bounds are bounded.
*/
public boolean isBounded() {
return !(Double.isInfinite(min.getX())
|| Double.isInfinite(max.getX())
|| Double.isInfinite(min.getY())
|| Double.isInfinite(max.getY())
|| Double.isInfinite(min.getZ())
|| Double.isInfinite(max.getZ()));
return cuboid.isFinite();
}

public Vector getCenter() {
return min.midpoint(max);
return cuboid.center();
}

public BlockRegion getCenterBlock() {
Expand All @@ -100,17 +95,17 @@ public BlockRegion getCenterBlock() {
* @return The blocks.
*/
public Collection<Block> getBlocks() {
if (!isBounded()) {
if (!cuboid.isBlockFinite()) {
throw new UnsupportedOperationException("Cannot get blocks in unbounded region");
}
Vector min = Vectors.alignToBlock(this.min);
Vector max = Vectors.alignToBlock(this.max);
Vector min = Geometry.alignToBlock(this.cuboid.minimum());
Vector max = Geometry.alignToBlock(this.cuboid.maximum());

ImmutableSet.Builder<Block> builder = ImmutableSet.builder();
for (int z = min.getBlockZ(); z < max.getBlockZ(); z++) {
for (int y = min.getBlockY(); y < max.getBlockY(); y++) {
for (int x = min.getBlockX(); x < max.getBlockX(); x++) {
builder.add(new Vector(x, y, z).toLocation(match.getWorld()).getBlock()); //TODO: Get match world
builder.add(new Vector(x, y, z).toLocation(match.getWorld()).getBlock());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import in.twizmwaz.cardinal.module.region.parser.CuboidRegionParser;
import in.twizmwaz.cardinal.module.region.parser.CylinderRegionParser;
import in.twizmwaz.cardinal.module.region.parser.HalfRegionParser;
import in.twizmwaz.cardinal.module.region.parser.PointRegionParser;
import in.twizmwaz.cardinal.module.region.parser.RectangleRegionParser;
import in.twizmwaz.cardinal.module.region.parser.SphereRegionParser;
import in.twizmwaz.cardinal.module.region.parser.modifications.ComplementRegionParser;
Expand Down Expand Up @@ -176,6 +177,8 @@ public Region getRegion(Match match, Element element, String... alternateAttribu
return checkRegion(match, id, new TranslatedRegion(new TranslatedRegionParser(match, element)));
case "mirror":
return checkRegion(match, id, new MirroredRegion(new MirroredRegionParser(match, element)));
case "point":
return checkRegion(match, id, PointRegionParser.generateRegion(match, element));
default:
if (id != null) {
Region region = getRegionById(match, id);
Expand All @@ -199,7 +202,12 @@ public Region getRegion(Match match, Element element, String... alternateAttribu

private Region checkRegion(Match match, String id, Region region) {
if (id != null) {
regions.get(match).put(id, region);
if (!regions.get(match).containsKey(id)) {
regions.get(match).put(id, region);
} else {
errors.add(new ModuleError(this, match.getMap(),
new String[] {"Cannot have two regions assigned to the same id."}, false));
}
}
return region;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import in.twizmwaz.cardinal.module.region.RegionParser;
import in.twizmwaz.cardinal.module.region.exception.property.InvalidRegionPropertyException;
import in.twizmwaz.cardinal.module.region.exception.property.MissingRegionPropertyException;
import in.twizmwaz.cardinal.util.Vectors;
import in.twizmwaz.cardinal.util.Numbers;
import lombok.Getter;
import org.bukkit.util.Vector;
import org.jdom2.Element;
Expand All @@ -52,7 +52,7 @@ public BlockRegionParser(Element element) throws RegionException {
if (text == null) {
throw new MissingRegionPropertyException("location", element);
}
vector = Vectors.getVector(text);
vector = Numbers.getVector(text);
if (vector == null) {
throw new InvalidRegionPropertyException("location", element);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,10 @@
import in.twizmwaz.cardinal.module.region.exception.attribute.InvalidRegionAttributeException;
import in.twizmwaz.cardinal.module.region.exception.attribute.MissingRegionAttributeException;
import in.twizmwaz.cardinal.util.Numbers;
import in.twizmwaz.cardinal.util.Vectors;
import lombok.Getter;
import org.bukkit.util.Vector;
import org.jdom2.Element;

import java.util.List;

@Getter
public class CircleRegionParser implements RegionParser {

Expand All @@ -54,11 +51,11 @@ public CircleRegionParser(Element element) throws RegionException {
if (centerValue == null) {
throw new MissingRegionAttributeException("center", element);
}
List<Double> coords = Vectors.getCoordinates(centerValue);
if (coords == null || coords.size() != 2) {
double[] coords = Numbers.parseCoordinates(centerValue);
if (coords == null || coords.length != 2) {
throw new InvalidRegionAttributeException("center", element);
}
center = new Vector(coords.get(0), 0, coords.get(1));
center = new Vector(coords[0], 0, coords[1]);

String radiusValue = element.getAttributeValue("radius");
if (radiusValue == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@
import in.twizmwaz.cardinal.module.region.exception.RegionAttributeException;
import in.twizmwaz.cardinal.module.region.exception.attribute.InvalidRegionAttributeException;
import in.twizmwaz.cardinal.module.region.exception.attribute.MissingRegionAttributeException;
import in.twizmwaz.cardinal.util.Vectors;
import in.twizmwaz.cardinal.util.Numbers;
import lombok.Getter;
import org.bukkit.util.Cuboid;
import org.bukkit.util.Vector;
import org.jdom2.Element;

@Getter
public class CuboidRegionParser implements RegionParser {

private final Vector min;
private final Vector max;
private final Cuboid cuboid;

/**
* Parses an element for a cuboid region.
Expand All @@ -52,7 +52,7 @@ public CuboidRegionParser(Element element) throws RegionException {
if (minValue == null) {
throw new MissingRegionAttributeException("min", element);
}
Vector min = Vectors.getVector(minValue);
Vector min = Numbers.getVector(minValue);
if (min == null) {
throw new InvalidRegionAttributeException("min", element);
}
Expand All @@ -61,13 +61,12 @@ public CuboidRegionParser(Element element) throws RegionException {
if (maxValue == null) {
throw new MissingRegionAttributeException("max", element);
}
Vector max = Vectors.getVector(maxValue);
Vector max = Numbers.getVector(maxValue);
if (max == null) {
throw new InvalidRegionAttributeException("max", element);
}

this.min = Vector.getMinimum(min, max);
this.max = Vector.getMaximum(min, max);
this.cuboid = Cuboid.between(min, max);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import in.twizmwaz.cardinal.module.region.exception.attribute.InvalidRegionAttributeException;
import in.twizmwaz.cardinal.module.region.exception.attribute.MissingRegionAttributeException;
import in.twizmwaz.cardinal.util.Numbers;
import in.twizmwaz.cardinal.util.Vectors;
import lombok.Getter;
import org.bukkit.util.Vector;
import org.jdom2.Element;
Expand All @@ -53,7 +52,7 @@ public CylinderRegionParser(Element element) throws RegionException {
if (baseValue == null) {
throw new MissingRegionAttributeException("base", element);
}
base = Vectors.getVector(baseValue);
base = Numbers.getVector(baseValue);
if (base == null) {
throw new InvalidRegionAttributeException("base", element);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import in.twizmwaz.cardinal.module.region.RegionParser;
import in.twizmwaz.cardinal.module.region.exception.attribute.InvalidRegionAttributeException;
import in.twizmwaz.cardinal.module.region.exception.attribute.MissingRegionAttributeException;
import in.twizmwaz.cardinal.util.Vectors;
import in.twizmwaz.cardinal.util.Numbers;
import lombok.Getter;
import org.bukkit.util.Vector;
import org.jdom2.Element;
Expand All @@ -51,7 +51,7 @@ public HalfRegionParser(Element element) throws RegionException {
if (normalValue == null) {
throw new MissingRegionAttributeException("normal", element);
}
normal = Vectors.getVector(normalValue);
normal = Numbers.getVector(normalValue);
if (normal == null) {
throw new InvalidRegionAttributeException("normal", element);
}
Expand All @@ -60,7 +60,7 @@ public HalfRegionParser(Element element) throws RegionException {
if (originValue == null) {
throw new MissingRegionAttributeException("origin", element);
}
origin = Vectors.getVector(originValue);
origin = Numbers.getVector(originValue);
if (origin == null) {
throw new InvalidRegionAttributeException("origin", element);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2016, Kevin Phoenix
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package in.twizmwaz.cardinal.module.region.parser;

import com.google.common.base.Strings;
import in.twizmwaz.cardinal.Cardinal;
import in.twizmwaz.cardinal.match.Match;
import in.twizmwaz.cardinal.module.region.Region;
import in.twizmwaz.cardinal.module.region.RegionException;
import in.twizmwaz.cardinal.module.region.RegionModule;
import in.twizmwaz.cardinal.module.region.RegionParser;
import in.twizmwaz.cardinal.module.region.exception.property.MissingRegionPropertyException;
import in.twizmwaz.cardinal.module.region.type.PointRegion;
import in.twizmwaz.cardinal.module.region.type.modifications.PointProviderRegion;
import in.twizmwaz.cardinal.util.Numbers;
import in.twizmwaz.cardinal.util.ParseUtil;
import lombok.Getter;
import lombok.NonNull;
import org.bukkit.Location;
import org.bukkit.util.Vector;
import org.jdom2.Element;

@Getter
public class PointRegionParser implements RegionParser {

private final float yaw;
private final float pitch;
private Vector position = null;
private Vector angle = null;
private Region region = null;

private PointRegionParser(@NonNull Match match, @NonNull Element element) throws RegionException {
yaw = Numbers.parseFloat(ParseUtil.getFirstAttribute("yaw"));
pitch = Numbers.parseFloat(element.getAttributeValue("pitch"));

if (!Strings.isNullOrEmpty(element.getText().trim())) {
position = Numbers.getVector(element.getText());
}

if (!Strings.isNullOrEmpty(element.getAttributeValue("angle").trim())) {
angle = Numbers.getVector(element.getAttributeValue("angle"));
}

RegionModule module = Cardinal.getModule(RegionModule.class);

if (!Strings.isNullOrEmpty(element.getAttributeValue("region"))) {

Region region = module.getRegionById(match, element.getAttributeValue("region"));
this.region = region;

} else if (element.getChildren("region").size() > 0) {

region = module.getRegion(match, element.getChild("region"));

}
}

/**
* Parses a region from the Element.
*
* <p>This method is different from other parsers intentionally. Point regions are different in that for some reason,
* we have two different types with similar yet different purposes. This method is in place to differentiate between
* the region types and to return the correct one without something ugly in the module class.</p>
*
* @param match The match.
* @param element The element to parse.
* @return The region, if applicable.
* @throws RegionException A {@link MissingRegionPropertyException} when there is no valid location.
*/
public static Region generateRegion(@NonNull Match match, @NonNull Element element) throws RegionException {
PointRegionParser parser = new PointRegionParser(match, element);
if (parser.getPosition() != null) {
Location location = parser.getPosition().toLocation(match.getWorld(), parser.getYaw(), parser.getPitch());
if (parser.getAngle() != null) {
location.setDirection(parser.getAngle());
}
return new PointRegion(match, location);
} else if (parser.getRegion() != null) {
return new PointProviderRegion(parser.getRegion(), parser.getAngle(), parser.getYaw(), parser.getPitch());
} else {
throw new MissingRegionPropertyException("position", element);
}

}

}
Loading