Skip to content

Commit 0e84ca8

Browse files
Pablete1234twizmwazin
authored andcommitted
Add FiniteBlockRegion, fix Intersect & Complement regions
1 parent f333e8c commit 0e84ca8

File tree

6 files changed

+157
-8
lines changed

6 files changed

+157
-8
lines changed

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,21 @@ public RegionBounds mirror(Vector origin, Vector normal) {
7272
Geometry.getMirrored(cuboid.maximum(), origin, normal)));
7373
}
7474

75+
/**
76+
* Substracts other regions.
77+
*
78+
* @param complement Regions to substract.
79+
* @return The complemented region bounds.
80+
*/
81+
public RegionBounds complement(Collection<Region> complement) {
82+
Cuboid result = Cuboid.between(this.cuboid.minimum(), this.cuboid.maximum());
83+
for (Region substract : complement) {
84+
// Fixme: this will cause problems, because the substracted region doesn't have the same size as its bounds.
85+
result = Cuboid.complement(result, substract.getBounds().getCuboid());
86+
}
87+
return new RegionBounds(match, result);
88+
}
89+
7590
/**
7691
* Checks if region bounds are bounded (non-infinite).
7792
*
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
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.type;
27+
28+
import in.twizmwaz.cardinal.match.Match;
29+
import in.twizmwaz.cardinal.module.region.AbstractRegion;
30+
import in.twizmwaz.cardinal.module.region.Region;
31+
import in.twizmwaz.cardinal.module.region.RegionBounds;
32+
import in.twizmwaz.cardinal.util.Geometry;
33+
import in.twizmwaz.cardinal.util.ListUtil;
34+
import in.twizmwaz.cardinal.util.MaterialPattern;
35+
import org.bukkit.block.Block;
36+
import org.bukkit.util.Cuboid;
37+
import org.bukkit.util.Vector;
38+
39+
import java.util.ArrayList;
40+
import java.util.Collection;
41+
import java.util.List;
42+
import java.util.stream.Collectors;
43+
44+
public class FiniteBlockRegion extends AbstractRegion {
45+
46+
private FiniteBlockRegion(RegionBounds bounds, List<Block> blocks) {
47+
super(bounds);
48+
super.setBlocks(blocks);
49+
}
50+
51+
@Override
52+
public Collection<Block> getBlocks() {
53+
return super.getBlocks();
54+
}
55+
56+
@Override
57+
public Vector getRandomPoint() {
58+
return ListUtil.getRandom((List<Block>) super.getBlocks()).getLocation();
59+
}
60+
61+
@Override
62+
public boolean isBounded() {
63+
return true;
64+
}
65+
66+
public boolean contains(Vector evaluating) {
67+
evaluating = Geometry.floor(evaluating);
68+
for (Block block : super.getBlocks()) {
69+
if (block.getLocation().equals(evaluating)) {
70+
return true;
71+
}
72+
}
73+
return false;
74+
}
75+
76+
@Override
77+
public boolean isRandomizable() {
78+
return true;
79+
}
80+
81+
/**
82+
* Creates a block finite region that matches a material.
83+
* @param match The match this region belongs to.
84+
* @param region The region to build the finite block region on. MUST be bounded.
85+
* @param pattern The material pattern to filter blocks.
86+
* @return A FiniteBlockRegion containing all regions that matched the pattern.
87+
*/
88+
public FiniteBlockRegion getFromMaterialPattern(Match match, Region region, MaterialPattern pattern) {
89+
List<Block> blocks = region.getBlocks().stream().filter(block -> pattern.contains(block.getType(), block.getData()))
90+
.collect(Collectors.toList());
91+
return new FiniteBlockRegion(new RegionBounds(match, getBounds(blocks)), blocks);
92+
}
93+
94+
95+
private Cuboid getBounds(List<Block> blocks) {
96+
List<Vector> vectors = new ArrayList<>();
97+
vectors.addAll(blocks.stream().map(Block::getLocation).collect(Collectors.toList()));
98+
vectors.addAll(blocks.stream().map(block -> block.getLocation().plus(1, 1, 1)).collect(Collectors.toList()));
99+
return Cuboid.enclosing(vectors.toArray(new Vector[vectors.size()]));
100+
}
101+
102+
}

src/main/java/in/twizmwaz/cardinal/module/region/type/modifications/ComplementRegion.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public class ComplementRegion extends AbstractRegion {
4848
* @param complements The complements.
4949
*/
5050
public ComplementRegion(Region region, List<Region> complements) {
51-
super(region.getBounds());
51+
super(region.getBounds().complement(complements));
5252
this.region = region;
5353
this.complements = complements;
5454
}

src/main/java/in/twizmwaz/cardinal/module/region/type/modifications/IntersectRegion.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public class IntersectRegion extends AbstractRegion {
4343
private final Collection<Region> regions;
4444

4545
public IntersectRegion(Match match, Collection<Region> regions) {
46-
super(new RegionBounds(match, Geometry.getCuboidEnclosing(regions)));
46+
super(new RegionBounds(match, Geometry.getCuboidIntersecting(regions)));
4747
this.regions = regions;
4848
}
4949

src/main/java/in/twizmwaz/cardinal/module/region/type/modifications/UnionRegion.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,7 @@ public boolean isRandomizable() {
6464

6565
@Override
6666
public boolean isBounded() {
67-
for (Region region : regions) {
68-
if (!region.isBounded()) {
69-
return false;
70-
}
71-
}
72-
return true;
67+
return getBounds().isBounded();
7368
}
7469

7570
@Override

src/main/java/in/twizmwaz/cardinal/util/Geometry.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
import org.bukkit.util.Vector;
3232

3333
import java.util.Collection;
34+
import java.util.Comparator;
35+
import java.util.List;
36+
import java.util.function.Function;
3437
import java.util.stream.Collectors;
3538

3639
public class Geometry {
@@ -93,6 +96,16 @@ public static Vector getMinimum(@NonNull Vector... vectors) {
9396
return Cuboid.enclosing(vectors).minimum();
9497
}
9598

99+
/**
100+
* Gets the second minimum double from a list of doubles.
101+
*
102+
* @param doubles The list of doubles.
103+
* @return The second minimum double.
104+
*/
105+
public static double getSecondMinimum(@NonNull List<Double> doubles) {
106+
return doubles.stream().sorted().collect(Collectors.toList()).get(1);
107+
}
108+
96109
/**
97110
* Gets the maximum vector from a list of regions.
98111
*
@@ -151,4 +164,28 @@ public static Cuboid getCuboidEnclosing(Collection<Region> regions) {
151164
return Cuboid.between(getMinimumBound(regions), getMaximumBound(regions));
152165
}
153166

167+
public static Cuboid getCuboidIntersecting(Collection<Region> regions) {
168+
if (regions.size() < 2) {
169+
return Cuboid.empty();
170+
}
171+
List<Vector>
172+
mins = regions.stream().map(region -> region.getBounds().getCuboid().minimum()).collect(Collectors.toList()),
173+
maxs = regions.stream().map(region -> region.getBounds().getCuboid().maximum()).collect(Collectors.toList());
174+
return Cuboid.between(
175+
new Vector(
176+
getSecond(mins, Vector::getX, false),
177+
getSecond(mins, Vector::getY, false),
178+
getSecond(mins, Vector::getZ, false)),
179+
new Vector(
180+
getSecond(maxs, Vector::getX, true),
181+
getSecond(maxs, Vector::getY, true),
182+
getSecond(maxs, Vector::getZ, true)));
183+
}
184+
185+
186+
private static double getSecond(@NonNull List<Vector> vectors, Function<Vector, Double> function, boolean max) {
187+
return vectors.stream().map(function)
188+
.sorted(max ? Comparator.reverseOrder() : Comparator.naturalOrder()).collect(Collectors.toList()).get(1);
189+
}
190+
154191
}

0 commit comments

Comments
 (0)