Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package games.coob.skywars.model;
- import com.sk89q.worldedit.EditSession;
- import com.sk89q.worldedit.MaxChangedBlocksException;
- import com.sk89q.worldedit.WorldEdit;
- import com.sk89q.worldedit.WorldEditException;
- import com.sk89q.worldedit.bukkit.BukkitWorld;
- import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
- import com.sk89q.worldedit.extent.clipboard.Clipboard;
- import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
- import com.sk89q.worldedit.function.operation.Operation;
- import com.sk89q.worldedit.function.operation.RunContext;
- import com.sk89q.worldedit.math.BlockVector3;
- import com.sk89q.worldedit.regions.CuboidRegion;
- import com.sk89q.worldedit.world.World;
- import com.sk89q.worldedit.world.block.BaseBlock;
- import lombok.experimental.UtilityClass;
- import org.bukkit.Location;
- import org.bukkit.block.Block;
- import org.mineacademy.fo.Common;
- import org.mineacademy.fo.collection.StrictMap;
- import org.mineacademy.fo.collection.StrictSet;
- import org.mineacademy.fo.model.ChunkedTask;
- import org.mineacademy.fo.region.Region;
- import java.util.List;
- @UtilityClass
- public final class ArenaMapManager {
- /**
- * Holds clipboards for saved regions (until we restore them or stop/reload/restart the server)
- */
- private final StrictMap<String, Clipboard> savedClipboards = new StrictMap<>();
- /**
- * Saves the arena region if it can be saved
- */
- public void saveRegion(final Arena arena) {
- final Region region = arena.getSettings().getRegion();
- if (region == null || !region.isWhole())
- return;
- final CuboidRegion cuboidRegion = new CuboidRegion(new BukkitWorld(region.getWorld()), toVector(region.getPrimary()), toVector(region.getSecondary()));
- final BlockArrayClipboard clipboard = new BlockArrayClipboard(cuboidRegion);
- try (EditSession editSession = createSession(cuboidRegion.getWorld())) {
- new ChunkedTask(1) {
- /**
- * The copy operation we are using
- */
- private Operation operation = new ForwardExtentCopy(editSession, cuboidRegion, clipboard, cuboidRegion.getMinimumPoint());
- /**
- * Resume the operation means the operation moves forward
- * until it can no longer be resumed
- */
- @Override
- protected void onProcess(final int index) {
- try {
- operation = operation.resume(new RunContext());
- } catch (final WorldEditException e) {
- e.printStackTrace();
- }
- }
- /**
- * Return true if the operation can be resumed, ie not null
- */
- @Override
- protected boolean canContinue(final int index) {
- return operation != null;
- }
- }.startChain();
- }
- if (savedClipboards.contains(arena.getName()))
- savedClipboards.remove(arena.getName());
- savedClipboards.put(arena.getName(), clipboard);
- }
- /**
- * Restore arena region if it has been saved
- */
- public void restoreRegion(final Arena arena) {
- final Clipboard clipboard = savedClipboards.removeWeak(arena.getName());
- final Region region = arena.getSettings().getRegion();
- if (clipboard == null)
- return;
- try (EditSession editSession = createSession(new BukkitWorld(region.getWorld()))) {
- final List<BlockVector3> vectors = Common.convert(region.getBlocks(), ArenaMapManager::toVector);
- new ChunkedTask(150_000) {
- /**
- * For each block in region find block stored in the clipboard,
- * if it exists, restore it back
- */
- @Override
- protected void onProcess(final int index) {
- final BlockVector3 vector = vectors.get(index);
- final BaseBlock copy = clipboard.getFullBlock(vector);
- if (copy != null)
- try {
- editSession.setBlock(vector, copy);
- editSession.close();
- } catch (final MaxChangedBlocksException e) {
- e.printStackTrace();
- }
- }
- /**
- * Flush the operation to make the blocks visible on finish
- */
- @Override
- protected void onFinish() {
- editSession.close();
- }
- /**
- * Return if we can pull more blocks from our region or we are finished
- */
- @Override
- protected boolean canContinue(final int index) {
- return index < vectors.size();
- }
- /**
- * Also show percentage how many blocks we have restored to finish
- */
- @Override
- protected String getProcessMessage(final long initialTime, final int processed) {
- final long progress = Math.round(((double) getCurrentIndex() / (double) vectors.size()) * 100);
- return "[" + progress + "%] " + super.getProcessMessage(initialTime, processed);
- }
- }.startChain();
- }
- }
- /*
- * Create a new edit session
- */
- private EditSession createSession(final World world) {
- // session.setReorderMode(EditSession.ReorderMode.FAST); CAUSES UNDESIRABLE SIDE (PREVENTS LIGHTING OR PHYSICS UPDATES) EFFECTS BUT INCREASES SPEED
- return WorldEdit.getInstance().newEditSession(world);
- }
- /*
- * Create a WorldEdit vector from the given block
- */
- private BlockVector3 toVector(final Block block) {
- return toVector(block.getLocation());
- }
- /*
- * Create a WorldEdit vector from the given location
- */
- private BlockVector3 toVector(final Location location) {
- return BlockVector3.at(location.getX(), location.getY(), location.getZ());
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement