Compare commits

...

12 Commits

Author SHA1 Message Date
e1d2c8751a Changes README file to markdown. 2014-08-29 22:24:01 -07:00
012e1f15a3 Moved project out of subfolder. 2014-08-29 22:22:20 -07:00
dd6f91e9e2 Merge branch 'master' into 0.5 2014-08-29 22:05:47 -07:00
487e745870 Updates pom to build with newer versions of dependencies.
Removes an unneeded import.
2014-08-29 21:46:50 -07:00
4f2adc52b0 turned off extra logging 2012-04-07 22:38:27 -07:00
c7ee4f8382 Implemented multiple plot sizes 2012-04-07 22:15:56 -07:00
4018ff1cc1 Implemented User Overrides 2012-03-16 05:35:54 -07:00
dcfdc2be60 f 2012-03-11 06:49:03 -07:00
ad2b7b5bf6 Merge branch 'master' of git@github.com:headhunter45/Metropolis.git
Conflicts:
	Metropolis/src/main/java/com/majinnaibu/bukkitplugins/metropolis/MetropolisPlugin.java
	Metropolis/src/main/java/com/majinnaibu/bukkitplugins/metropolis/commands/MetropolisHomeMoveCommand.java
	Metropolis/src/main/resources/plugin.yml
2012-03-11 06:47:54 -07:00
3c46c0879a Updated default config with new entries. 2012-03-08 20:46:32 -08:00
89bd6f3a2c Implemented /metropolis-home-evict command 2012-03-07 01:30:14 -08:00
5b81e6b8b2 Added /metropolis command to display version info 2012-03-07 00:52:54 -08:00
32 changed files with 542 additions and 187 deletions

View File

View File

@@ -22,10 +22,12 @@
</scm> </scm>
<repositories> <repositories>
<!--
<repository> <repository>
<id>wg</id> <id>wg</id>
<url>http://files.zachsthings.com/repo</url> <url>http://files.zachsthings.com/repo</url>
</repository> </repository>
-->
<repository> <repository>
<id>sk89q</id> <id>sk89q</id>
<url>http://mvn2.sk89q.com/repo</url> <url>http://mvn2.sk89q.com/repo</url>
@@ -35,6 +37,18 @@
<id>bukkit-repo</id> <id>bukkit-repo</id>
<url>http://repo.bukkit.org/content/groups/public</url> <url>http://repo.bukkit.org/content/groups/public</url>
</repository> </repository>
<repository>
<id>sonatype-nexus-releases</id>
<url>https://oss.sonatype.org/content/repositories/releases</url>
</repository>
<repository>
<id>sonatype-nexus-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories> </repositories>
<dependencies> <dependencies>
@@ -42,21 +56,21 @@
<dependency> <dependency>
<groupId>com.sk89q</groupId> <groupId>com.sk89q</groupId>
<artifactId>worldedit</artifactId> <artifactId>worldedit</artifactId>
<version>5.2</version> <version>5.6.3</version>
</dependency> </dependency>
<!-- Bukkit --> <!-- Bukkit -->
<dependency> <dependency>
<groupId>org.bukkit</groupId> <groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId> <artifactId>bukkit</artifactId>
<version>1.1-R6</version> <version>1.7.9-R0.2</version>
</dependency> </dependency>
<!-- WorldGuard --> <!-- WorldGuard -->
<dependency> <dependency>
<groupId>com.sk89q</groupId> <groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId> <artifactId>worldguard</artifactId>
<version>5.5</version> <version>5.9</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@@ -1,11 +1,17 @@
package com.majinnaibu.bukkitplugins.metropolis; package com.majinnaibu.bukkitplugins.metropolis;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@@ -21,6 +27,7 @@ import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import com.majinnaibu.bukkitplugins.metropolis.commands.MetropolisCommand;
import com.majinnaibu.bukkitplugins.metropolis.commands.MetropolisDebugGenerateTestHomesCommand; import com.majinnaibu.bukkitplugins.metropolis.commands.MetropolisDebugGenerateTestHomesCommand;
import com.majinnaibu.bukkitplugins.metropolis.commands.MetropolisFlagResetCommand; import com.majinnaibu.bukkitplugins.metropolis.commands.MetropolisFlagResetCommand;
import com.majinnaibu.bukkitplugins.metropolis.commands.MetropolisHomeEvictCommand; import com.majinnaibu.bukkitplugins.metropolis.commands.MetropolisHomeEvictCommand;
@@ -31,12 +38,11 @@ import com.majinnaibu.bukkitplugins.metropolis.commands.MetropolisHomeMoveComman
import com.majinnaibu.bukkitplugins.metropolis.commands.MetropolisPlotGoCommand; import com.majinnaibu.bukkitplugins.metropolis.commands.MetropolisPlotGoCommand;
import com.majinnaibu.bukkitplugins.metropolis.commands.MetropolisPlotReserveCommand; import com.majinnaibu.bukkitplugins.metropolis.commands.MetropolisPlotReserveCommand;
import com.majinnaibu.bukkitplugins.metropolis.eventlisteners.PlayerJoinListener; import com.majinnaibu.bukkitplugins.metropolis.eventlisteners.PlayerJoinListener;
import com.sk89q.util.yaml.YAMLProcessor;
import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.domains.DefaultDomain; import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.domains.Domain;
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
import com.sk89q.worldguard.protection.flags.DefaultFlag; import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.flags.StateFlag; import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.managers.RegionManager; import com.sk89q.worldguard.protection.managers.RegionManager;
@@ -44,7 +50,7 @@ import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion; import com.sk89q.worldguard.protection.regions.ProtectedRegion;
public class MetropolisPlugin extends JavaPlugin { public class MetropolisPlugin extends JavaPlugin {
public static final boolean DEBUG = true; public static final boolean DEBUG = false;
public static final Logger log=Logger.getLogger("Minecraft"); public static final Logger log=Logger.getLogger("Minecraft");
private static final int version = 1; private static final int version = 1;
@@ -60,13 +66,16 @@ public class MetropolisPlugin extends JavaPlugin {
public RegionManager regionManager = null; public RegionManager regionManager = null;
private List<Plot> _occupiedPlots; private List<Plot> _occupiedPlots;
private HashMap<String, List<Plot>> _ownedPlots;
private HashMap<String, UserOverride> _userOverrides;
private HashMap<String, Integer> _currentHomes;
private PlayerJoinListener _playerJoinListener = null; private PlayerJoinListener _playerJoinListener = null;
int size = 1; int size = 1;
private int plotSizeX = 24; private int plotSizeX = 24;
private int plotSizeY = 256; //private int plotSizeY = 256;
private int plotSizeZ = 24; private int plotSizeZ = 24;
private int gridSizeX = 28; private int gridSizeX = 28;
private int gridSizeY = 256; private int gridSizeY = 256;
@@ -90,6 +99,8 @@ public class MetropolisPlugin extends JavaPlugin {
private boolean generateWall = false; private boolean generateWall = false;
private Material wallMaterial = Material.GLASS; private Material wallMaterial = Material.GLASS;
private int wallHeight = 128; private int wallHeight = 128;
int _maxPlots = 1;
int _plotMultiplier = 1;
private Cuboid _spawnCuboid = null; private Cuboid _spawnCuboid = null;
private Cuboid _cityCuboid = null; private Cuboid _cityCuboid = null;
@@ -106,6 +117,11 @@ public class MetropolisPlugin extends JavaPlugin {
public void onEnable() { public void onEnable() {
pdf = getDescription(); pdf = getDescription();
_ownedPlots = new HashMap<String, List<Plot>>();
_userOverrides = new HashMap<String, UserOverride>();
_currentHomes = new HashMap<String, Integer>();
loadCurrentHomes();
if(DEBUG){log.info("Checking config");} if(DEBUG){log.info("Checking config");}
Configuration config = getConfig(); Configuration config = getConfig();
if(!config.contains("version")){ if(!config.contains("version")){
@@ -113,6 +129,7 @@ public class MetropolisPlugin extends JavaPlugin {
if(DEBUG){log.info("No config exists. Assuming new installation.");} if(DEBUG){log.info("No config exists. Assuming new installation.");}
}else{ }else{
int configVersion = safeGetIntFromConfig(config, "version"); int configVersion = safeGetIntFromConfig(config, "version");
if(configVersion < version){
if(DEBUG){log.info(String.format("Updating config from version v%s to v%s.", configVersion, version));} if(DEBUG){log.info(String.format("Updating config from version v%s to v%s.", configVersion, version));}
if(configVersion != version){ if(configVersion != version){
//upgrade config //upgrade config
@@ -121,6 +138,7 @@ public class MetropolisPlugin extends JavaPlugin {
saveConfig(); saveConfig();
if(DEBUG){log.info("Config updated");} if(DEBUG){log.info("Config updated");}
} }
}
config.set("version", version); config.set("version", version);
saveConfig(); saveConfig();
@@ -149,6 +167,11 @@ public class MetropolisPlugin extends JavaPlugin {
wallMaterial = safeGetMaterialFromConfig(config, "wall.material"); wallMaterial = safeGetMaterialFromConfig(config, "wall.material");
wallHeight = safeGetIntFromConfig(config, "wall.material"); wallHeight = safeGetIntFromConfig(config, "wall.material");
worldName = safeGetStringFromConfig(config, "worldname"); worldName = safeGetStringFromConfig(config, "worldname");
_maxPlots = safeGetIntFromConfig(config, "plot.multiplier");
_plotMultiplier = safeGetIntFromConfig(config, "plot.maxPerPlayer");
buildUserOverrides();
saveConfig(); saveConfig();
if(DEBUG){log.info("Done reading config.");} if(DEBUG){log.info("Done reading config.");}
@@ -192,7 +215,7 @@ public class MetropolisPlugin extends JavaPlugin {
_cityRegion = regionManager.getRegion("City"); _cityRegion = regionManager.getRegion("City");
if(_cityRegion == null){ if(_cityRegion == null){
_cityRegion = new ProtectedCuboidRegion("City", getPlotMin(0, 0), this.getPlotMax(0, 0)); _cityRegion = new ProtectedCuboidRegion("City", getPlotMin(0, 0, 1), this.getPlotMax(0, 0, 1));
_cityRegion.setPriority(0); _cityRegion.setPriority(0);
_cityRegion.setFlag(DefaultFlag.PVP, StateFlag.State.DENY); _cityRegion.setFlag(DefaultFlag.PVP, StateFlag.State.DENY);
_cityRegion.setFlag(DefaultFlag.MOB_DAMAGE, StateFlag.State.DENY); _cityRegion.setFlag(DefaultFlag.MOB_DAMAGE, StateFlag.State.DENY);
@@ -210,7 +233,7 @@ public class MetropolisPlugin extends JavaPlugin {
_spawnRegion = regionManager.getRegion("Spawn"); _spawnRegion = regionManager.getRegion("Spawn");
if(_spawnRegion == null){ if(_spawnRegion == null){
_spawnRegion = new ProtectedCuboidRegion("Spawn", getPlotMin(0, 0), getPlotMax(0, 0)); _spawnRegion = new ProtectedCuboidRegion("Spawn", getPlotMin(0, 0, 1), getPlotMax(0, 0, 1));
_spawnRegion.setPriority(1); _spawnRegion.setPriority(1);
_spawnRegion.setFlag(DefaultFlag.PVP, StateFlag.State.DENY); _spawnRegion.setFlag(DefaultFlag.PVP, StateFlag.State.DENY);
_spawnRegion.setFlag(DefaultFlag.MOB_DAMAGE, StateFlag.State.DENY); _spawnRegion.setFlag(DefaultFlag.MOB_DAMAGE, StateFlag.State.DENY);
@@ -233,15 +256,20 @@ public class MetropolisPlugin extends JavaPlugin {
_spawnCuboid = new Cuboid(_spawnRegion.getMinimumPoint(), _spawnRegion.getMaximumPoint()); _spawnCuboid = new Cuboid(_spawnRegion.getMinimumPoint(), _spawnRegion.getMaximumPoint());
if(DEBUG){ if(DEBUG){
log.info("Metropolis: first 9 plots"); /*
log.info("Metropolis: first 25 plots");
for (int ix=-1; ix<=1;ix++){ int n = 5;
for (int iz=-1; iz<=1; iz++){
for (int ix=-n; ix<=n; ix++){
for (int iz=-n; iz<=n; iz++){
log.info(getCuboid(iz, ix).toString()); log.info(getCuboid(iz, ix).toString());
} }
} }
} */
log.info(String.format("roadWidth = %d", roadWidth));
}
_occupiedPlots = new ArrayList<Plot>(); _occupiedPlots = new ArrayList<Plot>();
fillOccupiedPlots(); fillOccupiedPlots();
@@ -253,12 +281,9 @@ public class MetropolisPlugin extends JavaPlugin {
log.info(String.format("%s enabled", pdf.getFullName())); log.info(String.format("%s enabled", pdf.getFullName()));
PluginCommand command = getCommand("metropolis-debug-generatetesthomes"); RegisterCommandHandler("metropolis", new MetropolisCommand(this));
if(command != null){
command.setExecutor(new MetropolisDebugGenerateTestHomesCommand(this)); RegisterCommandHandler("metropolis-debug-generatetesthomes", new MetropolisDebugGenerateTestHomesCommand(this));
}else{
throw new RuntimeException("The metropolis-debug-generatetesthomes command does not appear to exist");
}
RegisterCommandHandler("metropolis-flag-reset", new MetropolisFlagResetCommand(this)); RegisterCommandHandler("metropolis-flag-reset", new MetropolisFlagResetCommand(this));
@@ -272,9 +297,65 @@ public class MetropolisPlugin extends JavaPlugin {
RegisterCommandHandler("metropolis-plot-reserve", new MetropolisPlotReserveCommand(this)); RegisterCommandHandler("metropolis-plot-reserve", new MetropolisPlotReserveCommand(this));
} }
private void loadCurrentHomes() {
YAMLProcessor processor = new YAMLProcessor(new File(getDataFolder(), "currentHomes.yml"), true);
try {
processor.load();
} catch (IOException e) {
log.info(e.toString());
return;
}
Set<String> keys = processor.getMap().keySet();
_currentHomes.clear();
for(String username : keys){
_currentHomes.put(username, processor.getInt(username, 0));
}
}
private void buildUserOverrides() {
if(getConfig().isList("userOverrides")){
List<?> list = getConfig().getList("userOverrides");
for(Object o2 : list){
if(o2 instanceof HashMap<?, ?>){
HashMap<?, ?>map = (HashMap<?, ?>)o2;
String username = "";
if(map.containsKey("username")){
Object o3 = map.get("username");
if(o3 instanceof String){
username = (String)o3;
}
}
int plotMultiplier = _plotMultiplier;
if(map.containsKey("plotMultiplier")){
Object o3 = map.get("plotMultiplier");
if(o3 instanceof Integer){
plotMultiplier = (Integer)o3;
}
}
int maxPlots = _maxPlots;
if(map.containsKey("maxPlots")){
Object o3 = map.get("maxPlots");
if(o3 instanceof Integer){
maxPlots = (Integer)o3;
}
}
UserOverride override = new UserOverride(username, plotMultiplier, maxPlots);
_userOverrides.put(username, override);
}
}
}
}
private Cuboid getCuboid(int row, int col) { private Cuboid getCuboid(int row, int col) {
BlockVector min = getPlotMin(row, col); //This is only used for debug info
BlockVector max = getPlotMax(row, col); BlockVector min = getPlotMin(row, col, 1);
BlockVector max = getPlotMax(row, col, 1);
return new Cuboid(min, max); return new Cuboid(min, max);
} }
@@ -366,13 +447,19 @@ public class MetropolisPlugin extends JavaPlugin {
private void fillOccupiedPlots(){ private void fillOccupiedPlots(){
_occupiedPlots.clear(); _occupiedPlots.clear();
_ownedPlots.clear();
for(ProtectedRegion region: regionManager.getRegions().values()){ for(ProtectedRegion region: regionManager.getRegions().values()){
if(region instanceof ProtectedCuboidRegion){ if(region instanceof ProtectedCuboidRegion){
ProtectedCuboidRegion cuboidRegion = (ProtectedCuboidRegion) region; ProtectedCuboidRegion cuboidRegion = (ProtectedCuboidRegion) region;
if(cuboidRegion.getId().startsWith("h_")){ if(cuboidRegion.getId().startsWith("h_")){
PlayerHome home = PlayerHome.get(region); PlayerHome home = PlayerHome.get(region);
if(!_currentHomes.containsKey(home.getPlayerName()))
{
_currentHomes.put(home.getPlayerName(), home.getNumber());
}
_occupiedPlots.add(home); _occupiedPlots.add(home);
addOwnedPlot(home.getPlayerName(), home);
}else if(cuboidRegion.getId().startsWith("r_")){ }else if(cuboidRegion.getId().startsWith("r_")){
_occupiedPlots.add(Plot.get(cuboidRegion)); _occupiedPlots.add(Plot.get(cuboidRegion));
} }
@@ -382,6 +469,17 @@ public class MetropolisPlugin extends JavaPlugin {
size=calculateCitySize(); size=calculateCitySize();
} }
private void addOwnedPlot(String substring, Plot plot) {
if(_ownedPlots.containsKey(substring)){
List<Plot> plots = _ownedPlots.get(substring);
plots.add(plot);
}else{
List<Plot> plots = new ArrayList<Plot>();
plots.add(plot);
_ownedPlots.put(substring, plots);
}
}
@Override @Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
return super.onCommand(sender, command, label, args); return super.onCommand(sender, command, label, args);
@@ -412,7 +510,27 @@ public class MetropolisPlugin extends JavaPlugin {
for(x = plotCuboid.minX; x <= plotCuboid.maxX; x++){ for(x = plotCuboid.minX; x <= plotCuboid.maxX; x++){
for(z=plotCuboid.minZ; z<=plotCuboid.maxZ; z++){ for(z=plotCuboid.minZ; z<=plotCuboid.maxZ; z++){
setFloor(x, y, z);
clearSpaceAbove(x, y, z);
}
}
}
private void clearSpaceAbove(int x, int y, int z) {
Block block = null;
for(int i=0; i<spaceAboveFloor; i++){
block = world.getBlockAt(x, y+1+i, z);
block.setType(Material.AIR);
}
}
private void setFloor(int x, int y, int z) {
//if(DEBUG){log.info(String.format("setting road at (%d, %d, %d)", x, y, z));}
Block block = world.getBlockAt(x, y, z); Block block = world.getBlockAt(x, y, z);
//Set the floor block //Set the floor block
block.setType(floorMaterial); block.setType(floorMaterial);
@@ -423,13 +541,6 @@ public class MetropolisPlugin extends JavaPlugin {
blockUnder.setType(floorSupportMaterial); blockUnder.setType(floorSupportMaterial);
} }
} }
for(int i=0; i<spaceAboveFloor; i++){
block = world.getBlockAt(x, y+1+i, z);
block.setType(Material.AIR);
}
}
}
} }
private void createRoads(Cuboid plotCuboid, int roadMask){ private void createRoads(Cuboid plotCuboid, int roadMask){
@@ -527,6 +638,8 @@ public class MetropolisPlugin extends JavaPlugin {
} }
private void setRoad(int x, int y, int z) { private void setRoad(int x, int y, int z) {
//if(DEBUG){log.info(String.format("setting road at (%d, %d, %d)", x, y, z));}
Block block = world.getBlockAt(x, y, z); Block block = world.getBlockAt(x, y, z);
//Set the road block //Set the road block
block.setType(roadMaterial); block.setType(roadMaterial);
@@ -562,7 +675,7 @@ public class MetropolisPlugin extends JavaPlugin {
} }
public boolean isBlockOccupied(int row, int col){ public boolean isBlockOccupied(int row, int col){
Cuboid cuboid = new Cuboid(getGridMin(row, col), getGridMax(row, col)); Cuboid cuboid = new Cuboid(getGridMin(row, col, 1), getGridMax(row, col, 1));
for(Plot plot: _occupiedPlots){ for(Plot plot: _occupiedPlots){
if(plot.getCuboid().intersects(cuboid)){ if(plot.getCuboid().intersects(cuboid)){
return true; return true;
@@ -576,60 +689,74 @@ public class MetropolisPlugin extends JavaPlugin {
return false; return false;
} }
private Cuboid findNextUnownedHomeRegion() { private boolean areBlocksOccupied(int row, int col, int i) {
for(int ix = col; ix < col+i; ix++){
for(int iy = row; iy < row+i; iy++){
if(isBlockOccupied(iy, ix)){
return true;
}
}
}
return false;
}
private Cuboid findNextUnownedHomeRegion(int plotMultiplier) {
int row = 0; int row = 0;
int col = 0; int col = 0;
int ring = 0; int ring = 0;
int min = -ring;
int max = ring - (plotMultiplier-1);
boolean done = false; boolean done = false;
while(!done){ while(!done){
row = -ring; row = min;
col = -ring; col = min;
for(col = -ring; col <= ring; col++){ //Top
if(!isBlockOccupied(row, col)){ for(col = min; col <= max; col++){
if(row != 0 || col != 0){ if(!areBlocksOccupied(row, col, plotMultiplier)){
if(DEBUG){log.info(String.format("row: %d, col: %d", row, col));} if(DEBUG){log.info(String.format("row: %d, col: %d", row, col));}
return new Cuboid(getPlotMin(row, col), getPlotMax(row, col)); return new Cuboid(getPlotMin(row, col, plotMultiplier), getPlotMax(row, col, plotMultiplier));
}
} }
} }
col = ring; //Right side
for(row=-ring + 1; row < ring; row++){ col = max;
if(!isBlockOccupied(row, col)){ for(row=min + 1; row < max; row++){
if(row != 0 || col != 0){ if(!areBlocksOccupied(row, col, plotMultiplier)){
if(DEBUG){log.info(String.format("row: %d, col: %d", row, col));} if(DEBUG){log.info(String.format("row: %d, col: %d", row, col));}
return new Cuboid(getPlotMin(row, col), getPlotMax(row, col)); return new Cuboid(getPlotMin(row, col, plotMultiplier), getPlotMax(row, col, plotMultiplier));
}
} }
} }
row = ring; //Bottom
for(col = ring; col >= -ring; col--){ row = max;
if(!isBlockOccupied(row, col)){ for(col = max; col >= min; col--){
if(row != 0 || col != 0){ if(!areBlocksOccupied(row, col, plotMultiplier)){
if(DEBUG){log.info(String.format("row: %d, col: %d", row, col));} if(DEBUG){log.info(String.format("row: %d, col: %d", row, col));}
return new Cuboid(getPlotMin(row, col), getPlotMax(row, col)); return new Cuboid(getPlotMin(row, col, plotMultiplier), getPlotMax(row, col, plotMultiplier));
}
} }
} }
col = -ring; //Left
for(row = ring; row > -ring; row--){ col = min;
if(!isBlockOccupied(row, col)){ for(row = max; row > min; row--){
if(!areBlocksOccupied(row, col, plotMultiplier)){
if(row != 0 || col != 0){ if(row != 0 || col != 0){
if(DEBUG){log.info(String.format("row: %d, col: %d", row, col));} if(DEBUG){log.info(String.format("row: %d, col: %d", row, col));}
return new Cuboid(getPlotMin(row, col), getPlotMax(row, col)); return new Cuboid(getPlotMin(row, col, plotMultiplier), getPlotMax(row, col, plotMultiplier));
} }
} }
} }
ring++; ring++;
min = -ring;
max = ring - (plotMultiplier-1);
} }
if(DEBUG){log.info(String.format("row: %d, col: %d", row, col));} if(DEBUG){log.info(String.format("row: %d, col: %d", row, col));}
return new Cuboid(getPlotMin(row, col), getPlotMax(row, col)); return new Cuboid(getPlotMin(row, col, plotMultiplier), getPlotMax(row, col, plotMultiplier));
} }
private void resizeCityRegion() { private void resizeCityRegion() {
@@ -641,8 +768,8 @@ public class MetropolisPlugin extends JavaPlugin {
BlockVector min; BlockVector min;
BlockVector max; BlockVector max;
min = getPlotMin(-size/2, -size/2); min = getPlotMin(-size/2, -size/2, 1);
max = getPlotMax(size/2, size/2); max = getPlotMax(size/2, size/2, 1);
region.setMinimumPoint(min); region.setMinimumPoint(min);
region.setMaximumPoint(max); region.setMaximumPoint(max);
@@ -663,28 +790,36 @@ public class MetropolisPlugin extends JavaPlugin {
return iSize; return iSize;
} }
public BlockVector getPlotMin(int row, int col){ public BlockVector getPlotMin(int row, int col, int plotMultiplier){
BlockVector gridMin = getGridMin(row, col); BlockVector gridMin = getGridMin(row, col, plotMultiplier);
return new BlockVector(gridMin.getBlockX() + roadWidth/2, gridMin.getBlockY(), gridMin.getBlockZ() + roadWidth/2); BlockVector bv = new BlockVector(gridMin.getBlockX() + roadWidth/2, gridMin.getBlockY(), gridMin.getBlockZ() + roadWidth/2);
log.info(String.format("getPlotMin (%d, %d, %d)", bv.getBlockX(), bv.getBlockY(), bv.getBlockZ()));
return bv;
} }
public BlockVector getGridMin(int row, int col){ public BlockVector getPlotMax(int row, int col, int plotMultiplier){
BlockVector gridMax = getGridMax(row, col, plotMultiplier);
BlockVector bv = new BlockVector(gridMax.getBlockX() - (roadWidth - roadWidth/2), gridMax.getBlockY(), gridMax.getBlockZ() - (roadWidth-roadWidth/2));
log.info(String.format("getPlotMax (%d, %d, %d)", bv.getBlockX(), bv.getBlockY(), bv.getBlockZ()));
return bv;
}
public BlockVector getGridMin(int row, int col, int plotMultiplier){
int level = 0; int level = 0;
return new BlockVector(col * gridSizeX, level * gridSizeY, row * gridSizeZ); BlockVector bv = new BlockVector(col * gridSizeX, level * gridSizeY, row * gridSizeZ);
log.info(String.format("getGridMin (%d, %d, %d)", bv.getBlockX(), bv.getBlockY(), bv.getBlockZ()));
return bv;
} }
public BlockVector getPlotMax(int row, int col){ public BlockVector getGridMax(int row, int col, int plotMultiplier){
BlockVector gridMax = getGridMax(row, col);
return new BlockVector(gridMax.getBlockX() - (int)Math.ceil(roadWidth/2.0f), gridMax.getBlockY(), gridMax.getBlockZ()-(int)Math.ceil(roadWidth/2.0f));
}
public BlockVector getGridMax(int row, int col) {
int level = 0; int level = 0;
return new BlockVector((col+1) * gridSizeX - 1, (level+1) * gridSizeY - 1, (row+1) * gridSizeZ - 1); BlockVector bv = new BlockVector((col+plotMultiplier) * gridSizeX*plotMultiplier-1, (level+1/*plotMultiplier*/) * gridSizeY-1, (row+plotMultiplier) * gridSizeZ-1);
log.info(String.format("getGridMax (%d, %d, %d)", bv.getBlockX(), bv.getBlockY(), bv.getBlockZ()));
return bv;
} }
private int getPlotXFromMin(Cuboid cuboid) { private int getPlotXFromMin(Cuboid cuboid) {
@@ -704,38 +839,59 @@ public class MetropolisPlugin extends JavaPlugin {
} }
public PlayerHome generateHome(String playerName) { public PlayerHome generateHome(String playerName) {
int multiplier = getPlotMultiplier(playerName);
if(DEBUG){log.info(String.format("Generating home for %s", playerName));} if(DEBUG){log.info(String.format("Generating home for %s", playerName));}
Cuboid homeCuboid = null; Cuboid homeCuboid = null;
ProtectedRegion homeRegion = null; ProtectedRegion phomeRegion = null;
String regionName = "h_" + playerName; String regionName = "h_1_" + playerName;
homeRegion = regionManager.getRegion("h_" + playerName); phomeRegion = regionManager.getRegion(regionName);
if(homeRegion != null){ if(phomeRegion != null){
return PlayerHome.get(homeRegion); return PlayerHome.get(phomeRegion);
} }
homeCuboid = findNextUnownedHomeRegion(); homeCuboid = findNextUnownedHomeRegion(multiplier);
log.info("Metropolis Generating home in " + homeCuboid.toString());
homeRegion = new ProtectedCuboidRegion(regionName, homeCuboid.getMin(), homeCuboid.getMax());
homeRegion.setFlag(DefaultFlag.PVP, StateFlag.State.DENY);
homeRegion.setFlag(DefaultFlag.MOB_DAMAGE, StateFlag.State.DENY);
homeRegion.setFlag(DefaultFlag.MOB_SPAWNING, StateFlag.State.DENY);
homeRegion.setFlag(DefaultFlag.CREEPER_EXPLOSION, StateFlag.State.DENY);
homeRegion.setFlag(DefaultFlag.ENDER_BUILD, StateFlag.State.DENY);
homeRegion.setFlag(DefaultFlag.GHAST_FIREBALL, StateFlag.State.DENY);
homeRegion.setFlag(DefaultFlag.TNT, StateFlag.State.DENY);
DefaultDomain d = homeRegion.getOwners(); log.info("Metropolis Generating home in " + homeCuboid.toString());
ProtectedCuboidRegion newHomeRegion = new ProtectedCuboidRegion(regionName, homeCuboid.getMin(), homeCuboid.getMax());
newHomeRegion.setFlag(DefaultFlag.PVP, StateFlag.State.DENY);
newHomeRegion.setFlag(DefaultFlag.MOB_DAMAGE, StateFlag.State.DENY);
newHomeRegion.setFlag(DefaultFlag.MOB_SPAWNING, StateFlag.State.DENY);
newHomeRegion.setFlag(DefaultFlag.CREEPER_EXPLOSION, StateFlag.State.DENY);
newHomeRegion.setFlag(DefaultFlag.ENDER_BUILD, StateFlag.State.DENY);
newHomeRegion.setFlag(DefaultFlag.GHAST_FIREBALL, StateFlag.State.DENY);
newHomeRegion.setFlag(DefaultFlag.TNT, StateFlag.State.DENY);
DefaultDomain d = newHomeRegion.getOwners();
d.addPlayer(playerName); d.addPlayer(playerName);
homeRegion.setPriority(1); newHomeRegion.setPriority(1);
regionManager.addRegion(homeRegion);
regionManager.addRegion(newHomeRegion);
try { try {
regionManager.save(); regionManager.save();
} catch (ProtectionDatabaseException e) { } catch (Exception e) {
log.info("Metropolis: ERROR Problem saving region"); log.info("Metropolis: ERROR Problem saving region");
e.printStackTrace(); e.printStackTrace();
} }
setHomeOccupied(playerName, homeRegion.getMinimumPoint(), homeRegion.getMaximumPoint()); try {
regionManager.save();
} catch (Exception e) {
log.info("Metropolis: ERROR Problem saving region");
e.printStackTrace();
}
log.info(String.format(
"New home region (%d, %d, %d) (%d, %d, %d)",
newHomeRegion.getMinimumPoint().getBlockX(),
newHomeRegion.getMinimumPoint().getBlockY(),
newHomeRegion.getMinimumPoint().getBlockZ(),
newHomeRegion.getMaximumPoint().getBlockX(),
newHomeRegion.getMaximumPoint().getBlockY(),
newHomeRegion.getMaximumPoint().getBlockZ()
));
setHomeOccupied(playerName, newHomeRegion.getMinimumPoint(), newHomeRegion.getMaximumPoint());
createRoads(homeCuboid); createRoads(homeCuboid);
@@ -750,7 +906,7 @@ public class MetropolisPlugin extends JavaPlugin {
if(DEBUG){log.info(String.format("Done generating home for %s", playerName));} if(DEBUG){log.info(String.format("Done generating home for %s", playerName));}
return new PlayerHome(homeRegion); return new PlayerHome(newHomeRegion);
} }
private void generateSign(Cuboid plotCuboid, String playerName) { private void generateSign(Cuboid plotCuboid, String playerName) {
@@ -809,39 +965,124 @@ public class MetropolisPlugin extends JavaPlugin {
return wallHeight; return wallHeight;
} }
public int getMaxPlots(String name) { public ProtectedRegion getRegion(String regionName) {
Player player = null; if(regionManager == null){
// TODO Auto-generated method stub return null;
return 0; }
return regionManager.getRegion(regionName);
}
public void removeRegion(String regionId) {
if(regionManager == null){
return;
}
try{
regionManager.removeRegion(regionId);
}catch(Exception ex){
log.info(String.format("[ERROR] Metropolis: Unable to remove region {%s}.", regionId));
return;
}
}
public void saveRegions() {
try {
regionManager.save();
} catch (Exception ex) {
log.info(String.format("[SEVERE] Metropolis: Unable to save WorldGuard regions."));
return;
}
} }
public int getNumPlots(String name) { public int getNumPlots(String name) {
// TODO Auto-generated method stub if(_ownedPlots.containsKey(name)){
return 1; List<Plot> plots = _ownedPlots.get(name);
if(plots == null){
return 0;
}else{
return plots.size();
}
}else{
return 0;
}
} }
public void assignPlot(Player player) { public int getMaxPlots(String name) {
// TODO Auto-generated method stub if(_userOverrides.containsKey(name)){
return _userOverrides.get(name).getMaxPlots();
}else{
return _maxPlots;
}
} }
public String setCurrentHome(Player player, int homeNumber) { public void assignPlot(OfflinePlayer player) {
// TODO Auto-generated method stub //PlayerHome home = generateHome(player.getName());
return null; generateHome(player.getName());
}
private int getPlotMultiplier(String name) {
if(_userOverrides.containsKey(name)){
return _userOverrides.get(name).getPlotMultiplier();
}else{
return _plotMultiplier;
}
} }
public Plot getPlot(String string) { public Plot getPlot(String string) {
// TODO Auto-generated method stub /**
* string is the name of the region to get a plot for
*
* loop through all regions and find one with the specified name return null if there is none
*/
for(Plot plot : _occupiedPlots){
if(plot.getRegionName().equals(string)){
return plot;
}
}
return null; return null;
} }
public Player getPlayer(String string) { public Player getPlayer(String name) {
// TODO Auto-generated method stub return getServer().getPlayer(name);
return null; }
public OfflinePlayer getOfflinePlayer(String name){
return getServer().getOfflinePlayer(name);
} }
public String teleportPlayerToPlot(Player player, Plot plot) { public String teleportPlayerToPlot(Player player, Plot plot) {
// TODO Auto-generated method stub Location loc = plot.getViableSpawnLocation(world);
if(loc != null){
player.teleport(loc);
}
return null; return null;
} }
public boolean homeExists(String playerName, int homeNumber) {
for(Plot plot: _occupiedPlots){
if(plot.getRegionName().equalsIgnoreCase(String.format("h_%d_%s", homeNumber, playerName))){
return true;
}
}
return false;
}
public void setHome(String name, int newHomeNumber) {
_currentHomes.put(name, newHomeNumber);
saveCurrentHomes();
}
private void saveCurrentHomes() {
File outFile = new File(getDataFolder(), "currentHomes.yml");
// TODO Auto-generated method stub
//YAMLProcessor processor = new YAMLProcessor(new File(getDataFolder(), "currentHomes.yml"), true);
//processor.save();
}
} }

View File

@@ -6,7 +6,6 @@ import javax.persistence.Table;
import com.avaje.ebean.validation.NotNull; import com.avaje.ebean.validation.NotNull;
import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion; import com.sk89q.worldguard.protection.regions.ProtectedRegion;
@Entity() @Entity()
@@ -17,6 +16,8 @@ public class PlayerHome extends Plot{
public String getPlayerName(){return this.playerName;} public String getPlayerName(){return this.playerName;}
public void setPlayerName(String playerName){this.playerName = playerName;} public void setPlayerName(String playerName){this.playerName = playerName;}
private int number;
public PlayerHome(String owner, BlockVector min, BlockVector max) { public PlayerHome(String owner, BlockVector min, BlockVector max) {
super("h_" + owner, min, max); super("h_" + owner, min, max);
this.playerName = owner; this.playerName = owner;
@@ -27,24 +28,30 @@ public class PlayerHome extends Plot{
} }
public PlayerHome(ProtectedRegion homeRegion){ public PlayerHome(ProtectedRegion homeRegion){
if(homeRegion instanceof ProtectedCuboidRegion){ try{
ProtectedCuboidRegion cuboidRegion = (ProtectedCuboidRegion) homeRegion; String rname = homeRegion.getId();
if(cuboidRegion.getId().startsWith("h_") && cuboidRegion.getId().length() > 2){
this.playerName = cuboidRegion.getId().substring(2); if(rname.startsWith("h_")){
int secondUnderscore = rname.indexOf('_', 2);
if(secondUnderscore > 2){
try{
this.number = Integer.parseInt(rname.substring(2, secondUnderscore));
this.playerName = rname.substring(secondUnderscore+1);
}catch(Exception ex){
this.number = 0;
}
}else{ }else{
this.playerName = cuboidRegion.getId(); this.number = 0;
this.playerName = rname.substring(2);
} }
setCuboid(new Cuboid(cuboidRegion.getMinimumPoint(), cuboidRegion.getMaximumPoint())); setCuboid(new Cuboid(homeRegion.getMinimumPoint(), homeRegion.getMaximumPoint()));
}else if(homeRegion instanceof ProtectedPolygonalRegion){
ProtectedPolygonalRegion polygonalRegion = (ProtectedPolygonalRegion)homeRegion;
if(polygonalRegion.getId().startsWith("h_") && polygonalRegion.getId().length() > 2){
this.playerName = polygonalRegion.getId().substring(2);
}else{
this.playerName = polygonalRegion.getId();
} }
else{
setCuboid(new Cuboid(polygonalRegion.getMinimumPoint(), polygonalRegion.getMaximumPoint())); throw new RuntimeException("Method not implemented.");
}
}catch(Exception ex){
throw new RuntimeException("Method not implemented.", ex);
} }
} }
@@ -82,4 +89,12 @@ public class PlayerHome extends Plot{
return null; return null;
} }
} }
public Integer getNumber() {
return number;
}
public void setNumber(int number){
this.number = number;
}
} }

View File

@@ -0,0 +1,17 @@
package com.majinnaibu.bukkitplugins.metropolis;
public class UserOverride {
private String _username;
private int _plotMultiplier;
private int _maxPlots;
public String getUsername(){return _username;}
public int getPlotMultiplier(){return _plotMultiplier;}
public int getMaxPlots(){return _maxPlots;}
public UserOverride(String username, int plotMultiplier, int maxPlots){
_username = username;
_plotMultiplier = plotMultiplier;
_maxPlots = maxPlots;
}
}

View File

@@ -6,18 +6,19 @@ import org.bukkit.command.CommandSender;
import com.majinnaibu.bukkitplugins.metropolis.MetropolisPlugin; import com.majinnaibu.bukkitplugins.metropolis.MetropolisPlugin;
public class MetropolisHomeEvictCommand implements CommandExecutor { public class MetropolisCommand implements CommandExecutor {
MetropolisPlugin _plugin = null; private MetropolisPlugin _plugin;
public MetropolisHomeEvictCommand(MetropolisPlugin plugin){ public MetropolisCommand(MetropolisPlugin plugin){
_plugin = plugin; _plugin = plugin;
} }
@Override @Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
// TODO Auto-generated method stub sender.sendMessage("Metropolis: version "+ _plugin.pdf.getVersion());
return false;
return true;
} }
} }

View File

@@ -0,0 +1,60 @@
package com.majinnaibu.bukkitplugins.metropolis.commands;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import com.majinnaibu.bukkitplugins.metropolis.MetropolisPlugin;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
public class MetropolisHomeEvictCommand implements CommandExecutor {
MetropolisPlugin _plugin = null;
public MetropolisHomeEvictCommand(MetropolisPlugin plugin){
_plugin = plugin;
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
//get the player and region
String playerName = "";
if(args.length == 0){
return false;
}
if(args.length >= 1){
playerName = args[0];
}
OfflinePlayer player = _plugin.getServer().getOfflinePlayer(playerName);
if(player == null){
sender.sendMessage(String.format("The requested player {%s}does not appear to exist.", playerName));
return false;
}
ProtectedRegion region = _plugin.getRegion(String.format("h_%s", player.getName()));
if(region == null){
sender.sendMessage(String.format("The player {%s} has no home to be evicted from."));
return false;
}
//remove the player as owner and/or member of the region
region.getMembers().removePlayer(playerName);
region.getOwners().removePlayer(playerName);
//if the region has no owners delete the region
if(region.getMembers().size() == 0 && region.getOwners().size() == 0){
_plugin.removeRegion(region.getId());
}
_plugin.saveRegions();
//?optionally regen the region
//_plugin.worldEdit.getCommand("regen").execute(_plugin.getServer().getConsoleSender(), "regen", new String[]{});
return true;
}
}

View File

@@ -1,9 +1,9 @@
package com.majinnaibu.bukkitplugins.metropolis.commands; package com.majinnaibu.bukkitplugins.metropolis.commands;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.majinnaibu.bukkitplugins.metropolis.MetropolisPlugin; import com.majinnaibu.bukkitplugins.metropolis.MetropolisPlugin;
@@ -16,40 +16,38 @@ public class MetropolisHomeMoveCommand implements CommandExecutor {
@Override @Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
Player player = null; OfflinePlayer player = null;
int homeNumber = 0; int newHomeNumber = 0;
if(sender instanceof Player){ if(sender instanceof OfflinePlayer){
player = (Player) sender; player = (OfflinePlayer)sender;
} }
if(args.length == 1){
if(args.length == 1 && player != null){
try{ try{
homeNumber = Integer.parseInt(args[0]); newHomeNumber = Integer.parseInt(args[0]);
}catch(NumberFormatException ex){ }catch(NumberFormatException ex){
return false; return false;
} }
}else if(args.length >= 2){ }else if(args.length >= 2){
try{ try{
homeNumber = Integer.parseInt(args[0]); newHomeNumber = Integer.parseInt(args[0]);
}catch(NumberFormatException ex){ }catch(NumberFormatException ex){
return false; return false;
} }
player = _plugin.getOfflinePlayer(args[1]);
}else{ }else{
return false; return false;
} }
if(homeNumber <= 0){ if(player == null || !_plugin.homeExists(player.getName(), newHomeNumber)){
return false; return false;
} }
String errorMessage = _plugin.setCurrentHome(player, homeNumber); _plugin.setHome(player.getName(), newHomeNumber);
if(errorMessage != null){
sender.sendMessage(errorMessage);
return false;
}
return true; return true;
} }
} }

View File

@@ -1,6 +1,6 @@
plot: plot:
sizeX: 24 sizeX: 32 sizeY: 256
sizeZ: 24 sizeZ: 32 offsetX: 0 offsetY: 0 offsetZ: 0 multiplier: 1 maxPerPlayer: 1 initial: 1
floor: floor:
generate: true generate: true
clearSpaceAbove: 66 clearSpaceAbove: 66
@@ -9,8 +9,7 @@ plot:
generate: true generate: true
material: 1 material: 1
sign: sign:
generate: true generate: true road:
road:
width: 4 width: 4
clearSpaceAbove: 66 clearSpaceAbove: 66
level: 62 level: 62
@@ -27,3 +26,10 @@ wall:
material: 7 material: 7
height: 66 height: 66
worldname: world worldname: world
userOverrides:
- username: majinnaibu
plotMultiplier: 2
maxPlots: 2
- username: hoggrim
plotMultiplier: 2
maxPlots: 2

View File

@@ -4,4 +4,7 @@ depend: [WorldGuard]
softdepend: [WorldEdit,CommandBook] softdepend: [WorldEdit,CommandBook]
version: 0.5 version: 0.5
database: false database: false
commands: metropolis-home-acquire: description: This command allocates a home. permission: metropolis.home.acquire usage: /metropolis-home-acquire metropolis-home-generate: description: This command generates a home for a user as if they'd just logged in. permission: metropolis.home.generate usage: /metropolis-home-generate <playername> metropolis-home-list: description: This lists the regions managed by Metropolis permission: metropolis.home.list usage: /metropolis-home-list metropolis-home-evict: description: This unassigns a player's current home. permission: metropolis.home.evict usage: /metropolis-home-evict <playerName> metropolis-home-move: description: This command swaps a player's current home with a reserved plot. permission: metropolis.home.move usage: /metropolis-home-move <newRegionName> metropolis-home-go: description: Teleports the user or another player to his home. permission: metropolis.home.go usage: /metropolis-home-go metropolis-flag-reset: description: This command resets the WorldGuard flags for all managed regions (city and h_*). permission: metropolis.flag.reset usage: /metropolis-flag-reset metropolis-plot-reserve: description: This command reserves a plot so it won't be assigned as a home. permission: metropolis.plot.reserve usage: /metropolis-plot-reserve <name> <minX> <minY> <minZ> <maxX> <maxY> <maxZ> metropolis-plot-go: description: This command teleports the user or another player to a plot. permission: metropolis.plot.go usage: /metropolis-plot-go <plotName> [playerName] metropolis-debug-generatetesthomes: description: This command is ignored on non-debug builds. permission: metropolis.debug usage: /metropolis-debug-gentesthomes commands:
metropolis:
description: This command displays the current metropolis version.
usage: /metropolis metropolis-home-generate: description: This command generates a home for a user as if they'd just logged in. permission: metropolis.home.generate usage: /metropolis-home-generate <playername> metropolis-home-list: description: This lists the regions managed by Metropolis permission: metropolis.home.list usage: /metropolis-home-list metropolis-home-evict: description: This unassigns a player's current home. permission: metropolis.home.evict usage: /metropolis-home-evict <playerName> metropolis-home-move: description: This command swaps a player's current home with a reserved plot. permission: metropolis.home.move usage: /metropolis-home-move <newHomeNumber> [player] metropolis-home-go: description: Teleports the user or another player to his home. permission: metropolis.home.go usage: /metropolis-home-go metropolis-flag-reset: description: This command resets the WorldGuard flags for all managed regions (city and h_*). permission: metropolis.flag.reset usage: /metropolis-flag-reset metropolis-plot-reserve: description: This command reserves a plot so it won't be assigned as a home. permission: metropolis.plot.reserve usage: /metropolis-plot-reserve <name> <minX> <minY> <minZ> <maxX> <maxY> <maxZ> metropolis-plot-go: description: This command teleports the user or another player to a plot. permission: metropolis.plot.go usage: /metropolis-plot-go <plotName> [playerName] metropolis-debug-generatetesthomes: description: This command is ignored on non-debug builds. permission: metropolis.debug usage: /metropolis-debug-gentesthomes