forked from SteamWar/SteamWar
Add CornerInnerGlobal and CornerOuterGlobal
Improve the selecting code
This commit is contained in:
+1
-11
@@ -71,17 +71,7 @@ public abstract class DynamicRegion implements Region {
|
||||
|
||||
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();
|
||||
PasteUtils.reset(minPoint, maxPoint);
|
||||
|
||||
DynamicRegionSystem.INSTANCE.getNeighbours(this).collect(Collectors.toList())
|
||||
.forEach(r -> r.update(this));
|
||||
|
||||
+17
@@ -19,10 +19,14 @@
|
||||
|
||||
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.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import de.steamwar.bausystem.region.Point;
|
||||
import de.steamwar.bausystem.utils.FlatteningWrapper;
|
||||
import lombok.experimental.UtilityClass;
|
||||
@@ -33,6 +37,19 @@ import java.io.File;
|
||||
@UtilityClass
|
||||
public class PasteUtils {
|
||||
|
||||
public static void reset(Point minPoint, Point maxPoint) {
|
||||
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();
|
||||
}
|
||||
|
||||
public static void paste(File file, Point minPoint, int rotate) {
|
||||
Clipboard clipboard = FlatteningWrapper.impl.loadSchematic(file);
|
||||
BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
|
||||
|
||||
+53
-72
@@ -26,6 +26,7 @@ import de.steamwar.bausystem.region.RegionType;
|
||||
import de.steamwar.bausystem.region.dynamic.PasteUtils;
|
||||
import de.steamwar.bausystem.region.dynamic.Tile;
|
||||
import de.steamwar.bausystem.region.dynamic.VariantSelector;
|
||||
import de.steamwar.bausystem.shared.Pair;
|
||||
import de.steamwar.bausystem.utils.PasteBuilder;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -36,15 +37,34 @@ import java.io.File;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static de.steamwar.bausystem.region.RegionType.ConnectionType.Global;
|
||||
import static de.steamwar.bausystem.region.RegionType.ConnectionType.Path;
|
||||
|
||||
public class PathArea implements Region.Area {
|
||||
|
||||
private static final File PATH_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections/path");
|
||||
|
||||
private static final VariantSelector CENTER_NORMAL = VariantSelector.Get(new File(PATH_DIR, "center/normal"));
|
||||
private static final VariantSelector SIDE_GLOBAL = VariantSelector.Get(new File(PATH_DIR, "side/global"));
|
||||
private static final VariantSelector CORNER_INNER_GLOBAL = VariantSelector.Get(new File(PATH_DIR, "cinner/global"));
|
||||
private static final VariantSelector CORNER_OUTER_GLOBAL = VariantSelector.Get(new File(PATH_DIR, "couter/global"));
|
||||
|
||||
private static final SelectorSide SELECTOR_SIDE = new SelectorSide()
|
||||
.Case(Path, CENTER_NORMAL)
|
||||
.Case(Global, SIDE_GLOBAL);
|
||||
|
||||
private static final SelectorCorner SELECTOR_CORNER = new SelectorCorner()
|
||||
.Case(Path, Global, Global, SIDE_GLOBAL, RotationCorrection.WithCorrection)
|
||||
.Case(Global, Path, Path, SIDE_GLOBAL)
|
||||
.Case(Global, Path, Global, SIDE_GLOBAL)
|
||||
.Case(Path, Global, Path, SIDE_GLOBAL, RotationCorrection.WithCorrection)
|
||||
.Case(Path, Path, Path, CENTER_NORMAL, RotationCorrection.UsingOrdinal)
|
||||
.Case(Global, Global, Global, CORNER_OUTER_GLOBAL, RotationCorrection.UsingOrdinal)
|
||||
.Case(Path, Path, Global, CORNER_INNER_GLOBAL, RotationCorrection.UsingOrdinal)
|
||||
;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
private enum Side {
|
||||
protected enum Side {
|
||||
North(0, -1, 7, 0, 0),
|
||||
South(0, 1, 7, 14, 180),
|
||||
West(-1, 0, 0, 7, 90),
|
||||
@@ -59,21 +79,27 @@ public class PathArea implements Region.Area {
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
private enum Corner {
|
||||
protected enum Corner {
|
||||
NorthEast(Side.North, Side.East, 14, 0, 0, -90),
|
||||
NorthWest(Side.North, Side.West, 0, 0, 0, 90),
|
||||
SouthEast(Side.South, Side.East, 14, 14, 180, 90),
|
||||
SouthWest(Side.South, Side.West, 0, 14, 180, -90),
|
||||
;
|
||||
|
||||
private final Side side1;
|
||||
private final Side side2;
|
||||
protected final Side side1;
|
||||
protected final Side side2;
|
||||
private final int pasteOffsetX;
|
||||
private final int pasteOffsetZ;
|
||||
private final int rotate;
|
||||
private final int rotateCorrection;
|
||||
}
|
||||
|
||||
protected enum RotationCorrection {
|
||||
Unchanged,
|
||||
WithCorrection,
|
||||
UsingOrdinal,
|
||||
}
|
||||
|
||||
private final UUID regionIdentifier;
|
||||
private final Tile tile;
|
||||
private final Point minPoint;
|
||||
@@ -121,79 +147,34 @@ public class PathArea implements Region.Area {
|
||||
}
|
||||
|
||||
for (Side side : Side.values()) {
|
||||
RegionType.ConnectionType connectionType = getConnectionType(side, null);
|
||||
|
||||
VariantSelector selector = switch (connectionType) {
|
||||
case Path -> CENTER_NORMAL;
|
||||
case Water -> null;
|
||||
case Closed -> null;
|
||||
case Global -> SIDE_GLOBAL;
|
||||
};
|
||||
if (selector == null) {
|
||||
continue;
|
||||
}
|
||||
VariantSelector selector = SELECTOR_SIDE.Select(tile, side);
|
||||
if (selector == null) continue;
|
||||
|
||||
resetFile = selector.select(regionIdentifier, side.ordinal() + side.rotate).orElse(null);
|
||||
if (resetFile == null) {
|
||||
continue;
|
||||
}
|
||||
if (resetFile == null) continue;
|
||||
|
||||
PasteUtils.paste(resetFile, minPoint.add(side.pasteOffsetX, 0, side.pasteOffsetZ), side.rotate);
|
||||
}
|
||||
|
||||
for (Corner corner : Corner.values()) {
|
||||
RegionType.ConnectionType connectionType1 = getConnectionType(corner.side1, null);
|
||||
RegionType.ConnectionType connectionType2 = getConnectionType(corner.side2, null);
|
||||
RegionType.ConnectionType connectionType3 = getConnectionType(corner.side1, corner.side2);
|
||||
|
||||
VariantSelector selector = null;
|
||||
int rotate = corner.rotate;
|
||||
if (connectionType1 == RegionType.ConnectionType.Path && connectionType2 == connectionType3) {
|
||||
selector = switch (connectionType2) {
|
||||
case Global -> SIDE_GLOBAL;
|
||||
case Closed -> null;
|
||||
case Water -> null;
|
||||
case Path -> null;
|
||||
};
|
||||
rotate += corner.rotateCorrection;
|
||||
}
|
||||
if (connectionType1 == RegionType.ConnectionType.Global && connectionType2 == connectionType3) {
|
||||
selector = switch (connectionType2) {
|
||||
case Global -> null;
|
||||
case Closed -> null;
|
||||
case Water -> null;
|
||||
case Path -> SIDE_GLOBAL;
|
||||
};
|
||||
}
|
||||
|
||||
if (connectionType2 == RegionType.ConnectionType.Path && connectionType1 == connectionType3) {
|
||||
selector = switch (connectionType1) {
|
||||
case Global -> SIDE_GLOBAL;
|
||||
case Closed -> null;
|
||||
case Water -> null;
|
||||
case Path -> null;
|
||||
};
|
||||
}
|
||||
if (connectionType2 == RegionType.ConnectionType.Global && connectionType1 == connectionType3) {
|
||||
selector = switch (connectionType1) {
|
||||
case Global -> null;
|
||||
case Closed -> null;
|
||||
case Water -> null;
|
||||
case Path -> SIDE_GLOBAL;
|
||||
};
|
||||
rotate += corner.rotateCorrection;
|
||||
}
|
||||
if (connectionType1 == RegionType.ConnectionType.Path && connectionType1 == connectionType2 && connectionType1 == connectionType3) {
|
||||
selector = CENTER_NORMAL;
|
||||
rotate = 90 * corner.ordinal();
|
||||
}
|
||||
if (selector == null) {
|
||||
continue;
|
||||
}
|
||||
Pair<VariantSelector, RotationCorrection> pair = SELECTOR_CORNER.Select(tile, corner);
|
||||
VariantSelector selector = pair.getKey();
|
||||
if (selector == null) continue;
|
||||
RotationCorrection rotationCorrection = pair.getValue();
|
||||
|
||||
resetFile = selector.select(regionIdentifier, corner.side1.ordinal() * corner.side2.ordinal() + corner.side1.rotate * corner.side2.rotate).orElse(null);
|
||||
if (resetFile == null) {
|
||||
continue;
|
||||
if (resetFile == null) continue;
|
||||
|
||||
int rotate = corner.rotate;
|
||||
switch (rotationCorrection) {
|
||||
case Unchanged:
|
||||
break;
|
||||
case UsingOrdinal:
|
||||
rotate = corner.ordinal() * 90;
|
||||
break;
|
||||
case WithCorrection:
|
||||
rotate += corner.rotateCorrection;
|
||||
break;
|
||||
}
|
||||
|
||||
PasteUtils.paste(resetFile, minPoint.add(corner.pasteOffsetX, 0, corner.pasteOffsetZ), rotate);
|
||||
@@ -216,12 +197,12 @@ public class PathArea implements Region.Area {
|
||||
return true;
|
||||
}
|
||||
|
||||
private RegionType.ConnectionType getConnectionType(Side side, Side optionalSide) {
|
||||
Optional<Tile> optionalTile = this.tile.add(side.tileOffsetX, side.tileOffsetZ);
|
||||
protected static RegionType.ConnectionType getConnectionType(Tile tile, Side side, Side optionalSide) {
|
||||
Optional<Tile> optionalTile = tile.add(side.tileOffsetX, side.tileOffsetZ);
|
||||
if (optionalSide != null) {
|
||||
optionalTile = optionalTile.flatMap(tile -> tile.add(optionalSide.tileOffsetX, optionalSide.tileOffsetZ));
|
||||
optionalTile = optionalTile.flatMap(t -> t.add(optionalSide.tileOffsetX, optionalSide.tileOffsetZ));
|
||||
}
|
||||
return optionalTile.map(tile -> DynamicRegionSystem.INSTANCE.get(tile.getCenterLocation()).getType().getConnectionType())
|
||||
return optionalTile.map(t -> DynamicRegionSystem.INSTANCE.get(t.getCenterLocation()).getType().getConnectionType())
|
||||
.orElse(RegionType.ConnectionType.Global);
|
||||
}
|
||||
}
|
||||
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2026 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.region.dynamic.path;
|
||||
|
||||
import de.steamwar.bausystem.region.RegionType;
|
||||
import de.steamwar.bausystem.region.dynamic.Tile;
|
||||
import de.steamwar.bausystem.region.dynamic.VariantSelector;
|
||||
import de.steamwar.bausystem.shared.Pair;
|
||||
|
||||
class SelectorCorner {
|
||||
|
||||
private static final int BITS;
|
||||
private static final int SELECTOR_COUNT;
|
||||
|
||||
static {
|
||||
int values = RegionType.ConnectionType.values().length;
|
||||
BITS = (int) (Math.log(values) / Math.log(2));
|
||||
SELECTOR_COUNT = (int) Math.pow(2, BITS * 3);
|
||||
}
|
||||
|
||||
private VariantSelector[] selectors = new VariantSelector[SELECTOR_COUNT];
|
||||
private PathArea.RotationCorrection[] rotationCorrections = new PathArea.RotationCorrection[SELECTOR_COUNT];
|
||||
|
||||
private int getIndex(RegionType.ConnectionType left, RegionType.ConnectionType right, RegionType.ConnectionType diagonal) {
|
||||
int index = left.ordinal();
|
||||
index = index << BITS | right.ordinal();
|
||||
return index << BITS | diagonal.ordinal();
|
||||
}
|
||||
|
||||
public SelectorCorner Case(RegionType.ConnectionType left, RegionType.ConnectionType right, RegionType.ConnectionType diagonal, VariantSelector selector) {
|
||||
int index = getIndex(left, right, diagonal);
|
||||
selectors[index] = selector;
|
||||
rotationCorrections[index] = PathArea.RotationCorrection.Unchanged;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectorCorner Case(RegionType.ConnectionType left, RegionType.ConnectionType right, RegionType.ConnectionType diagonal, VariantSelector selector, PathArea.RotationCorrection rotationCorrection) {
|
||||
int index = getIndex(left, right, diagonal);
|
||||
selectors[index] = selector;
|
||||
rotationCorrections[index] = rotationCorrection;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Pair<VariantSelector, PathArea.RotationCorrection> Select(Tile tile, PathArea.Corner corner) {
|
||||
RegionType.ConnectionType left = PathArea.getConnectionType(tile, corner.side1, null);
|
||||
RegionType.ConnectionType right = PathArea.getConnectionType(tile, corner.side2, null);
|
||||
RegionType.ConnectionType diagonal = PathArea.getConnectionType(tile, corner.side1, corner.side2);
|
||||
int index = getIndex(left, right, diagonal);
|
||||
return new Pair<>(selectors[index], rotationCorrections[index]);
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2026 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.region.dynamic.path;
|
||||
|
||||
import de.steamwar.bausystem.region.RegionType;
|
||||
import de.steamwar.bausystem.region.dynamic.Tile;
|
||||
import de.steamwar.bausystem.region.dynamic.VariantSelector;
|
||||
|
||||
class SelectorSide {
|
||||
|
||||
private VariantSelector[] selectors = new VariantSelector[RegionType.ConnectionType.values().length];
|
||||
|
||||
protected SelectorSide Case(RegionType.ConnectionType type, VariantSelector selector) {
|
||||
selectors[type.ordinal()] = selector;
|
||||
return this;
|
||||
}
|
||||
|
||||
public VariantSelector Select(Tile tile, PathArea.Side side) {
|
||||
RegionType.ConnectionType type = PathArea.getConnectionType(tile, side, null);
|
||||
return selectors[type.ordinal()];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user