diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/RegionCommand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/RegionCommand.java index 640d4eb3..8b5e68da 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/RegionCommand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/RegionCommand.java @@ -30,6 +30,7 @@ import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.features.util.SelectCommand; import de.steamwar.bausystem.region.Point; import de.steamwar.bausystem.region.Region; +import de.steamwar.bausystem.region.RegionHistory; import de.steamwar.bausystem.region.RegionUtils; import de.steamwar.bausystem.region.flags.Flag; import de.steamwar.bausystem.shared.Pair; @@ -71,7 +72,10 @@ public class RegionCommand extends SWCommand { @Register(value = "undo", description = "REGION_REGION_HELP_UNDO") public void undoCommand(@Validator Player p) { Region region = Region.getRegion(p.getLocation()); - if (checkGlobalRegion(region, p)) return; + if (region.getHistory() == RegionHistory.EMPTY) { + BauSystem.MESSAGE.send("REGION_REGION_NO_REGION", p); + return; + } if (region.getHistory().undo()) { RegionUtils.message(region, "REGION_REGION_UNDID"); @@ -83,7 +87,8 @@ public class RegionCommand extends SWCommand { @Register(value = "redo", description = "REGION_REGION_HELP_REDO") public void redoCommand(@Validator Player p) { Region region = Region.getRegion(p.getLocation()); - if (checkGlobalRegion(region, p)) { + if (region.getHistory() == RegionHistory.EMPTY) { + BauSystem.MESSAGE.send("REGION_REGION_NO_REGION", p); return; } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/region/RegionType.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/region/RegionType.java index ccdc03af..305c4dd9 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/region/RegionType.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/region/RegionType.java @@ -26,15 +26,24 @@ import lombok.RequiredArgsConstructor; @Getter public enum RegionType { - GLOBAL(true, false), - NORMAL(false, true), + GLOBAL(true, false, true, ConnectionType.Global), + NORMAL(false, true, false, ConnectionType.Closed), - SPAWN(false, false), - SPAWN_PATH(false, false), - SPAWN_EXTENSION(false, false), - PATH(false, false), + SPAWN(false, false, true, ConnectionType.Closed), + SPAWN_PATH(false, false, true, ConnectionType.Path), + SPAWN_EXTENSION(false, false, false, ConnectionType.Closed), + PATH(false, false, false, ConnectionType.Path), ; private final boolean global; private final boolean createBackup; + private final boolean cannotDelete; + private final ConnectionType connectionType; + + public enum ConnectionType { + Closed, + Path, + Water, + Global + } } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/PasteBuilder.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/PasteBuilder.java index 9323ceab..6d209b74 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/PasteBuilder.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/PasteBuilder.java @@ -205,10 +205,10 @@ public class PasteBuilder { } public EditSession run() { - if (pastPoint == null) { - throw new IllegalStateException("pastePoint is null"); + if (pastPoint != null || minPoint != null) { + return FlatteningWrapper.impl.paste(this); } - return FlatteningWrapper.impl.paste(this); + throw new IllegalStateException("pastePoint is null"); } public interface ClipboardProvider { diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionCommand.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionCommand.java new file mode 100644 index 00000000..968ad04d --- /dev/null +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionCommand.java @@ -0,0 +1,58 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 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.region; + +import de.steamwar.bausystem.features.region.RegionCommand; +import de.steamwar.bausystem.region.dynamic.DynamicRegion; +import de.steamwar.bausystem.region.dynamic.TileUtils; +import de.steamwar.bausystem.region.dynamic.path.PathRegion; +import de.steamwar.bausystem.shared.Pair; +import de.steamwar.command.AbstractSWCommand; +import de.steamwar.command.SWCommand; +import org.bukkit.entity.Player; + +import java.util.stream.Collectors; + +@AbstractSWCommand.PartOf(RegionCommand.class) +public class DynamicRegionCommand extends SWCommand { + + public DynamicRegionCommand() { + super(""); + } + + @Register({"dynamic", "place"}) + public void placeRegion(Player player) { + Region region = DynamicRegionSystem.INSTANCE.get(player.getLocation()); + if (!region.getType().isGlobal()) return; + Pair tile = TileUtils.fromLocation(player.getLocation()); + Pair min = TileUtils.toMinLocation(tile); + PathRegion pathRegion = new PathRegion(min.getKey(), min.getValue()); + pathRegion.getArea().reset(null, false); + DynamicRegionSystem.INSTANCE.getNeighbours(pathRegion).collect(Collectors.toList()) + .forEach(r -> r.update(pathRegion)); + } + + @Register({"dynamic", "delete"}) + public void deleteRegion(Player player) { + Region region = DynamicRegionSystem.INSTANCE.get(player.getLocation()); + if (region.getType().isCannotDelete()) return; + ((DynamicRegion) region).delete(); + } +} diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionSystem.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionSystem.java index 92d039a1..170bc191 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionSystem.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionSystem.java @@ -24,6 +24,7 @@ import de.steamwar.bausystem.region.dynamic.DynamicRegion; import de.steamwar.bausystem.region.dynamic.MovementListener; import de.steamwar.bausystem.region.dynamic.RegionDataRepository; import de.steamwar.bausystem.region.dynamic.global.GlobalRegion; +import de.steamwar.bausystem.region.dynamic.path.PathRegion; import de.steamwar.bausystem.region.dynamic.spawn.SpawnPathRegion; import de.steamwar.bausystem.region.dynamic.spawn.SpawnRegion; import lombok.NonNull; @@ -44,15 +45,21 @@ public class DynamicRegionSystem implements RegionSystem { @Override public void load() { INSTANCE = this; + new DynamicRegionCommand(); RegionDataRepository.loadRegions(); Bukkit.getPluginManager().registerEvents(new MovementListener(), BauSystem.getInstance()); if (regionMap.isEmpty()) { new SpawnRegion(-9, -9); - new SpawnPathRegion(-9, -27); + new SpawnPathRegion(-9, -28); new SpawnPathRegion(-9, 10); - new SpawnPathRegion(-27, -9); + new SpawnPathRegion(-28, -9); new SpawnPathRegion(10, -9); + + new PathRegion(-28, -28); + new PathRegion(-28, 10); + new PathRegion(10, -28); + new PathRegion(10, 10); } } @@ -96,9 +103,10 @@ public class DynamicRegionSystem implements RegionSystem { return regionMap.values().stream(); } - public Stream getNeighbours(Region region) { - Point minPoint = region.getArea().getMinPoint(false).subtract(19, 0, 19); + public Stream getNeighbours(Region region) { + Point minPoint = region.getArea().getMinPoint(false).subtract(18, 0, 18); Point maxPoint = region.getArea().getMaxPoint(false).add(19, 0, 19); + // TODO: Optimize Set away! Set neighbours = new HashSet<>(); for (int x = minPoint.getX(); x <= maxPoint.getX(); x += 19) { int minZ = minPoint.getZ(); @@ -106,14 +114,14 @@ public class DynamicRegionSystem implements RegionSystem { neighbours.add(get(new Location(WORLD, x, 0, minZ))); neighbours.add(get(new Location(WORLD, x, 0, maxZ))); } - for (int z = minPoint.getZ() + 19; z <= maxPoint.getZ() - 19; z += 19) { + for (int z = minPoint.getZ() + 18; z <= maxPoint.getZ() - 19; z += 19) { int minX = minPoint.getX(); int maxX = maxPoint.getX(); neighbours.add(get(new Location(WORLD, minX, 0, z))); neighbours.add(get(new Location(WORLD, maxX, 0, z))); } neighbours.remove(GlobalRegion.INSTANCE); - return neighbours.stream(); + return ((Set)(Set) neighbours).stream(); } @Override diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/DynamicRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/DynamicRegion.java index 1d545d58..eb0e9329 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/DynamicRegion.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/DynamicRegion.java @@ -19,10 +19,17 @@ package de.steamwar.bausystem.region.dynamic; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.world.block.BlockTypes; import de.steamwar.bausystem.region.*; import lombok.NonNull; +import org.bukkit.Bukkit; import java.util.UUID; +import java.util.stream.Collectors; public abstract class DynamicRegion implements Region { @@ -30,7 +37,6 @@ public abstract class DynamicRegion implements Region { protected final int minX; protected final int minZ; - protected final RegionHistory history = new RegionHistory.Impl(20); protected final RegionBackups backups; protected DynamicRegion(int minX, int minZ) { @@ -69,13 +75,26 @@ public abstract class DynamicRegion implements Region { public abstract void setFlags(FlagStorage flags); public void delete() { + if (getType().isCannotDelete()) return; DynamicRegionSystem.INSTANCE.delete(this); RegionDataRepository.deleteRegion(this); - } - @Override - public @NonNull RegionHistory getHistory() { - return history; + Point minPoint = getArea().getMinPoint(false); + Point maxPoint = getArea().getMaxPoint(false); + + EditSession editSession = WorldEdit.getInstance() + .newEditSessionBuilder() + .world(BukkitAdapter.adapt(Bukkit.getWorlds().get(0))) + .checkMemory(false) + .allowedRegionsEverywhere() + .limitUnlimited() + .changeSetNull() + .build(); + editSession.setBlocks((com.sk89q.worldedit.regions.Region) new CuboidRegion(minPoint.toBlockVector3(), maxPoint.toBlockVector3()), BlockTypes.AIR.getDefaultState()); + editSession.close(); + + DynamicRegionSystem.INSTANCE.getNeighbours(this).collect(Collectors.toList()) + .forEach(region -> region.update(this)); } @Override diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/MovementListener.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/MovementListener.java index 33a1197e..665ac3ef 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/MovementListener.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/MovementListener.java @@ -23,32 +23,15 @@ import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.shared.Pair; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.TextComponent; -import org.bukkit.Location; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerMoveEvent; -import java.util.Optional; - public class MovementListener implements Listener { - private static final int tileSize = 19; - private static final int minTile = -1023; - private static final int maxTile = 1023; - - public static Pair fromLocation(Location location) { - int x = (location.getBlockX() + 9) / tileSize; - int z = (location.getBlockZ() + 9) / tileSize; - if (location.getX() < -9) x--; - if (location.getZ() < -9) z--; - if (x < minTile || z < minTile) return null; - if (x > maxTile || z > maxTile) return null; - return new Pair<>(x, z); - } - @EventHandler public void onPlayerMove(PlayerMoveEvent event) { - Pair tile = fromLocation(event.getTo()); + Pair tile = TileUtils.fromLocation(event.getTo()); Region region = Region.getRegion(event.getTo()); if (tile != null) { event.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(tile.getKey() + " : " + tile.getValue() + " " + region.getType())); diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/RegionDataRepository.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/RegionDataRepository.java index e7dbeb27..e0df1198 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/RegionDataRepository.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/RegionDataRepository.java @@ -28,6 +28,7 @@ import de.steamwar.bausystem.region.Point; import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.region.RegionBackups; import de.steamwar.bausystem.region.dynamic.normal.NormalFlagStorage; +import de.steamwar.bausystem.region.dynamic.path.PathRegion; import de.steamwar.bausystem.region.dynamic.spawn.SpawnPathRegion; import de.steamwar.bausystem.region.dynamic.spawn.SpawnRegion; import de.steamwar.bausystem.region.flags.Flag; @@ -66,6 +67,7 @@ public class RegionDataRepository { static { regionCreators.put(SpawnRegion.class.getSimpleName(), SpawnRegion::new); regionCreators.put(SpawnPathRegion.class.getSimpleName(), SpawnPathRegion::new); + regionCreators.put(PathRegion.class.getSimpleName(), PathRegion::new); } static { @@ -109,6 +111,7 @@ public class RegionDataRepository { File file = getRegionDirectory(region); file = new File(file, FLAGS_FILE_NAME); loadFlagStorage(file, storage); + if (!file.exists()) saveFlagStorage(region, storage); storage.setSaveOperation(currentStorage -> { saveFlagStorage(region, currentStorage); }); diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/TileUtils.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/TileUtils.java new file mode 100644 index 00000000..6e61919d --- /dev/null +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/TileUtils.java @@ -0,0 +1,44 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 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.region.dynamic; + +import de.steamwar.bausystem.shared.Pair; +import lombok.experimental.UtilityClass; +import org.bukkit.Location; + +@UtilityClass +public class TileUtils { + + private static final int tileSize = 19; + private static final int minTile = -1023; + private static final int maxTile = 1023; + + public Pair fromLocation(Location location) { + int x = (int) Math.floor((location.getBlockX() + 9) / (double) tileSize); + int z = (int) Math.floor((location.getBlockZ() + 9) / (double) tileSize); + if (x < minTile || z < minTile) return null; + if (x > maxTile || z > maxTile) return null; + return new Pair<>(x, z); + } + + public Pair toMinLocation(Pair tile) { + return new Pair<>(tile.getKey() * tileSize - 9, tile.getValue() * tileSize - 9); + } +} diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathAreaTile.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathAreaTile.java new file mode 100644 index 00000000..d3429400 --- /dev/null +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathAreaTile.java @@ -0,0 +1,155 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 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.region.dynamic.path; + +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.math.BlockVector3; +import de.steamwar.bausystem.region.Point; +import de.steamwar.bausystem.region.Region; +import de.steamwar.bausystem.region.RegionSystem; +import de.steamwar.bausystem.region.RegionType; +import de.steamwar.bausystem.utils.FlatteningWrapper; +import de.steamwar.bausystem.utils.PasteBuilder; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.bukkit.Bukkit; +import org.bukkit.World; + +import javax.annotation.Nullable; +import java.io.File; +import java.util.function.Function; + +public class PathAreaTile implements Region.Area { + + private static final File PATH_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections/path"); + private static final File PATH_CENTER = new File(PATH_DIR, "PathCenter.schem"); + + @RequiredArgsConstructor + private enum Path { + North(0, -18, 5, 0), + South(0, 19, 5, 14), + West(-18, 0, 0, 5), + East(19, 0, 14, 5), + ; + + private final int checkX; + private final int checkZ; + private final int pasteX; + private final int pasteZ; + private final Function function = connectionType -> { + return new File(PATH_DIR, "Path" + name() + connectionType.name() + ".schem"); + }; + } + + @RequiredArgsConstructor + private enum PathCorner { + NorthEast(Path.North, Path.East, 14, 0), + EastSouth(Path.East, Path.South, 14, 14), + SouthWest(Path.South, Path.West, 0, 14), + WestNorth(Path.West, Path.North, 0, 0), + ; + + private final Path check1; + private final Path check2; + private final int pasteX; + private final int pasteZ; + private final TriFunction function = (connectionType1, connectionType2, connectionTypeCorner) -> { + return new File(PATH_DIR, "Path" + name() + connectionType1.name() + connectionType2.name() + connectionTypeCorner.name() + ".schem"); + }; + + private interface TriFunction { + W apply(T t, U u, V v); + } + } + + private final int minX; + private final int minZ; + private final Point minPoint; + private final Point maxPoint; + private final Point copyPoint; + private final Region region; + + public PathAreaTile(int minX, int minZ, Region region) { + this.minX = minX; + this.minZ = minZ; + + minPoint = new Point(minX, 0, minZ); + maxPoint = new Point(minX + 18, 255, minZ + 18); + copyPoint = new Point(minX + 9, 0, minZ + 9); + + this.region = region; + } + + @Override + public @NonNull Point getMinPoint(boolean extension) { + return minPoint; + } + + @Override + public @NonNull Point getMaxPoint(boolean extension) { + return maxPoint; + } + + @Override + public @NonNull Point getCopyPoint() { + return copyPoint; + } + + @Nullable + @Override + public File getResetFile() { + return null; // TODO: I know what I do! + } + + @Override + public void reset(PasteBuilder pasteBuilder, boolean extension) { + Point minPoint = getMinPoint(false); + + paste(PATH_CENTER, minPoint.add(5, 0, 5)); + + for (Path path : Path.values()) { + RegionType.ConnectionType connectionType = RegionSystem.INSTANCE.get(minPoint.add(path.checkX, 0, path.checkZ).toLocation((World) null)).getType().getConnectionType(); + File schem = path.function.apply(connectionType); + if (schem.exists()) { + paste(schem, minPoint.add(path.pasteX, 0, path.pasteZ)); + } + } + + for (PathCorner corner : PathCorner.values()) { + RegionType.ConnectionType connectionType1 = RegionSystem.INSTANCE.get(minPoint.add(corner.check1.checkX, 0, corner.check1.checkZ).toLocation((World) null)).getType().getConnectionType(); + RegionType.ConnectionType connectionType2 = RegionSystem.INSTANCE.get(minPoint.add(corner.check2.checkX, 0, corner.check2.checkZ).toLocation((World) null)).getType().getConnectionType(); + RegionType.ConnectionType connectionTypeCorner = RegionSystem.INSTANCE.get(minPoint.add(corner.check1.checkX + corner.check2.checkX, 0, corner.check1.checkZ + corner.check2.checkZ).toLocation((World) null)).getType().getConnectionType(); + File schem = corner.function.apply(connectionType1, connectionType2, connectionTypeCorner); + if (schem.exists()) { + paste(schem, minPoint.add(corner.pasteX, 0, corner.pasteZ)); + } else { + paste(new File(PATH_DIR, "PathCornerUnknown.schem"), minPoint.add(corner.pasteX, 0, corner.pasteZ)); + } + } + } + + private void paste(File file, Point minPoint) { + Clipboard clipboard = FlatteningWrapper.impl.loadSchematic(file); + BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin()); + BlockVector3 to = minPoint.toBlockVector3().subtract(offset); + clipboard.paste(BukkitAdapter.adapt(Bukkit.getWorlds().get(0)), to); + } +} diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathRegion.java new file mode 100644 index 00000000..1c2a925f --- /dev/null +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathRegion.java @@ -0,0 +1,115 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 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.region.dynamic.path; + +import de.steamwar.bausystem.region.FlagStorage; +import de.steamwar.bausystem.region.RegionConfig; +import de.steamwar.bausystem.region.RegionHistory; +import de.steamwar.bausystem.region.RegionType; +import de.steamwar.bausystem.region.dynamic.DynamicRegion; +import de.steamwar.bausystem.region.dynamic.NonNormalFlagStorage; +import de.steamwar.bausystem.region.dynamic.RegionConstructorData; +import de.steamwar.bausystem.region.dynamic.RegionDataRepository; +import de.steamwar.bausystem.region.dynamic.spawn.SpawnAreaTile; +import de.steamwar.bausystem.region.dynamic.spawn.SpawnResetter; +import lombok.NonNull; +import org.bukkit.Bukkit; + +import java.io.File; + +public class PathRegion extends DynamicRegion { + + private static final File SECTIONS_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections"); + private static final File RESET_FILE = new File(SECTIONS_DIR, "path/Path.schem"); // Temp + + private FlagStorage flagStorage = new NonNormalFlagStorage(); + private final Area area; + private final RegionConfig config = new RegionConfig(null); + + public PathRegion(int minX, int minZ) { + super(minX, minZ); + RegionDataRepository.loadFlagStorage(this, flagStorage); + if (minX >= -28 && minX <= 10 && minZ >= -28 && minZ <= 10) { + area = new SpawnAreaTile(minX, minZ, RESET_FILE, this); + } else { + area = new PathAreaTile(minX, minZ, this); + } + } + + public PathRegion(RegionConstructorData regionConstructorData) { + super(regionConstructorData); + RegionDataRepository.loadFlagStorage(this, flagStorage); + if (minX >= -28 && minX <= 10 && minZ >= -28 && minZ <= 10) { + area = new SpawnAreaTile(minX, minZ, RESET_FILE, this); + } else { + area = new PathAreaTile(minX, minZ, this); + } + } + + @Override + public void update(DynamicRegion updateFrom) { + if (area instanceof PathAreaTile) { + area.reset(null, false); + } + } + + @Override + public void setFlags(FlagStorage flags) { + } + + @Override + public @NonNull RegionType getType() { + if (area instanceof SpawnAreaTile) { + return RegionType.SPAWN_EXTENSION; + } else { + return RegionType.PATH; + } + } + + @Override + public @NonNull FlagStorage getFlags() { + return flagStorage; + } + + @Override + public @NonNull Area getArea() { + return area; + } + + @Override + public @NonNull Area getBuildArea() { + return Area.EMPTY; + } + + @Override + public @NonNull Area getTestblockArea() { + return Area.EMPTY; + } + + @Override + public @NonNull RegionConfig getGameModeConfig() { + return config; + } + + @Override + public @NonNull RegionHistory getHistory() { + return RegionHistory.EMPTY; + } +} diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/TileArea.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnAreaTile.java similarity index 75% rename from BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/TileArea.java rename to BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnAreaTile.java index 71a11093..dea5cbb5 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/TileArea.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnAreaTile.java @@ -17,19 +17,17 @@ * along with this program. If not, see . */ -package de.steamwar.bausystem.region.dynamic; +package de.steamwar.bausystem.region.dynamic.spawn; -import com.sk89q.worldedit.EditSession; import de.steamwar.bausystem.region.Point; import de.steamwar.bausystem.region.Region; -import de.steamwar.bausystem.region.RegionHistory; import de.steamwar.bausystem.utils.PasteBuilder; import lombok.NonNull; import javax.annotation.Nullable; import java.io.File; -public class TileArea implements Region.Area { +public class SpawnAreaTile implements Region.Area { private final int minX; private final int minZ; @@ -37,9 +35,9 @@ public class TileArea implements Region.Area { private final Point minPoint; private final Point maxPoint; private final Point copyPoint; - private final RegionHistory regionHistory; + private final Region region; - public TileArea(int minX, int minZ, File resetFile, RegionHistory regionHistory) { + public SpawnAreaTile(int minX, int minZ, File resetFile, Region region) { this.minX = minX; this.minZ = minZ; this.resetFile = resetFile; @@ -48,7 +46,7 @@ public class TileArea implements Region.Area { maxPoint = new Point(minX + 18, 255, minZ + 18); copyPoint = new Point(minX + 9, 0, minZ + 9); - this.regionHistory = regionHistory; + this.region = region; } @Override @@ -74,11 +72,6 @@ public class TileArea implements Region.Area { @Override public void reset(PasteBuilder pasteBuilder, boolean extension) { - EditSession editSession = pasteBuilder.with(new PasteBuilder.FileProvider(resetFile)) - .minPoint(minPoint) - .maxPoint(maxPoint) - .pastePoint(minPoint) - .run(); - regionHistory.remember(editSession); + SpawnResetter.reset(region); } } diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnPathRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnPathRegion.java index ab1a537e..2bf50e8c 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnPathRegion.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnPathRegion.java @@ -21,12 +21,22 @@ package de.steamwar.bausystem.region.dynamic.spawn; import de.steamwar.bausystem.region.FlagStorage; import de.steamwar.bausystem.region.RegionConfig; +import de.steamwar.bausystem.region.RegionHistory; import de.steamwar.bausystem.region.RegionType; import de.steamwar.bausystem.region.dynamic.*; import lombok.NonNull; +import org.bukkit.Bukkit; + +import java.io.File; public class SpawnPathRegion extends DynamicRegion { + private static final File SECTIONS_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections"); + private static final File RESET_FILE_NORTH = new File(SECTIONS_DIR, "spawn/SpawnNorth.schem"); + private static final File RESET_FILE_SOUTH = new File(SECTIONS_DIR, "spawn/SpawnSouth.schem"); + private static final File RESET_FILE_WEST = new File(SECTIONS_DIR, "spawn/SpawnWest.schem"); + private static final File RESET_FILE_EAST = new File(SECTIONS_DIR, "spawn/SpawnEast.schem"); + private FlagStorage flagStorage = new NonNormalFlagStorage(); private final Area area; private final RegionConfig config = new RegionConfig(null); @@ -34,13 +44,26 @@ public class SpawnPathRegion extends DynamicRegion { public SpawnPathRegion(int minX, int minZ) { super(minX, minZ); RegionDataRepository.loadFlagStorage(this, flagStorage); - area = new TileArea(minX, minZ, null, history); + area = new SpawnAreaTile(minX, minZ, getResetFile(minX, minZ), this); } public SpawnPathRegion(RegionConstructorData regionConstructorData) { super(regionConstructorData); RegionDataRepository.loadFlagStorage(this, flagStorage); - area = new TileArea(minX, minZ, null, history); + area = new SpawnAreaTile(minX, minZ, getResetFile(minX, minZ), this); + } + + private static File getResetFile(int minX, int minZ) { + if (minX == -28) { + return RESET_FILE_WEST; + } else if (minX == 10) { + return RESET_FILE_EAST; + } else if (minZ == -28) { + return RESET_FILE_NORTH; + } else if (minZ == 10) { + return RESET_FILE_SOUTH; + } + throw new IllegalArgumentException("Invalid minX: " + minX + ", minZ: " + minZ); } @Override @@ -81,4 +104,9 @@ public class SpawnPathRegion extends DynamicRegion { public @NonNull RegionConfig getGameModeConfig() { return config; } + + @Override + public @NonNull RegionHistory getHistory() { + return RegionHistory.EMPTY; + } } diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnRegion.java index d11f602f..321a8602 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnRegion.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnRegion.java @@ -21,12 +21,22 @@ package de.steamwar.bausystem.region.dynamic.spawn; import de.steamwar.bausystem.region.FlagStorage; import de.steamwar.bausystem.region.RegionConfig; +import de.steamwar.bausystem.region.RegionHistory; import de.steamwar.bausystem.region.RegionType; -import de.steamwar.bausystem.region.dynamic.*; +import de.steamwar.bausystem.region.dynamic.DynamicRegion; +import de.steamwar.bausystem.region.dynamic.NonNormalFlagStorage; +import de.steamwar.bausystem.region.dynamic.RegionConstructorData; +import de.steamwar.bausystem.region.dynamic.RegionDataRepository; import lombok.NonNull; +import org.bukkit.Bukkit; + +import java.io.File; public class SpawnRegion extends DynamicRegion { + private static final File SECTIONS_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections"); + private static final File RESET_FILE = new File(SECTIONS_DIR, "spawn/SpawnMiddle.schem"); + private FlagStorage flagStorage = new NonNormalFlagStorage(); private final Area area; private final RegionConfig config = new RegionConfig(null); @@ -34,18 +44,18 @@ public class SpawnRegion extends DynamicRegion { public SpawnRegion(int minX, int minZ) { super(minX, minZ); RegionDataRepository.loadFlagStorage(this, flagStorage); - area = new TileArea(minX, minZ, null, history); + area = new SpawnAreaTile(minX, minZ, RESET_FILE, this); } public SpawnRegion(RegionConstructorData regionConstructorData) { super(regionConstructorData); RegionDataRepository.loadFlagStorage(this, flagStorage); - area = new TileArea(minX, minZ, null, history); + area = new SpawnAreaTile(minX, minZ, RESET_FILE, this); } @Override public void update(DynamicRegion updateFrom) { - // TODO: Implement + SpawnResetter.reset(null); } @Override @@ -81,4 +91,9 @@ public class SpawnRegion extends DynamicRegion { public @NonNull RegionConfig getGameModeConfig() { return config; } + + @Override + public @NonNull RegionHistory getHistory() { + return RegionHistory.EMPTY; + } } diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnResetter.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnResetter.java new file mode 100644 index 00000000..e9d0b218 --- /dev/null +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnResetter.java @@ -0,0 +1,92 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 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.region.dynamic.spawn; + +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.math.BlockVector3; +import de.steamwar.bausystem.region.*; +import de.steamwar.bausystem.utils.FlatteningWrapper; +import lombok.experimental.UtilityClass; +import org.bukkit.Bukkit; +import org.bukkit.Location; + +import java.io.File; +import java.util.List; +import java.util.stream.Collectors; + +@UtilityClass +public class SpawnResetter { + + private static final File SECTIONS_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections"); + private static final File RESET_FILE = new File(SECTIONS_DIR, "spawn/SpawnBig.schem"); + + private static final Location LOCATION = new Location(null, 0, 0, 0); + + public boolean isBigSpawn() { + Region spawnRegion = DynamicRegionSystem.INSTANCE.get(LOCATION); + List neighbours = DynamicRegionSystem.INSTANCE.getNeighbours(spawnRegion) + .filter(r -> r.getType() == RegionType.PATH || r.getType() == RegionType.SPAWN_EXTENSION || r.getType() == RegionType.SPAWN_PATH) + .collect(Collectors.toList()); + return neighbours.size() == 8; + } + + public void reset(Region region) { + Region spawnRegion = DynamicRegionSystem.INSTANCE.get(LOCATION); + List neighbours = DynamicRegionSystem.INSTANCE.getNeighbours(spawnRegion) + .filter(r -> r.getType() == RegionType.PATH || r.getType() == RegionType.SPAWN_EXTENSION || r.getType() == RegionType.SPAWN_PATH) + .collect(Collectors.toList()); + + if (neighbours.size() == 8) { + Region.Area area = spawnRegion.getArea(); + Point minPoint = area.getMinPoint(false).subtract(19, 0, 19); + Clipboard clipboard = FlatteningWrapper.impl.loadSchematic(RESET_FILE); + BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin()); + BlockVector3 to = minPoint.toBlockVector3().subtract(offset); + clipboard.paste(BukkitAdapter.adapt(Bukkit.getWorlds().get(0)), to); + + if (spawnRegion != region) { + RegionUtils.message(spawnRegion, "REGION_RESET_RESETED"); + } + neighbours.forEach(r -> { + if (r != region) { + RegionUtils.message(r, "REGION_RESET_RESETED"); + } + }); + return; + } + + internalReset(spawnRegion, spawnRegion != region); + DynamicRegionSystem.INSTANCE.getNeighbours(spawnRegion) + .forEach(r -> internalReset(r, r != region)); + } + + private void internalReset(Region region, boolean message) { + Region.Area area = region.getArea(); + Point minPoint = area.getMinPoint(false); + Clipboard clipboard = FlatteningWrapper.impl.loadSchematic(area.getResetFile()); + BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin()); + BlockVector3 to = minPoint.toBlockVector3().subtract(offset); + clipboard.paste(BukkitAdapter.adapt(Bukkit.getWorlds().get(0)), to); + if (message) { + RegionUtils.message(region, "REGION_RESET_RESETED"); + } + } +}