package com.intellectualcrafters.plot.commands;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.object.Expression;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.util.ByteArrayUtilities;
import com.intellectualcrafters.plot.util.EconHandler;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.TaskManager;
import com.plotsquared.general.commands.CommandDeclaration;
import java.util.Set;
@CommandDeclaration(command = "auto",
permission = "plots.auto",
category = CommandCategory.CLAIMING,
requiredType = RequiredType.NONE,
description = "Claim the nearest plot",
aliases = "a",
usage = "/plot auto [length,width]")
public class Auto extends SubCommand {
@Deprecated
public static PlotId getNextPlotId(PlotId id, int step) {
return id.getNextId(step);
}
@Override
public boolean onCommand(final PlotPlayer player, String[] args) {
PlotArea plotarea = player.getApplicablePlotArea();
if (plotarea == null) {
if (EconHandler.manager != null) {
for (PlotArea area : PS.get().getPlotAreaManager().getAllPlotAreas()) {
if (EconHandler.manager.hasPermission(area.worldname, player.getName(), "plots.auto")) {
if (plotarea != null) {
plotarea = null;
break;
}
plotarea = area;
}
}
}
if (plotarea == null) {
MainUtil.sendMessage(player, C.NOT_IN_PLOT_WORLD);
return false;
}
}
int size_x = 1;
int size_z = 1;
String schematic = null;
if (args.length > 0) {
if (Permissions.hasPermission(player, C.PERMISSION_AUTO_MEGA)) {
try {
String[] split = args[0].split(",|;");
size_x = Integer.parseInt(split[0]);
size_z = Integer.parseInt(split[1]);
if (size_x < 1 || size_z < 1) {
MainUtil.sendMessage(player, "&cError: size<=0");
}
if (args.length > 1) {
schematic = args[1];
}
} catch (NumberFormatException ignored) {
size_x = 1;
size_z = 1;
schematic = args[0];
// PlayerFunctions.sendMessage(plr,
// "&cError: Invalid size (X,Y)");
// return false;
}
} else {
schematic = args[0];
// PlayerFunctions.sendMessage(plr, C.NO_PERMISSION);
// return false;
}
}
if (size_x * size_z > Settings.Claim.MAX_AUTO_AREA) {
MainUtil.sendMessage(player, C.CANT_CLAIM_MORE_PLOTS_NUM, Settings.Claim.MAX_AUTO_AREA + "");
return false;
}
int currentPlots = Settings.Limit.GLOBAL ? player.getPlotCount() : player.getPlotCount(plotarea.worldname);
int diff = currentPlots - player.getAllowedPlots();
if (diff + size_x * size_z > 0) {
if (diff < 0) {
MainUtil.sendMessage(player, C.CANT_CLAIM_MORE_PLOTS_NUM, -diff + "");
return false;
} else if (player.hasPersistentMeta("grantedPlots")) {
int grantedPlots = ByteArrayUtilities.bytesToInteger(player.getPersistentMeta("grantedPlots"));
if (grantedPlots - diff < size_x * size_z) {
player.removePersistentMeta("grantedPlots");
return sendMessage(player, C.CANT_CLAIM_MORE_PLOTS);
} else {
int left = grantedPlots - diff - size_x * size_z;
if (left == 0) {
player.removePersistentMeta("grantedPlots");
} else {
player.setPersistentMeta("grantedPlots", ByteArrayUtilities.integerToBytes(left));
}
sendMessage(player, C.REMOVED_GRANTED_PLOT, "" + left, "" + (grantedPlots - left));
}
} else {
MainUtil.sendMessage(player, C.CANT_CLAIM_MORE_PLOTS);
return false;
}
}
if (schematic != null && !schematic.isEmpty()) {
if (!plotarea.SCHEMATICS.contains(schematic.toLowerCase())) {
sendMessage(player, C.SCHEMATIC_INVALID, "non-existent: " + schematic);
return true;
}
if (!Permissions.hasPermission(player, C.PERMISSION_CLAIM_SCHEMATIC.f(schematic)) && !Permissions.hasPermission(player, C.PERMISSION_ADMIN_COMMAND_SCHEMATIC)) {
MainUtil.sendMessage(player, C.NO_PERMISSION, C.PERMISSION_CLAIM_SCHEMATIC.f(schematic));
return true;
}
}
if (EconHandler.manager != null && plotarea.USE_ECONOMY) {
Expression<Double> costExp = plotarea.PRICES.get("claim");
double cost = costExp.evaluate((double) currentPlots);
cost = (size_x * size_z) * cost;
if (cost > 0d) {
if (EconHandler.manager.getMoney(player) < cost) {
sendMessage(player, C.CANNOT_AFFORD_PLOT, "" + cost);
return true;
}
EconHandler.manager.withdrawMoney(player, cost);
sendMessage(player, C.REMOVED_BALANCE, cost + "");
}
}
// TODO handle type 2 the same as normal worlds!
if (size_x == 1 && size_z == 1) {
autoClaimSafe(player, plotarea, null, schematic);
return true;
} else {
if (plotarea.TYPE == 2) {
// TODO
MainUtil.sendMessage(player, C.NO_FREE_PLOTS);
return false;
}
while (true) {
PlotId start = plotarea.getMeta("lastPlot", new PlotId(0, 0)).getNextId(1);
PlotId end = new PlotId(start.x + size_x - 1, start.y + size_z - 1);
if (plotarea.canClaim(player, start, end)) {
plotarea.setMeta("lastPlot", start);
for (int i = start.x; i <= end.x; i++) {
for (int j = start.y; j <= end.y; j++) {
Plot plot = plotarea.getPlotAbs(new PlotId(i, j));
boolean teleport = i == end.x && j == end.y;
plot.claim(player, teleport, null);
}
}
if (!plotarea.mergePlots(MainUtil.getPlotSelectionIds(start, end), true, true)) {
return false;
}
break;
}
}
return true;
}
}
/**
* Get the next plot id (spiral out from 0,0)
* @param start
* @return
*/
@Deprecated
public static PlotId getNextPlot(PlotId start) {
int plots;
PlotId center;
center = new PlotId(0, 0);
plots = Integer.MAX_VALUE;
PlotId currentId;
for (int i = 0; i < plots; i++) {
if (start == null) {
start = new PlotId(0, 0);
} else {
start = start.getNextId(1);
}
currentId = new PlotId(center.x + start.x, center.y + start.y);
return currentId;
}
return null;
}
/**
* Teleport the player home, or claim a new plot
* @param player
* @param area
* @param start
* @param schem
*/
public static void homeOrAuto(final PlotPlayer player, final PlotArea area, PlotId start, final String schem) {
Set<Plot> plots = player.getPlots();
if (!plots.isEmpty()) {
plots.iterator().next().teleportPlayer(player);
} else {
autoClaimSafe(player, area, start, schem);
}
}
/**
* Claim a new plot for a player
* @param player
* @param area
* @param start
* @param schem
*/
public static void autoClaimSafe(final PlotPlayer player, final PlotArea area, PlotId start, final String schem) {
autoClaimFromDatabase(player, area, start, new RunnableVal<Plot>() {
@Override
public void run(final Plot plot) {
TaskManager.IMP.sync(new RunnableVal<Object>() {
@Override
public void run(Object ignore) {
if (plot == null) {
MainUtil.sendMessage(player, C.NO_FREE_PLOTS);
} else {
plot.claim(player, true, schem, false);
}
}
});
}
});
}
private static void autoClaimFromDatabase(final PlotPlayer player, final PlotArea area, PlotId start, final RunnableVal<Plot> whenDone) {
final Plot plot = area.getNextFreePlot(player, start);
if (plot == null) {
whenDone.run(null);
return;
}
whenDone.value = plot;
plot.owner = player.getUUID();
DBFunc.createPlotSafe(plot, whenDone, new Runnable() {
@Override
public void run() {
autoClaimFromDatabase(player, area, plot.getId(), whenDone);
}
});
}
}