Add CuboidCreator for clipboard cuboid creation
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Signed-off-by: yoyosource <yoyosource@nidido.de>
Dieser Commit ist enthalten in:
yoyosource 2023-01-29 09:58:52 +01:00
Ursprung 91abbc25fc
Commit 3eeca6c349
5 geänderte Dateien mit 260 neuen und 21 gelöschten Zeilen

Datei anzeigen

@ -53,7 +53,7 @@ public class CuboidSchematicWriter {
// Setup
Pos playerPos = new Pos(player.getLocation());
Pos offset = min.sub(playerPos);
Map<Pos, String> blocks = CuboidSchematicWriter.getBlocks(player, min, max);
Map<Pos, String> blocks = CuboidSchematicWriter.getBlocks(player, min, max); // Needs to be optimized
Map<String, Set<Pos>> reverseBlocks = reverse(blocks);
// Create CuboidSchematic

Datei anzeigen

@ -45,26 +45,6 @@ public class TypedCuboid {
this.blockData = blockData;
}
public boolean intersects(TypedCuboid cuboid) {
int minx = x - cuboid.dx;
int miny = y - cuboid.dy;
int minz = z - cuboid.dz;
int maxx = minx + dx + cuboid.dx;
int maxy = miny + dy + cuboid.dy;
int maxz = minz + dz + cuboid.dz;
return maxx > cuboid.x && maxy > cuboid.y && maxz > cuboid.z && minx < cuboid.x && miny < cuboid.y && minz < cuboid.z;
}
public boolean intersects(Pos pos) {
int minx = x - dx;
int miny = y - dy;
int minz = z - dz;
int maxx = minx + dx;
int maxy = miny + dy;
int maxz = minz + dz;
return maxx > pos.x && maxy > pos.y && maxz > pos.z && minx < pos.x && miny < pos.y && minz < pos.z;
}
public long size() {
return (long) dx * (long) dy * (long) dz;
}

Datei anzeigen

@ -0,0 +1,55 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.cuboid.clipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.bausystem.utils.WorldEditUtils;
import de.steamwar.command.SWCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
import java.util.concurrent.atomic.AtomicInteger;
@Linked
public class CuboidCommand extends SWCommand {
public CuboidCommand() {
super("clipboardcuboid");
}
@Register
public void onCommand(Player player) {
Clipboard clipboard = WorldEditUtils.getClipboard(player);
if (clipboard == null) {
player.sendMessage("§cDu hast keine Schematic geladen!");
return;
}
long time = System.currentTimeMillis();
AtomicInteger counter = new AtomicInteger();
new CuboidCreator(clipboard).forEachRemaining(cuboid -> {
counter.incrementAndGet();
});
time = System.currentTimeMillis() - time;
player.sendMessage("§aEs wurden " + counter.get() + " Cuboids erstellt!");
player.sendMessage("§aDas hat " + time + "ms gedauert!");
player.sendMessage("§aDas sind " + (counter.get() / time) + " Cuboids/ms!");
}
}

Datei anzeigen

@ -0,0 +1,190 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.cuboid.clipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockState;
import lombok.ToString;
import org.bukkit.Axis;
import org.bukkit.util.Vector;
import java.util.*;
public class CuboidCreator implements Iterator<CuboidCreator.Cuboid> {
private static final List<Axis[]> AXES = Arrays.asList(
new Axis[]{Axis.X, Axis.Y, Axis.Z},
new Axis[]{Axis.X, Axis.Z, Axis.Y},
new Axis[]{Axis.Y, Axis.X, Axis.Z},
new Axis[]{Axis.Y, Axis.Z, Axis.X},
new Axis[]{Axis.Z, Axis.X, Axis.Y},
new Axis[]{Axis.Z, Axis.Y, Axis.X}
);
private Map<BlockVector3, BlockState> blocks = new HashMap<>();
private Map<BlockState, Set<BlockVector3>> reverseBlocks = new HashMap<>();
private List<BlockVector3> left = new ArrayList<>();
public CuboidCreator(Clipboard clipboard) {
clipboard.getRegion().forEach(blockVector3 -> {
BlockVector3 position = blockVector3.subtract(clipboard.getMinimumPoint());
BlockState block = clipboard.getBlock(blockVector3);
blocks.put(position, block);
reverseBlocks.computeIfAbsent(block, k -> new HashSet<>()).add(position);
});
left.add(BlockVector3.ZERO);
}
@Override
public boolean hasNext() {
left.removeIf(blockVector3 -> !blocks.containsKey(blockVector3));
return !left.isEmpty();
}
@Override
public Cuboid next() {
BlockVector3 origin = left.get(0);
BlockState block = blocks.get(origin);
Cuboid cuboid = null;
for (Axis[] axes : AXES) {
Cuboid currentCuboid = new Cuboid(origin, block);
expand(currentCuboid, new ArrayList<>(Arrays.asList(axes)));
if (cuboid == null || cuboid.size() < currentCuboid.size()) {
cuboid = currentCuboid;
}
}
Set<BlockVector3> cuboidBlocks = reverseBlocks.get(block);
for (int x = cuboid.x; x < cuboid.x + cuboid.dx; x++) {
for (int y = cuboid.y; y < cuboid.y + cuboid.dy; y++) {
for (int z = cuboid.z; z < cuboid.z + cuboid.dz; z++) {
BlockVector3 pos = BlockVector3.at(x, y, z);
cuboidBlocks.remove(pos);
blocks.remove(pos);
}
}
}
left.add(BlockVector3.at(origin.getBlockX() + cuboid.dx + 1, origin.getBlockY(), origin.getBlockZ()));
left.add(BlockVector3.at(origin.getBlockX(), origin.getBlockY() + cuboid.dy + 1, origin.getBlockZ()));
left.add(BlockVector3.at(origin.getBlockX(), origin.getBlockY(), origin.getBlockZ() + cuboid.dz + 1));
return cuboid;
}
private void expand(Cuboid cuboid, List<Axis> axes) {
while (!axes.isEmpty()) {
axes.removeIf(axis -> {
org.bukkit.util.Vector direction = new Vector();
switch (axis) {
case X:
direction.setX(1);
break;
case Y:
direction.setY(1);
break;
case Z:
direction.setZ(1);
break;
}
return !expand(cuboid, direction);
});
}
}
private boolean expand(Cuboid cuboid, Vector direction) {
Set<BlockVector3> blocks = reverseBlocks.get(cuboid.getBlock());
if (direction.getX() == 1) {
for (int y = cuboid.y; y < cuboid.y + cuboid.dy; y++) {
for (int z = cuboid.z; z < cuboid.z + cuboid.dz; z++) {
if (!blocks.contains(BlockVector3.at(cuboid.x + cuboid.dx + 1, y, z))) {
return false;
}
}
}
} else if (direction.getY() == 1) {
for (int x = cuboid.x; x < cuboid.x + cuboid.dx; x++) {
for (int z = cuboid.z; z < cuboid.z + cuboid.dz; z++) {
if (!blocks.contains(BlockVector3.at(x, cuboid.y + cuboid.dy + 1, z))) {
return false;
}
}
}
} else if (direction.getZ() == 1) {
for (int x = cuboid.x; x < cuboid.x + cuboid.dx; x++) {
for (int y = cuboid.y; y < cuboid.y + cuboid.dy; y++) {
if (!blocks.contains(BlockVector3.at(x, y, cuboid.z + cuboid.dz + 1))) {
return false;
}
}
}
}
if (direction.getX() == 1) {
cuboid.dx++;
} else if (direction.getY() == 1) {
cuboid.dy++;
} else if (direction.getZ() == 1) {
cuboid.dz++;
}
return true;
}
@ToString
public static class Cuboid {
int x;
int y;
int z;
int dx;
int dy;
int dz;
private BlockState block;
public Cuboid(BlockVector3 origin, BlockState block) {
this.x = origin.getBlockX();
this.y = origin.getBlockY();
this.z = origin.getBlockZ();
this.dx = 1;
this.dy = 1;
this.dz = 1;
this.block = block;
}
public long size() {
return (long) dx * (long) dy * (long) dz;
}
public BlockVector3 getOrigin() {
return BlockVector3.at(x, y, z);
}
public BlockVector3 getSize() {
return BlockVector3.at(dx, dy, dz);
}
public BlockState getBlock() {
return block;
}
}
}

Datei anzeigen

@ -20,10 +20,12 @@
package de.steamwar.bausystem.utils;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.EmptyClipboardException;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extension.factory.PatternFactory;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.registry.InputParser;
@ -95,4 +97,16 @@ public class WorldEditUtils {
private Location adapt(World world, BlockVector3 blockVector3) {
return new Location(world, blockVector3.getBlockX(), blockVector3.getBlockY(), blockVector3.getBlockZ());
}
public Clipboard getClipboard(Player player) {
try {
return WorldEdit.getInstance()
.getSessionManager()
.get(BukkitAdapter.adapt(player))
.getClipboard()
.getClipboard();
} catch (EmptyClipboardException e) {
return null;
}
}
}