Expand City and bound plot search
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
This file is part of Metropolis.
|
||||
|
||||
Metropolis is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Metropolis is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Metropolis. If not, see <https://www.gnu.org/licenses/agpl-3.0.txt>.
|
||||
*/
|
||||
|
||||
package com.majinnaibu.bukkitplugins.metropolis;
|
||||
|
||||
public final class CityRegionBounds {
|
||||
private CityRegionBounds() {}
|
||||
|
||||
public static Cuboid expandToContain(
|
||||
Cuboid existing, Cuboid requested, Iterable<Cuboid> occupiedRegions) {
|
||||
int minX = Math.min(existing.minX, requested.minX);
|
||||
int minY = Math.min(existing.minY, requested.minY);
|
||||
int minZ = Math.min(existing.minZ, requested.minZ);
|
||||
int maxX = Math.max(existing.maxX, requested.maxX);
|
||||
int maxY = Math.max(existing.maxY, requested.maxY);
|
||||
int maxZ = Math.max(existing.maxZ, requested.maxZ);
|
||||
|
||||
for (Cuboid occupied : occupiedRegions) {
|
||||
minX = Math.min(minX, occupied.minX);
|
||||
minY = Math.min(minY, occupied.minY);
|
||||
minZ = Math.min(minZ, occupied.minZ);
|
||||
maxX = Math.max(maxX, occupied.maxX);
|
||||
maxY = Math.max(maxY, occupied.maxY);
|
||||
maxZ = Math.max(maxZ, occupied.maxZ);
|
||||
}
|
||||
|
||||
return new Cuboid(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
}
|
||||
}
|
||||
@@ -209,7 +209,7 @@ public class MetropolisPlugin extends JavaPlugin {
|
||||
plotOffsetX = safeGetIntFromConfig(config, "plot.offsetX");
|
||||
plotOffsetY = safeGetIntFromConfig(config, "plot.offsetY");
|
||||
plotOffsetZ = safeGetIntFromConfig(config, "plot.offsetZ");
|
||||
maxLevels = optionalIntFromConfig(config, "plot.maxLevels", "maxLevels", 1);
|
||||
maxLevels = optionalIntFromConfig(config, "plot.maxLevels", 1);
|
||||
generateFloor = safeGetBooleanFromConfig(config, "plot.floor.generate");
|
||||
floorMaterial = safeGetMaterialFromConfig(config, "plot.floor.material");
|
||||
spaceAboveFloor = safeGetIntFromConfig(config, "plot.floor.clearSpaceAbove");
|
||||
@@ -919,14 +919,26 @@ public class MetropolisPlugin extends JavaPlugin {
|
||||
int ring = 0;
|
||||
int min = -ring;
|
||||
int max = ring - (plotMultiplier - 1);
|
||||
boolean done = false;
|
||||
int levelCount = getEffectiveMaxLevels();
|
||||
if (levelCount == 0) {
|
||||
getLogger().severe("No configured plot level fits within the world's build height.");
|
||||
return null;
|
||||
}
|
||||
|
||||
while (!done) {
|
||||
var worldBorder = world.getWorldBorder();
|
||||
Location borderCenter = worldBorder.getCenter();
|
||||
int maxSearchRing =
|
||||
PlotWorldBorderBounds.maximumSearchRing(
|
||||
worldBorder.getSize(),
|
||||
borderCenter.getX(),
|
||||
borderCenter.getZ(),
|
||||
plotOffsetX,
|
||||
plotOffsetZ,
|
||||
gridSizeX,
|
||||
gridSizeZ,
|
||||
plotMultiplier);
|
||||
|
||||
while (ring <= maxSearchRing) {
|
||||
row = min;
|
||||
col = min;
|
||||
|
||||
@@ -988,13 +1000,9 @@ public class MetropolisPlugin extends JavaPlugin {
|
||||
ring++;
|
||||
min = -ring;
|
||||
max = ring - (plotMultiplier - 1);
|
||||
if (ring > 256) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
getLogger()
|
||||
.severe("Unable to find an available supported plot within the allocation search area.");
|
||||
getLogger().severe("Unable to find an available supported plot before the world border.");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1004,7 +1012,17 @@ public class MetropolisPlugin extends JavaPlugin {
|
||||
}
|
||||
|
||||
private boolean isAvailableSupportedPlot(int row, int col, int plotMultiplier, int level) {
|
||||
return !areBlocksOccupied(row, col, plotMultiplier, level)
|
||||
Location borderCenter = world.getWorldBorder().getCenter();
|
||||
Cuboid candidateGrid =
|
||||
new Cuboid(
|
||||
getGridMin(row, col, plotMultiplier, level),
|
||||
getGridMax(row, col, plotMultiplier, level));
|
||||
return PlotWorldBorderBounds.contains(
|
||||
candidateGrid,
|
||||
world.getWorldBorder().getSize(),
|
||||
borderCenter.getX(),
|
||||
borderCenter.getZ())
|
||||
&& !areBlocksOccupied(row, col, plotMultiplier, level)
|
||||
&& PlotLevelSupport.hasCompleteSupport(
|
||||
row, col, plotMultiplier, level, this::isGeneratedLogicalBlock);
|
||||
}
|
||||
@@ -1027,11 +1045,19 @@ public class MetropolisPlugin extends JavaPlugin {
|
||||
if (cityRegion instanceof ProtectedCuboidRegion) {
|
||||
ProtectedCuboidRegion region = (ProtectedCuboidRegion) cityRegion;
|
||||
|
||||
BlockVector3 min;
|
||||
BlockVector3 max;
|
||||
|
||||
min = getPlotMin(-size / 2, -size / 2, 1);
|
||||
max = getPlotMax(size / 2, size / 2, 1);
|
||||
Cuboid requestedCityBounds =
|
||||
new Cuboid(getPlotMin(-size / 2, -size / 2, 1), getPlotMax(size / 2, size / 2, 1));
|
||||
List<Cuboid> occupiedBounds = new ArrayList<>();
|
||||
for (Plot plot : _occupiedPlots) {
|
||||
occupiedBounds.add(plot.getCuboid());
|
||||
}
|
||||
if (_spawnCuboid != null) {
|
||||
occupiedBounds.add(_spawnCuboid);
|
||||
}
|
||||
Cuboid cityBounds =
|
||||
CityRegionBounds.expandToContain(_cityCuboid, requestedCityBounds, occupiedBounds);
|
||||
BlockVector3 min = cityBounds.getMin();
|
||||
BlockVector3 max = cityBounds.getMax();
|
||||
|
||||
ProtectedCuboidRegion resizedRegion = new ProtectedCuboidRegion(region.getId(), min, max);
|
||||
resizedRegion.copyFrom(region);
|
||||
@@ -1233,6 +1259,7 @@ public class MetropolisPlugin extends JavaPlugin {
|
||||
homeNumber,
|
||||
newHomeRegion.getMinimumPoint(),
|
||||
newHomeRegion.getMaximumPoint());
|
||||
resizeCityRegion();
|
||||
_currentHomes.put(playerId, homeNumber);
|
||||
saveCurrentHomes();
|
||||
|
||||
@@ -1383,6 +1410,7 @@ public class MetropolisPlugin extends JavaPlugin {
|
||||
regionManager.addRegion(reservedRegion);
|
||||
|
||||
_occupiedPlots.add(Plot.get(reservedRegion));
|
||||
resizeCityRegion();
|
||||
saveRegions();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
This file is part of Metropolis.
|
||||
|
||||
Metropolis is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Metropolis is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Metropolis. If not, see <https://www.gnu.org/licenses/agpl-3.0.txt>.
|
||||
*/
|
||||
|
||||
package com.majinnaibu.bukkitplugins.metropolis;
|
||||
|
||||
public final class PlotWorldBorderBounds {
|
||||
private PlotWorldBorderBounds() {}
|
||||
|
||||
public static int maximumSearchRing(
|
||||
double borderSize,
|
||||
double borderCenterX,
|
||||
double borderCenterZ,
|
||||
int offsetX,
|
||||
int offsetZ,
|
||||
int gridSizeX,
|
||||
int gridSizeZ,
|
||||
int plotMultiplier) {
|
||||
if (borderSize <= 0 || gridSizeX <= 0 || gridSizeZ <= 0 || plotMultiplier < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
double halfBorder = borderSize / 2;
|
||||
double farthestX = halfBorder + Math.abs(borderCenterX - offsetX);
|
||||
double farthestZ = halfBorder + Math.abs(borderCenterZ - offsetZ);
|
||||
double cellRadius = Math.max(farthestX / gridSizeX, farthestZ / gridSizeZ);
|
||||
long bound = (long) Math.ceil(cellRadius) + plotMultiplier + 1L;
|
||||
return (int) Math.min(bound, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public static boolean contains(Cuboid bounds, double borderSize, double centerX, double centerZ) {
|
||||
if (borderSize <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double halfBorder = borderSize / 2;
|
||||
double borderMinX = centerX - halfBorder;
|
||||
double borderMaxX = centerX + halfBorder;
|
||||
double borderMinZ = centerZ - halfBorder;
|
||||
double borderMaxZ = centerZ + halfBorder;
|
||||
return bounds.minX + 0.5 >= borderMinX
|
||||
&& bounds.maxX + 0.5 <= borderMaxX
|
||||
&& bounds.minZ + 0.5 >= borderMinZ
|
||||
&& bounds.maxZ + 0.5 <= borderMaxZ;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user