Skip to content

Commit 189a18e

Browse files
committed
Rework regions to use SportBukkit math features, implement point regions
1 parent 2efbec5 commit 189a18e

31 files changed

+618
-317
lines changed

src/main/java/in/twizmwaz/cardinal/module/region/AbstractRegion.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.bukkit.block.Block;
3333

3434
import java.util.Collection;
35+
import java.util.Random;
3536

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

4344
private Collection<Block> blocks;
4445

46+
private Random random = new Random();
47+
4548
}

src/main/java/in/twizmwaz/cardinal/module/region/RegionBounds.java

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@
2828
import com.google.common.collect.ImmutableSet;
2929
import in.twizmwaz.cardinal.match.Match;
3030
import in.twizmwaz.cardinal.module.region.type.BlockRegion;
31-
import in.twizmwaz.cardinal.util.Vectors;
31+
import in.twizmwaz.cardinal.util.Geometry;
3232
import lombok.Data;
3333
import org.bukkit.block.Block;
34+
import org.bukkit.util.Cuboid;
3435
import org.bukkit.util.Vector;
3536

3637
import java.util.Collection;
@@ -44,19 +45,18 @@
4445
public class RegionBounds {
4546

4647
private final Match match;
47-
private final Vector min;
48-
private final Vector max;
48+
private final Cuboid cuboid;
4949

5050
public static RegionBounds empty(Match match) {
51-
return new RegionBounds(match, Vectors.max(), Vectors.min());
51+
return new RegionBounds(match, Cuboid.empty());
5252
}
5353

5454
public static RegionBounds unbounded(Match match) {
55-
return new RegionBounds(match, Vectors.min(), Vectors.max());
55+
return new RegionBounds(match, Cuboid.unbounded());
5656
}
5757

5858
public RegionBounds translate(Vector offset) {
59-
return new RegionBounds(match, min.plus(offset), max.plus(offset));
59+
return new RegionBounds(match, cuboid.translate(offset));
6060
}
6161

6262
/**
@@ -67,9 +67,9 @@ public RegionBounds translate(Vector offset) {
6767
* @return The mirrored region bounds.
6868
*/
6969
public RegionBounds mirror(Vector origin, Vector normal) {
70-
return new RegionBounds(match,
71-
Vectors.getMirroredVector(min, origin, normal),
72-
Vectors.getMirroredVector(max, origin, normal));
70+
return new RegionBounds(match, Cuboid.between(
71+
Geometry.getMirrored(cuboid.minimum(), origin, normal),
72+
Geometry.getMirrored(cuboid.maximum(), origin, normal)));
7373
}
7474

7575
/**
@@ -78,16 +78,11 @@ public RegionBounds mirror(Vector origin, Vector normal) {
7878
* @return If the bounds are bounded.
7979
*/
8080
public boolean isBounded() {
81-
return !(Double.isInfinite(min.getX())
82-
|| Double.isInfinite(max.getX())
83-
|| Double.isInfinite(min.getY())
84-
|| Double.isInfinite(max.getY())
85-
|| Double.isInfinite(min.getZ())
86-
|| Double.isInfinite(max.getZ()));
81+
return cuboid.isFinite();
8782
}
8883

8984
public Vector getCenter() {
90-
return min.midpoint(max);
85+
return cuboid.center();
9186
}
9287

9388
public BlockRegion getCenterBlock() {
@@ -100,17 +95,17 @@ public BlockRegion getCenterBlock() {
10095
* @return The blocks.
10196
*/
10297
public Collection<Block> getBlocks() {
103-
if (!isBounded()) {
98+
if (!cuboid.isBlockFinite()) {
10499
throw new UnsupportedOperationException("Cannot get blocks in unbounded region");
105100
}
106-
Vector min = Vectors.alignToBlock(this.min);
107-
Vector max = Vectors.alignToBlock(this.max);
101+
Vector min = Geometry.alignToBlock(this.cuboid.minimum());
102+
Vector max = Geometry.alignToBlock(this.cuboid.maximum());
108103

109104
ImmutableSet.Builder<Block> builder = ImmutableSet.builder();
110105
for (int z = min.getBlockZ(); z < max.getBlockZ(); z++) {
111106
for (int y = min.getBlockY(); y < max.getBlockY(); y++) {
112107
for (int x = min.getBlockX(); x < max.getBlockX(); x++) {
113-
builder.add(new Vector(x, y, z).toLocation(match.getWorld()).getBlock()); //TODO: Get match world
108+
builder.add(new Vector(x, y, z).toLocation(match.getWorld()).getBlock());
114109
}
115110
}
116111
}

src/main/java/in/twizmwaz/cardinal/module/region/RegionModule.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import in.twizmwaz.cardinal.module.region.parser.CuboidRegionParser;
4545
import in.twizmwaz.cardinal.module.region.parser.CylinderRegionParser;
4646
import in.twizmwaz.cardinal.module.region.parser.HalfRegionParser;
47+
import in.twizmwaz.cardinal.module.region.parser.PointRegionParser;
4748
import in.twizmwaz.cardinal.module.region.parser.RectangleRegionParser;
4849
import in.twizmwaz.cardinal.module.region.parser.SphereRegionParser;
4950
import in.twizmwaz.cardinal.module.region.parser.modifications.ComplementRegionParser;
@@ -176,6 +177,8 @@ public Region getRegion(Match match, Element element, String... alternateAttribu
176177
return checkRegion(match, id, new TranslatedRegion(new TranslatedRegionParser(match, element)));
177178
case "mirror":
178179
return checkRegion(match, id, new MirroredRegion(new MirroredRegionParser(match, element)));
180+
case "point":
181+
return checkRegion(match, id, PointRegionParser.generateRegion(match, element));
179182
default:
180183
if (id != null) {
181184
Region region = getRegionById(match, id);
@@ -199,7 +202,12 @@ public Region getRegion(Match match, Element element, String... alternateAttribu
199202

200203
private Region checkRegion(Match match, String id, Region region) {
201204
if (id != null) {
202-
regions.get(match).put(id, region);
205+
if (!regions.get(match).containsKey(id)) {
206+
regions.get(match).put(id, region);
207+
} else {
208+
errors.add(new ModuleError(this, match.getMap(),
209+
new String[] {"Cannot have two regions assigned to the same id."}, false));
210+
}
203211
}
204212
return region;
205213
}

src/main/java/in/twizmwaz/cardinal/module/region/parser/BlockRegionParser.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import in.twizmwaz.cardinal.module.region.RegionParser;
3030
import in.twizmwaz.cardinal.module.region.exception.property.InvalidRegionPropertyException;
3131
import in.twizmwaz.cardinal.module.region.exception.property.MissingRegionPropertyException;
32-
import in.twizmwaz.cardinal.util.Vectors;
32+
import in.twizmwaz.cardinal.util.Numbers;
3333
import lombok.Getter;
3434
import org.bukkit.util.Vector;
3535
import org.jdom2.Element;
@@ -52,7 +52,7 @@ public BlockRegionParser(Element element) throws RegionException {
5252
if (text == null) {
5353
throw new MissingRegionPropertyException("location", element);
5454
}
55-
vector = Vectors.getVector(text);
55+
vector = Numbers.getVector(text);
5656
if (vector == null) {
5757
throw new InvalidRegionPropertyException("location", element);
5858
}

src/main/java/in/twizmwaz/cardinal/module/region/parser/CircleRegionParser.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,10 @@
3030
import in.twizmwaz.cardinal.module.region.exception.attribute.InvalidRegionAttributeException;
3131
import in.twizmwaz.cardinal.module.region.exception.attribute.MissingRegionAttributeException;
3232
import in.twizmwaz.cardinal.util.Numbers;
33-
import in.twizmwaz.cardinal.util.Vectors;
3433
import lombok.Getter;
3534
import org.bukkit.util.Vector;
3635
import org.jdom2.Element;
3736

38-
import java.util.List;
39-
4037
@Getter
4138
public class CircleRegionParser implements RegionParser {
4239

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

6360
String radiusValue = element.getAttributeValue("radius");
6461
if (radiusValue == null) {

src/main/java/in/twizmwaz/cardinal/module/region/parser/CuboidRegionParser.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,16 @@
3030
import in.twizmwaz.cardinal.module.region.exception.RegionAttributeException;
3131
import in.twizmwaz.cardinal.module.region.exception.attribute.InvalidRegionAttributeException;
3232
import in.twizmwaz.cardinal.module.region.exception.attribute.MissingRegionAttributeException;
33-
import in.twizmwaz.cardinal.util.Vectors;
33+
import in.twizmwaz.cardinal.util.Numbers;
3434
import lombok.Getter;
35+
import org.bukkit.util.Cuboid;
3536
import org.bukkit.util.Vector;
3637
import org.jdom2.Element;
3738

3839
@Getter
3940
public class CuboidRegionParser implements RegionParser {
4041

41-
private final Vector min;
42-
private final Vector max;
42+
private final Cuboid cuboid;
4343

4444
/**
4545
* Parses an element for a cuboid region.
@@ -52,7 +52,7 @@ public CuboidRegionParser(Element element) throws RegionException {
5252
if (minValue == null) {
5353
throw new MissingRegionAttributeException("min", element);
5454
}
55-
Vector min = Vectors.getVector(minValue);
55+
Vector min = Numbers.getVector(minValue);
5656
if (min == null) {
5757
throw new InvalidRegionAttributeException("min", element);
5858
}
@@ -61,13 +61,12 @@ public CuboidRegionParser(Element element) throws RegionException {
6161
if (maxValue == null) {
6262
throw new MissingRegionAttributeException("max", element);
6363
}
64-
Vector max = Vectors.getVector(maxValue);
64+
Vector max = Numbers.getVector(maxValue);
6565
if (max == null) {
6666
throw new InvalidRegionAttributeException("max", element);
6767
}
6868

69-
this.min = Vector.getMinimum(min, max);
70-
this.max = Vector.getMaximum(min, max);
69+
this.cuboid = Cuboid.between(min, max);
7170
}
7271

7372
}

src/main/java/in/twizmwaz/cardinal/module/region/parser/CylinderRegionParser.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import in.twizmwaz.cardinal.module.region.exception.attribute.InvalidRegionAttributeException;
3131
import in.twizmwaz.cardinal.module.region.exception.attribute.MissingRegionAttributeException;
3232
import in.twizmwaz.cardinal.util.Numbers;
33-
import in.twizmwaz.cardinal.util.Vectors;
3433
import lombok.Getter;
3534
import org.bukkit.util.Vector;
3635
import org.jdom2.Element;
@@ -53,7 +52,7 @@ public CylinderRegionParser(Element element) throws RegionException {
5352
if (baseValue == null) {
5453
throw new MissingRegionAttributeException("base", element);
5554
}
56-
base = Vectors.getVector(baseValue);
55+
base = Numbers.getVector(baseValue);
5756
if (base == null) {
5857
throw new InvalidRegionAttributeException("base", element);
5958
}

src/main/java/in/twizmwaz/cardinal/module/region/parser/HalfRegionParser.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import in.twizmwaz.cardinal.module.region.RegionParser;
3030
import in.twizmwaz.cardinal.module.region.exception.attribute.InvalidRegionAttributeException;
3131
import in.twizmwaz.cardinal.module.region.exception.attribute.MissingRegionAttributeException;
32-
import in.twizmwaz.cardinal.util.Vectors;
32+
import in.twizmwaz.cardinal.util.Numbers;
3333
import lombok.Getter;
3434
import org.bukkit.util.Vector;
3535
import org.jdom2.Element;
@@ -51,7 +51,7 @@ public HalfRegionParser(Element element) throws RegionException {
5151
if (normalValue == null) {
5252
throw new MissingRegionAttributeException("normal", element);
5353
}
54-
normal = Vectors.getVector(normalValue);
54+
normal = Numbers.getVector(normalValue);
5555
if (normal == null) {
5656
throw new InvalidRegionAttributeException("normal", element);
5757
}
@@ -60,7 +60,7 @@ public HalfRegionParser(Element element) throws RegionException {
6060
if (originValue == null) {
6161
throw new MissingRegionAttributeException("origin", element);
6262
}
63-
origin = Vectors.getVector(originValue);
63+
origin = Numbers.getVector(originValue);
6464
if (origin == null) {
6565
throw new InvalidRegionAttributeException("origin", element);
6666
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Copyright (c) 2016, Kevin Phoenix
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
*
8+
* 1. Redistributions of source code must retain the above copyright notice, this
9+
* list of conditions and the following disclaimer.
10+
* 2. Redistributions in binary form must reproduce the above copyright notice,
11+
* this list of conditions and the following disclaimer in the documentation
12+
* and/or other materials provided with the distribution.
13+
*
14+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18+
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
package in.twizmwaz.cardinal.module.region.parser;
27+
28+
import com.google.common.base.Strings;
29+
import in.twizmwaz.cardinal.Cardinal;
30+
import in.twizmwaz.cardinal.match.Match;
31+
import in.twizmwaz.cardinal.module.region.Region;
32+
import in.twizmwaz.cardinal.module.region.RegionException;
33+
import in.twizmwaz.cardinal.module.region.RegionModule;
34+
import in.twizmwaz.cardinal.module.region.RegionParser;
35+
import in.twizmwaz.cardinal.module.region.exception.property.MissingRegionPropertyException;
36+
import in.twizmwaz.cardinal.module.region.type.PointRegion;
37+
import in.twizmwaz.cardinal.module.region.type.modifications.PointProviderRegion;
38+
import in.twizmwaz.cardinal.util.Numbers;
39+
import in.twizmwaz.cardinal.util.ParseUtil;
40+
import lombok.Getter;
41+
import lombok.NonNull;
42+
import org.bukkit.Location;
43+
import org.bukkit.util.Vector;
44+
import org.jdom2.Element;
45+
46+
@Getter
47+
public class PointRegionParser implements RegionParser {
48+
49+
private final float yaw;
50+
private final float pitch;
51+
private Vector position = null;
52+
private Vector angle = null;
53+
private Region region = null;
54+
55+
private PointRegionParser(@NonNull Match match, @NonNull Element element) throws RegionException {
56+
yaw = Numbers.parseFloat(ParseUtil.getFirstAttribute("yaw"));
57+
pitch = Numbers.parseFloat(element.getAttributeValue("pitch"));
58+
59+
if (!Strings.isNullOrEmpty(element.getText().trim())) {
60+
position = Numbers.getVector(element.getText());
61+
}
62+
63+
if (!Strings.isNullOrEmpty(element.getAttributeValue("angle", "").trim())) {
64+
angle = Numbers.getVector(element.getAttributeValue("angle"));
65+
}
66+
67+
RegionModule module = Cardinal.getModule(RegionModule.class);
68+
69+
if (!Strings.isNullOrEmpty(element.getAttributeValue("region"))) {
70+
71+
Region region = module.getRegionById(match, element.getAttributeValue("region"));
72+
this.region = region;
73+
74+
} else if (element.getChildren("region").size() > 0) {
75+
76+
region = module.getRegion(match, element.getChild("region"));
77+
78+
}
79+
}
80+
81+
/**
82+
* Parses a region from the Element.
83+
*
84+
* <p>This method is different from other parsers intentionally. Point regions are different in that for some reason,
85+
* we have two different types with similar yet different purposes. This method is in place to differentiate between
86+
* the region types and to return the correct one without something ugly in the module class.</p>
87+
*
88+
* @param match The match.
89+
* @param element The element to parse.
90+
* @return The region, if applicable.
91+
* @throws RegionException A {@link MissingRegionPropertyException} when there is no valid location.
92+
*/
93+
public static Region generateRegion(@NonNull Match match, @NonNull Element element) throws RegionException {
94+
PointRegionParser parser = new PointRegionParser(match, element);
95+
if (parser.getPosition() != null) {
96+
Location location = parser.getPosition().toLocation(match.getWorld(), parser.getYaw(), parser.getPitch());
97+
if (parser.getAngle() != null) {
98+
location.setDirection(parser.getAngle());
99+
}
100+
return new PointRegion(match, location);
101+
} else if (parser.getRegion() != null) {
102+
return new PointProviderRegion(parser.getRegion(), parser.getAngle(), parser.getYaw(), parser.getPitch());
103+
} else {
104+
throw new MissingRegionPropertyException("position", element);
105+
}
106+
107+
}
108+
109+
}

0 commit comments

Comments
 (0)