diff --git a/BedWars.iml b/BedWars.iml index 1fd1d00..f570be0 100644 --- a/BedWars.iml +++ b/BedWars.iml @@ -33,5 +33,13 @@ + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 4273aeb..e266c31 100644 --- a/pom.xml +++ b/pom.xml @@ -61,6 +61,14 @@ sonatype https://oss.sonatype.org/content/groups/public/ + + fawe-repo + https://ci.athion.net/job/FastAsyncWorldEdit/ws/mvn/ + + + placeholderapi + https://repo.extendedclip.com/content/repositories/placeholderapi/ + @@ -98,5 +106,29 @@ provided + + + com.sk89q + worldedit + 6.0.0-SNAPSHOT + provided + + + + + com.boydti + fawe-api + latest + provided + + + + + me.clip + placeholderapi + 2.10.9 + provided + + diff --git a/src/main/java/rip/tilly/bedwars/commands/arena/ArenaCommand.java b/src/main/java/rip/tilly/bedwars/commands/arena/ArenaCommand.java new file mode 100644 index 0000000..d9b469d --- /dev/null +++ b/src/main/java/rip/tilly/bedwars/commands/arena/ArenaCommand.java @@ -0,0 +1,49 @@ +package rip.tilly.bedwars.commands.arena; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import rip.tilly.bedwars.BedWars; +import rip.tilly.bedwars.utils.CC; + +public class ArenaCommand implements CommandExecutor { + + private BedWars plugin = BedWars.getInstance(); + + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + Player player = (Player) sender; + + if (!player.hasPermission("bedwars.admin")) { + player.sendMessage(CC.translate("&cNo permission")); + + return true; + } + + if (args.length == 0) { + player.sendMessage(CC.translate("&cUsage:")); + player.sendMessage(CC.translate(" &c/arena")); + player.sendMessage(CC.translate(" &c/arena manage (Opens arena manage menu)")); + player.sendMessage(CC.translate(" &c/arena create ")); + player.sendMessage(CC.translate(" &c/arena icon ")); + player.sendMessage(CC.translate(" &c/arena enable ")); + player.sendMessage(CC.translate(" &c/arena disable ")); + player.sendMessage(CC.translate(" &c/arena a ")); + player.sendMessage(CC.translate(" &c/arena b ")); + player.sendMessage(CC.translate(" &c/arena min ")); + player.sendMessage(CC.translate(" &c/arena max ")); + player.sendMessage(CC.translate(" &c/arena teamAmin ")); + player.sendMessage(CC.translate(" &c/arena teamAmax ")); + player.sendMessage(CC.translate(" &c/arena teamBmin ")); + player.sendMessage(CC.translate(" &c/arena teamBmax ")); + player.sendMessage(CC.translate(" &c/arena deadzone ")); + player.sendMessage(CC.translate(" &c/arena buildmax ")); + } else { + switch (args[0].toLowerCase()) { + + } + } + + return true; + } +} diff --git a/src/main/java/rip/tilly/bedwars/managers/CommandManager.java b/src/main/java/rip/tilly/bedwars/managers/CommandManager.java index c6313c5..074b984 100644 --- a/src/main/java/rip/tilly/bedwars/managers/CommandManager.java +++ b/src/main/java/rip/tilly/bedwars/managers/CommandManager.java @@ -1,6 +1,7 @@ package rip.tilly.bedwars.managers; import rip.tilly.bedwars.BedWars; +import rip.tilly.bedwars.commands.arena.ArenaCommand; import rip.tilly.bedwars.commands.level.LevelCommand; import rip.tilly.bedwars.commands.party.PartyCommand; import rip.tilly.bedwars.commands.setspawn.SetSpawnCommand; @@ -19,5 +20,6 @@ public class CommandManager { this.main.getCommand("level").setExecutor(new LevelCommand()); this.main.getCommand("xp").setExecutor(new XpCommand()); this.main.getCommand("party").setExecutor(new PartyCommand()); + this.main.getCommand("arena").setExecutor(new ArenaCommand()); } } diff --git a/src/main/java/rip/tilly/bedwars/runnables/ArenaCommandRunnable.java b/src/main/java/rip/tilly/bedwars/runnables/ArenaCommandRunnable.java new file mode 100644 index 0000000..7cddb15 --- /dev/null +++ b/src/main/java/rip/tilly/bedwars/runnables/ArenaCommandRunnable.java @@ -0,0 +1,89 @@ +package rip.tilly.bedwars.runnables; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import rip.tilly.bedwars.BedWars; +import rip.tilly.bedwars.game.arena.Arena; +import rip.tilly.bedwars.game.arena.CopiedArena; +import rip.tilly.bedwars.utils.CustomLocation; + +@Getter +@AllArgsConstructor +public class ArenaCommandRunnable implements Runnable { + + private final BedWars plugin; + private final Arena copiedArena; + + private int times; + + @Override + public void run() { + this.duplicateArena(this.copiedArena, 10000, 10000); + } + + private void duplicateArena(Arena arena, int offsetX, int offsetZ) { + new DuplicateArenaRunnable(this.plugin, arena, offsetX, offsetZ, 500, 500) { + @Override + public void onComplete() { + double minX = arena.getMin().getX() + this.getOffsetX(); + double minZ = arena.getMin().getZ() + this.getOffsetZ(); + double maxX = arena.getMax().getX() + this.getOffsetX(); + double maxZ = arena.getMax().getZ() + this.getOffsetZ(); + + double aX = arena.getA().getX() + this.getOffsetX(); + double aZ = arena.getA().getZ() + this.getOffsetZ(); + double bX = arena.getB().getX() + this.getOffsetX(); + double bZ = arena.getB().getZ() + this.getOffsetZ(); + + CustomLocation min = new CustomLocation(minX, arena.getMin().getY(), minZ, arena.getMin().getYaw(), arena.getMin().getPitch()); + CustomLocation max = new CustomLocation(maxX, arena.getMax().getY(), maxZ, arena.getMax().getYaw(), arena.getMax().getPitch()); + CustomLocation a = new CustomLocation(aX, arena.getA().getY(), aZ, arena.getA().getYaw(), arena.getA().getPitch()); + CustomLocation b = new CustomLocation(bX, arena.getB().getY(), bZ, arena.getB().getYaw(), arena.getB().getPitch()); + + double aMinX = arena.getTeamAmin().getX() + this.getOffsetX(); + double aMinZ = arena.getTeamAmin().getZ() + this.getOffsetZ(); + double aMaxX = arena.getTeamAmax().getX() + this.getOffsetX(); + double aMaxZ = arena.getTeamAmax().getZ() + this.getOffsetZ(); + + double bMinX = arena.getTeamBmin().getX() + this.getOffsetX(); + double bMinZ = arena.getTeamBmin().getZ() + this.getOffsetZ(); + double bMaxX = arena.getTeamBmax().getX() + this.getOffsetX(); + double bMaxZ = arena.getTeamBmax().getZ() + this.getOffsetZ(); + + CustomLocation teamAmin = new CustomLocation(aMinX, arena.getTeamAmin().getY(), aMinZ, arena.getTeamAmin().getYaw(), arena.getTeamAmin().getPitch()); + CustomLocation teamAmax = new CustomLocation(aMaxX, arena.getTeamAmax().getY(), aMaxZ, arena.getTeamAmax().getYaw(), arena.getTeamAmax().getPitch()); + CustomLocation teamBmin = new CustomLocation(bMinX, arena.getTeamBmin().getY(), bMinZ, arena.getTeamBmin().getYaw(), arena.getTeamBmin().getPitch()); + CustomLocation teamBmax = new CustomLocation(bMaxX, arena.getTeamBmax().getY(), bMaxZ, arena.getTeamBmax().getYaw(), arena.getTeamBmax().getPitch()); + + CopiedArena copiedArena = new CopiedArena(a, b, min, max, teamAmin, teamAmax, teamBmin, teamBmax); + + arena.addCopiedArena(copiedArena); + arena.addAvailableArena(copiedArena); + + String arenaPasteMessage = "[Copied Arena] - " + arena.getName() + " placed at " + (int) minX + ", " + (int) minZ + ". " + ArenaCommandRunnable.this.times + " copies remaining."; + + if (--ArenaCommandRunnable.this.times > 0) { + ArenaCommandRunnable.this.plugin.getServer().getLogger().info(arenaPasteMessage); + for (Player player : Bukkit.getOnlinePlayers()) { + if (player.isOp()) { + player.sendMessage(ChatColor.GREEN + arenaPasteMessage); + } + } + ArenaCommandRunnable.this.duplicateArena(arena, (int) Math.round(maxX), (int) Math.round(maxZ)); + } else { + for (Player player : Bukkit.getOnlinePlayers()) { + if (player.isOp()) { + player.sendMessage(ChatColor.GREEN + "All the copies for " + ArenaCommandRunnable.this.copiedArena.getName() + " have been pasted successfully!"); + } + } + ArenaCommandRunnable.this.plugin.getServer().getLogger().info("All the copies for " + ArenaCommandRunnable.this.copiedArena.getName() + " have been pasted successfully!"); + ArenaCommandRunnable.this.plugin.getArenaManager().setGeneratingArenaRunnable(ArenaCommandRunnable.this.plugin.getArenaManager().getGeneratingArenaRunnable() - 1); + this.getPlugin().getArenaManager().reloadArenas(); + } + } + }.run(); + } +} \ No newline at end of file diff --git a/src/main/java/rip/tilly/bedwars/runnables/ArenaCopyRemovalRunnable.java b/src/main/java/rip/tilly/bedwars/runnables/ArenaCopyRemovalRunnable.java new file mode 100644 index 0000000..20aafeb --- /dev/null +++ b/src/main/java/rip/tilly/bedwars/runnables/ArenaCopyRemovalRunnable.java @@ -0,0 +1,54 @@ +package rip.tilly.bedwars.runnables; + +import com.boydti.fawe.util.EditSessionBuilder; +import com.boydti.fawe.util.TaskManager; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BlockID; +import com.sk89q.worldedit.regions.CuboidRegion; +import org.bukkit.scheduler.BukkitRunnable; +import rip.tilly.bedwars.BedWars; +import rip.tilly.bedwars.game.arena.Arena; +import rip.tilly.bedwars.game.arena.CopiedArena; + +public class ArenaCopyRemovalRunnable extends BukkitRunnable { + + private final int number; + private final Arena arena; + private final CopiedArena arenaCopy; + + private final BedWars plugin = BedWars.getInstance(); + + public ArenaCopyRemovalRunnable(int number, Arena arena, CopiedArena arenaCopy) { + this.number = number; + this.arena = arena; + this.arenaCopy = arenaCopy; + } + + @Override + public void run() { + TaskManager.IMP.async(() -> { + EditSession editSession = new EditSessionBuilder(arenaCopy.getA().getWorld()).fastmode(true).allowedRegionsEverywhere().autoQueue(false).limitUnlimited().build(); + CuboidRegion copyRegion = new CuboidRegion( + new Vector(arenaCopy.getMax().getX(), arenaCopy.getMax().getY(), arenaCopy.getMax().getZ()), + new Vector(arenaCopy.getMin().getX(), arenaCopy.getMin().getY(), arenaCopy.getMin().getZ()) + ); + + try { + editSession.setBlocks(copyRegion, new BaseBlock(BlockID.AIR)); + } catch (MaxChangedBlocksException e) { + e.getStackTrace(); + } + + editSession.flushQueue(); + }); + + this.plugin.getArenasConfig().getConfig().getConfigurationSection("arenas." + arena.getName() + ".copiedArenas").set(String.valueOf(number), null); + this.plugin.getArenasConfig().save(); + + this.plugin.getArenaManager().getArena(arena.getName()).getCopiedArenas().remove(arenaCopy); + this.plugin.getArenaManager().getArena(arena.getName()).getAvailableArenas().remove(number); + } +} diff --git a/src/main/java/rip/tilly/bedwars/runnables/BlockPlaceRunnable.java b/src/main/java/rip/tilly/bedwars/runnables/BlockPlaceRunnable.java new file mode 100644 index 0000000..8f1c344 --- /dev/null +++ b/src/main/java/rip/tilly/bedwars/runnables/BlockPlaceRunnable.java @@ -0,0 +1,62 @@ +package rip.tilly.bedwars.runnables; + +import com.boydti.fawe.util.EditSessionBuilder; +import com.boydti.fawe.util.TaskManager; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.blocks.BaseBlock; +import lombok.Getter; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +@Getter +public abstract class BlockPlaceRunnable extends BukkitRunnable { + + private final ConcurrentMap blocks; + private final int totalBlocks; + private final Iterator iterator; + private World world; + private int blockIndex = 0; + private int blocksPlaced = 0; + private boolean completed = false; + + public BlockPlaceRunnable(World world, Map blocks) { + this.world = world; + this.blocks = new ConcurrentHashMap<>(); + this.blocks.putAll(blocks); + this.totalBlocks = blocks.keySet().size(); + this.iterator = blocks.keySet().iterator(); + } + + @Override + public void run() { + if (blocks.isEmpty() || !iterator.hasNext()) { + finish(); + completed = true; + cancel(); + return; + } + + TaskManager.IMP.async(() -> { + EditSession editSession = new EditSessionBuilder(this.world.getName()).fastmode(true).allowedRegionsEverywhere().autoQueue(false).limitUnlimited().build(); + for (Map.Entry entry : this.blocks.entrySet()) { + try { + editSession.setBlock(new Vector(entry.getKey().getBlockX(), entry.getKey().getBlockY(), entry.getKey().getZ()), new BaseBlock(entry.getValue().getTypeId(), entry.getValue().getData())); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + editSession.flushQueue(); + TaskManager.IMP.task(this.blocks::clear); + }); + } + + public abstract void finish(); +} diff --git a/src/main/java/rip/tilly/bedwars/runnables/DuplicateArenaRunnable.java b/src/main/java/rip/tilly/bedwars/runnables/DuplicateArenaRunnable.java new file mode 100644 index 0000000..4cf639e --- /dev/null +++ b/src/main/java/rip/tilly/bedwars/runnables/DuplicateArenaRunnable.java @@ -0,0 +1,107 @@ +package rip.tilly.bedwars.runnables; + +import lombok.Getter; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.scheduler.BukkitRunnable; +import rip.tilly.bedwars.BedWars; +import rip.tilly.bedwars.game.arena.Arena; + +import java.util.HashMap; +import java.util.Map; + +@Getter +public abstract class DuplicateArenaRunnable extends BukkitRunnable { + + private final BedWars plugin; + private Arena copiedArena; + private int offsetX; + private int offsetZ; + private int incrementX; + private int incrementZ; + private Map paste; + + public DuplicateArenaRunnable(BedWars plugin, Arena copiedArena, int offsetX, int offsetZ, int incrementX, int incrementZ) { + this.plugin = plugin; + this.copiedArena = copiedArena; + this.offsetX = offsetX; + this.offsetZ = offsetZ; + this.incrementX = incrementX; + this.incrementZ = incrementZ; + } + + @Override + public void run() { + if (this.paste == null) { + Map copy = this.blocksFromTwoPoints(this.copiedArena.getMin().toBukkitLocation(), this.copiedArena.getMax().toBukkitLocation()); + this.paste = new HashMap<>(); + for (Location loc : copy.keySet()) { + if (copy.get(loc).getType() != Material.AIR) { + this.paste.put(loc.clone().add(this.offsetX, 0, this.offsetZ), copy.get(loc)); + } + } + copy.clear(); + } else { + Map newPaste = new HashMap<>(); + for (Location loc : this.paste.keySet()) { + if (this.paste.get(loc).getType() != Material.AIR) { + newPaste.put(loc.clone().add(this.incrementX, 0, this.incrementZ), this.paste.get(loc)); + } + } + this.paste.clear(); + this.paste.putAll(newPaste); + } + + boolean safe = true; + for (Location loc : this.paste.keySet()) { + Block block = loc.getBlock(); + if (block.getType() != Material.AIR) { + safe = false; + break; + } + } + + if (!safe) { + this.offsetX += this.incrementX; + this.offsetZ += this.incrementZ; + this.run(); + return; + } + + new BlockPlaceRunnable(this.copiedArena.getA().toBukkitLocation().getWorld(), this.paste) { + @Override + public void finish() { + DuplicateArenaRunnable.this.onComplete(); + } + }.runTaskTimer(this.plugin, 0L, 5L); + } + + public Map blocksFromTwoPoints(Location loc1, Location loc2) { + Map blocks = new HashMap<>(); + + int topBlockX = (loc1.getBlockX() < loc2.getBlockX() ? loc2.getBlockX() : loc1.getBlockX()); + int bottomBlockX = (loc1.getBlockX() > loc2.getBlockX() ? loc2.getBlockX() : loc1.getBlockX()); + + int topBlockY = (loc1.getBlockY() < loc2.getBlockY() ? loc2.getBlockY() : loc1.getBlockY()); + int bottomBlockY = (loc1.getBlockY() > loc2.getBlockY() ? loc2.getBlockY() : loc1.getBlockY()); + + int topBlockZ = (loc1.getBlockZ() < loc2.getBlockZ() ? loc2.getBlockZ() : loc1.getBlockZ()); + int bottomBlockZ = (loc1.getBlockZ() > loc2.getBlockZ() ? loc2.getBlockZ() : loc1.getBlockZ()); + + for (int x = bottomBlockX; x <= topBlockX; x++) { + for (int z = bottomBlockZ; z <= topBlockZ; z++) { + for (int y = bottomBlockY; y <= topBlockY; y++) { + Block block = loc1.getWorld().getBlockAt(x, y, z); + if (block.getType() != Material.AIR) { + blocks.put(new Location(loc1.getWorld(), x, y, z), block); + } + } + } + } + + return blocks; + } + + public abstract void onComplete(); +}