/* * This file is a part of the SteamWar software. * * Copyright (C) 2023 SteamWar.de-Serverteam * * This program 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. * * This program 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 this program. If not, see . */ package de.steamwar.bausystem.utils; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.function.pattern.WaterloggedRemover; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockTypes; import de.steamwar.bausystem.region.Color; import de.steamwar.bausystem.region.Point; import de.steamwar.sql.SchematicData; import de.steamwar.sql.SchematicNode; import lombok.Getter; import lombok.NonNull; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.function.BiConsumer; import java.util.function.BiPredicate; @Getter public class PasteBuilder { private final ClipboardProvider clipboardProvider; private Point pastPoint; private boolean rotate; private boolean ignoreAir; private boolean reset; private Point minPoint; private Point maxPoint; private int waterLevel; private List> predicates = new ArrayList<>(); private List> mappers = new ArrayList<>(); public PasteBuilder(@NonNull ClipboardProvider clipboardProvider) { this.clipboardProvider = clipboardProvider; } public PasteBuilder pastePoint(Point point) { this.pastPoint = point; return this; } public PasteBuilder rotate(boolean rotate) { this.rotate = rotate; return this; } public PasteBuilder ignoreAir(boolean ignoreAir) { this.ignoreAir = ignoreAir; return this; } public PasteBuilder reset(boolean reset) { this.reset = reset; return this; } public PasteBuilder minPoint(Point point) { this.minPoint = point; return this; } public PasteBuilder maxPoint(Point point) { this.maxPoint = point; return this; } public PasteBuilder waterLevel(int waterLevel) { this.waterLevel = waterLevel; return this; } public PasteBuilder only(BiPredicate predicate) { predicates.add(predicate); return this; } public PasteBuilder map(BiConsumer mapper) { mappers.add(mapper); return this; } public PasteBuilder color(Color color) { if (color == Color.PINK) return this; BaseBlock WOOL = Objects.requireNonNull(BlockTypes.PINK_WOOL).getDefaultState().toBaseBlock(); BaseBlock CLAY = Objects.requireNonNull(BlockTypes.PINK_TERRACOTTA).getDefaultState().toBaseBlock(); BaseBlock GLAZED = Objects.requireNonNull(BlockTypes.PINK_GLAZED_TERRACOTTA).getDefaultState().toBaseBlock(); BaseBlock GLASS = Objects.requireNonNull(BlockTypes.PINK_STAINED_GLASS).getDefaultState().toBaseBlock(); BaseBlock GLASS_PANE = Objects.requireNonNull(BlockTypes.PINK_STAINED_GLASS_PANE).getDefaultState().toBaseBlock(); BaseBlock CONCRETE = Objects.requireNonNull(BlockTypes.PINK_CONCRETE).getDefaultState().toBaseBlock(); BaseBlock CONCRETE_POWDER = Objects.requireNonNull(BlockTypes.PINK_CONCRETE_POWDER).getDefaultState().toBaseBlock(); BaseBlock CARPET = Objects.requireNonNull(BlockTypes.PINK_CARPET).getDefaultState().toBaseBlock(); BaseBlock wool = Objects.requireNonNull(BlockTypes.get(color.name().toLowerCase() + "_wool")).getDefaultState().toBaseBlock(); BaseBlock clay = Objects.requireNonNull(BlockTypes.get(color.name().toLowerCase() + "_terracotta")).getDefaultState().toBaseBlock(); BaseBlock glazed = Objects.requireNonNull(BlockTypes.get(color.name().toLowerCase() + "_glazed_terracotta")).getDefaultState().toBaseBlock(); BaseBlock glass = Objects.requireNonNull(BlockTypes.get(color.name().toLowerCase() + "_stained_glass")).getDefaultState().toBaseBlock(); BaseBlock glassPane = Objects.requireNonNull(BlockTypes.get(color.name().toLowerCase() + "_stained_glass_pane")).getDefaultState().toBaseBlock(); BaseBlock carpet = Objects.requireNonNull(BlockTypes.get(color.name().toLowerCase() + "_carpet")).getDefaultState().toBaseBlock(); BaseBlock concrete = Objects.requireNonNull(BlockTypes.get(color.name().toLowerCase() + "_concrete")).getDefaultState().toBaseBlock(); BaseBlock concretePowder = Objects.requireNonNull(BlockTypes.get(color.name().toLowerCase() + "_concrete_powder")).getDefaultState().toBaseBlock(); return map((clipboard, blockVector3) -> { BaseBlock block = clipboard.getFullBlock(blockVector3); if (block.equals(WOOL)) { clipboard.setBlock(blockVector3, wool); } else if (block.equals(CLAY)) { clipboard.setBlock(blockVector3, clay); } else if (block.equals(GLAZED)) { clipboard.setBlock(blockVector3, glazed); } else if (block.equals(GLASS)) { clipboard.setBlock(blockVector3, glass); } else if (block.equals(GLASS_PANE)) { clipboard.setBlock(blockVector3, glassPane); } else if (block.equals(CARPET)) { clipboard.setBlock(blockVector3, carpet); } else if (block.equals(CONCRETE)) { clipboard.setBlock(blockVector3, concrete); } else if (block.equals(CONCRETE_POWDER)) { clipboard.setBlock(blockVector3, concretePowder); } }); } public PasteBuilder onlyColors(boolean onlyColors) { if (!onlyColors) return this; return only((baseBlock, s) -> { return s.endsWith("_wool") || s.endsWith("_terracotta") || s.endsWith("_glazed_terracotta") || s.endsWith("_stained_glass") || s.endsWith("_stained_glass_pane") || s.endsWith("_carpet") || s.endsWith("_concrete") || s.endsWith("_concrete_powder"); }); } public PasteBuilder removeTNT(boolean removeTNT) { if (!removeTNT) return this; BaseBlock tnt = Objects.requireNonNull(BlockTypes.get("tnt")).getDefaultState().toBaseBlock(); BaseBlock air = Objects.requireNonNull(BlockTypes.get("air")).getDefaultState().toBaseBlock(); return map((clipboard, blockVector3) -> { BaseBlock baseBlock = clipboard.getFullBlock(blockVector3); if (baseBlock.equals(tnt)) { clipboard.setBlock(blockVector3, air); } }); } public PasteBuilder removeWater(boolean removeWater) { if (!removeWater) return this; BaseBlock water = Objects.requireNonNull(BlockTypes.get("water")).getDefaultState().toBaseBlock(); BaseBlock air = Objects.requireNonNull(BlockTypes.get("air")).getDefaultState().toBaseBlock(); WaterloggedRemover waterloggedRemover = new WaterloggedRemover(getClipboard()); return map((clipboard, blockVector3) -> { BaseBlock baseBlock = clipboard.getFullBlock(blockVector3); if (baseBlock.equals(water)) { clipboard.setBlock(blockVector3, air); return; } String blockName = clipboard.getFullBlock(blockVector3).getBlockType().getName(); if (blockName.equals("Water")) { clipboard.setBlock(blockVector3, air); return; } baseBlock = waterloggedRemover.applyBlock(blockVector3); if (baseBlock != air) { clipboard.setBlock(blockVector3, baseBlock); } }); } public Clipboard getClipboard() { return clipboardProvider.getClipboard(); } public EditSession run() { if (pastPoint == null) { throw new IllegalStateException("pastePoint is null"); } return FlatteningWrapper.impl.paste(this); } public interface ClipboardProvider { Clipboard getClipboard(); default boolean is(Class clazz) { return clazz.isInstance(this); } default T as(Class clazz) { return clazz.cast(this); } } @Getter public static class FileProvider implements ClipboardProvider { private final File file; private final Clipboard clipboard; public FileProvider(File file) { this.file = file; this.clipboard = FlatteningWrapper.impl.loadSchematic(file); } @Override public Clipboard getClipboard() { return clipboard; } } @Getter public static class SchematicProvider implements ClipboardProvider { private final SchematicNode schematic; private final Clipboard clipboard; public SchematicProvider(SchematicNode schematic) { this.schematic = schematic; try { this.clipboard = new SchematicData(schematic).load(); } catch (IOException e) { throw new SecurityException(e); } } @Override public Clipboard getClipboard() { return clipboard; } } @Getter public static class ClipboardProviderImpl implements ClipboardProvider { private final Clipboard clipboard; public ClipboardProviderImpl(Clipboard clipboard) { this.clipboard = clipboard; } @Override public Clipboard getClipboard() { return clipboard; } } }