forked from SteamWar/SteamWar
Remove stability from VariantSelector
This commit is contained in:
@@ -22,6 +22,7 @@ package de.steamwar.bausystem.region;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
|
||||||
import javax.annotation.CheckReturnValue;
|
import javax.annotation.CheckReturnValue;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@@ -78,9 +79,9 @@ public interface RegionBackups {
|
|||||||
public final void load(RegionData regionData) {
|
public final void load(RegionData regionData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("java:S3038") // This forces everybody to implement 'deleteRegion' for Backups!
|
@SuppressWarnings("java:S3038") // This forces everybody to implement 'delete' for Backups!
|
||||||
@Override
|
@Override
|
||||||
public abstract void delete();
|
public abstract void delete(Location location);
|
||||||
}
|
}
|
||||||
|
|
||||||
@CheckReturnValue
|
@CheckReturnValue
|
||||||
|
|||||||
@@ -19,9 +19,11 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.region;
|
package de.steamwar.bausystem.region;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
|
||||||
public interface RegionDataStore {
|
public interface RegionDataStore {
|
||||||
void save();
|
void save();
|
||||||
void load(RegionData regionData);
|
void load(RegionData regionData);
|
||||||
default void delete() {
|
default void delete(Location location) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -174,7 +174,7 @@ public class DynamicRegionVisualizer implements SWPlayer.Component, Listener {
|
|||||||
player.closeInventory();
|
player.closeInventory();
|
||||||
Region region = DynamicRegionSystem.INSTANCE.get(tile);
|
Region region = DynamicRegionSystem.INSTANCE.get(tile);
|
||||||
Set<Tile> tiles = DynamicRegionSystem.INSTANCE.getTilesOfRegion(region);
|
Set<Tile> tiles = DynamicRegionSystem.INSTANCE.getTilesOfRegion(region);
|
||||||
region.delete();
|
region.delete(tile.getCenterLocation());
|
||||||
|
|
||||||
SWPlayer.allWithSingleComponent(DynamicRegionVisualizer.class)
|
SWPlayer.allWithSingleComponent(DynamicRegionVisualizer.class)
|
||||||
.forEach(pair -> {
|
.forEach(pair -> {
|
||||||
|
|||||||
+2
-1
@@ -27,6 +27,7 @@ import de.steamwar.bausystem.region.dynamic.path.PathRegion;
|
|||||||
import de.steamwar.bausystem.shared.Pair;
|
import de.steamwar.bausystem.shared.Pair;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -98,7 +99,7 @@ public abstract class DynamicRegion implements Region {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete(Location location) {
|
||||||
if (!getType().isDeletable()) return;
|
if (!getType().isDeletable()) return;
|
||||||
DynamicRegionSystem.INSTANCE.remove(this);
|
DynamicRegionSystem.INSTANCE.remove(this);
|
||||||
DynamicRegionRepository.deleteRegion(this);
|
DynamicRegionRepository.deleteRegion(this);
|
||||||
|
|||||||
+8
-1
@@ -32,7 +32,14 @@ import java.util.function.BiConsumer;
|
|||||||
|
|
||||||
public abstract class MultiTileArea implements Region.Area {
|
public abstract class MultiTileArea implements Region.Area {
|
||||||
|
|
||||||
private final Set<Tile> tiles = new HashSet<>();
|
protected final Set<Tile> tiles = new HashSet<>();
|
||||||
|
|
||||||
|
protected MultiTileArea() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MultiTileArea(Set<Tile> initialTiles) {
|
||||||
|
tiles.addAll(initialTiles);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean addTile(Tile tile) {
|
public boolean addTile(Tile tile) {
|
||||||
boolean result = tiles.add(tile);
|
boolean result = tiles.add(tile);
|
||||||
|
|||||||
+12
-10
@@ -24,14 +24,17 @@ import lombok.NonNull;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.Month;
|
import java.time.Month;
|
||||||
import java.util.*;
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
public abstract class VariantSelector {
|
public abstract class VariantSelector {
|
||||||
|
|
||||||
private static final Random RANDOM = new Random();
|
private static final Random RANDOM = new Random();
|
||||||
public static final VariantSelector EMPTY = new VariantSelector() {
|
public static final VariantSelector EMPTY = new VariantSelector() {
|
||||||
@Override
|
@Override
|
||||||
public Optional<File> select(UUID regionID, int drift) {
|
public Optional<File> select() {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -39,15 +42,15 @@ public abstract class VariantSelector {
|
|||||||
private VariantSelector() {
|
private VariantSelector() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Optional<File> select(UUID regionID, int drift);
|
public abstract Optional<File> select();
|
||||||
|
|
||||||
public final VariantSelector or(VariantSelector other) {
|
public final VariantSelector or(VariantSelector other) {
|
||||||
if (this == EMPTY) return other;
|
if (this == EMPTY) return other;
|
||||||
VariantSelector self = this;
|
VariantSelector self = this;
|
||||||
return new VariantSelector() {
|
return new VariantSelector() {
|
||||||
@Override
|
@Override
|
||||||
public Optional<File> select(UUID regionID, int drift) {
|
public Optional<File> select() {
|
||||||
return self.select(regionID, drift).or(() -> other.select(regionID, drift));
|
return self.select().or(() -> other.select());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -57,10 +60,10 @@ public abstract class VariantSelector {
|
|||||||
VariantSelector self = this;
|
VariantSelector self = this;
|
||||||
return new VariantSelector() {
|
return new VariantSelector() {
|
||||||
@Override
|
@Override
|
||||||
public Optional<File> select(UUID regionID, int drift) {
|
public Optional<File> select() {
|
||||||
LocalDate date = LocalDate.now();
|
LocalDate date = LocalDate.now();
|
||||||
if (date.getDayOfMonth() == day && date.getMonth() == month) {
|
if (date.getDayOfMonth() == day && date.getMonth() == month) {
|
||||||
return self.select(regionID, drift);
|
return self.select();
|
||||||
} else {
|
} else {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
@@ -75,7 +78,7 @@ public abstract class VariantSelector {
|
|||||||
final File file = files[0];
|
final File file = files[0];
|
||||||
return new VariantSelector() {
|
return new VariantSelector() {
|
||||||
@Override
|
@Override
|
||||||
public Optional<File> select(UUID regionID, int drift) {
|
public Optional<File> select() {
|
||||||
return Optional.of(file);
|
return Optional.of(file);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -85,8 +88,7 @@ public abstract class VariantSelector {
|
|||||||
final int filesCount = files.length;
|
final int filesCount = files.length;
|
||||||
return new VariantSelector() {
|
return new VariantSelector() {
|
||||||
@Override
|
@Override
|
||||||
public Optional<File> select(UUID regionID, int drift) {
|
public Optional<File> select() {
|
||||||
RANDOM.setSeed(regionID.getLeastSignificantBits() ^ regionID.getMostSignificantBits() ^ drift);
|
|
||||||
return Optional.of(files[RANDOM.nextInt(filesCount)]);
|
return Optional.of(files[RANDOM.nextInt(filesCount)]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+1
-1
@@ -162,7 +162,7 @@ public class AreaBlock implements Region.Area {
|
|||||||
@Override
|
@Override
|
||||||
public void place(Location location, PasteBuilder pasteBuilder, boolean extension) {
|
public void place(Location location, PasteBuilder pasteBuilder, boolean extension) {
|
||||||
EditSession editSession = pasteBuilder
|
EditSession editSession = pasteBuilder
|
||||||
.with(PasteBuilder.ClipboardProvider.file(selector.select(region.getID(), 0).orElse(null)))
|
.with(PasteBuilder.ClipboardProvider.file(selector.select().orElse(null)))
|
||||||
.pastePoint(copyPoint)
|
.pastePoint(copyPoint)
|
||||||
.run();
|
.run();
|
||||||
region.getHistory()
|
region.getHistory()
|
||||||
|
|||||||
+1
-1
@@ -67,7 +67,7 @@ public class AreaTile implements Region.Area {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void place(Location location, PasteBuilder pasteBuilder, boolean extension) {
|
public void place(Location location, PasteBuilder pasteBuilder, boolean extension) {
|
||||||
File resetFile = selector.select(regionIdentifier, 0).orElse(null);
|
File resetFile = selector.select().orElse(null);
|
||||||
if (resetFile != null) PasteUtils.paste(resetFile, minPoint, 0);
|
if (resetFile != null) PasteUtils.paste(resetFile, minPoint, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -30,6 +30,7 @@ import de.steamwar.bausystem.region.dynamic.DynamicRegionRepository;
|
|||||||
import de.steamwar.bausystem.region.dynamic.PasteUtils;
|
import de.steamwar.bausystem.region.dynamic.PasteUtils;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -75,7 +76,7 @@ public class PlotRegionBackups implements RegionBackups {
|
|||||||
// Cleanup backups if there are too many!
|
// Cleanup backups if there are too many!
|
||||||
backupList.sort(Backup::compareTo);
|
backupList.sort(Backup::compareTo);
|
||||||
while (backupList.size() >= backupType.maxBackups) {
|
while (backupList.size() >= backupType.maxBackups) {
|
||||||
backupList.removeFirst().delete();
|
backupList.removeFirst().delete(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create backup and save!
|
// Create backup and save!
|
||||||
@@ -148,7 +149,7 @@ public class PlotRegionBackups implements RegionBackups {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete(Location location) {
|
||||||
backups.getOrDefault(type, Collections.emptyList())
|
backups.getOrDefault(type, Collections.emptyList())
|
||||||
.remove(this);
|
.remove(this);
|
||||||
DynamicRegionRepository.deleteBackup(region, this);
|
DynamicRegionRepository.deleteBackup(region, this);
|
||||||
|
|||||||
+4
-10
@@ -111,12 +111,6 @@ public class PathArea implements Region.Area {
|
|||||||
.Case(Path, Path, Garden, CORNER_INNER_GARDEN, RotationCorrection.UsingOrdinal)
|
.Case(Path, Path, Garden, CORNER_INNER_GARDEN, RotationCorrection.UsingOrdinal)
|
||||||
;
|
;
|
||||||
|
|
||||||
protected enum RotationCorrection {
|
|
||||||
Unchanged,
|
|
||||||
WithCorrection,
|
|
||||||
UsingOrdinal,
|
|
||||||
}
|
|
||||||
|
|
||||||
private final PathRegion region;
|
private final PathRegion region;
|
||||||
private final UUID regionIdentifier;
|
private final UUID regionIdentifier;
|
||||||
private final Tile tile;
|
private final Tile tile;
|
||||||
@@ -177,7 +171,7 @@ public class PathArea implements Region.Area {
|
|||||||
public void reset(PathSide side) {
|
public void reset(PathSide side) {
|
||||||
File resetFile = null;
|
File resetFile = null;
|
||||||
VariantSelector selector = SELECTOR_SIDE.Select(tile, side);
|
VariantSelector selector = SELECTOR_SIDE.Select(tile, side);
|
||||||
if (selector != null) resetFile = selector.select(regionIdentifier, side.ordinal() + side.rotate).orElse(null);
|
if (selector != null) resetFile = selector.select().orElse(null);
|
||||||
if (selector == null || resetFile == null) {
|
if (selector == null || resetFile == null) {
|
||||||
if (!BauSystem.DEV_SERVER) return;
|
if (!BauSystem.DEV_SERVER) return;
|
||||||
resetFile = FALLBACK_SCHEM;
|
resetFile = FALLBACK_SCHEM;
|
||||||
@@ -191,7 +185,7 @@ public class PathArea implements Region.Area {
|
|||||||
Pair<VariantSelector, RotationCorrection> pair = SELECTOR_CORNER.Select(tile, corner);
|
Pair<VariantSelector, RotationCorrection> pair = SELECTOR_CORNER.Select(tile, corner);
|
||||||
VariantSelector selector = pair.getKey();
|
VariantSelector selector = pair.getKey();
|
||||||
RotationCorrection rotationCorrection = pair.getValue();
|
RotationCorrection rotationCorrection = pair.getValue();
|
||||||
if (selector != null) resetFile = selector.select(regionIdentifier, corner.side1.ordinal() * corner.side2.ordinal() + corner.side1.rotate * corner.side2.rotate).orElse(null);
|
if (selector != null) resetFile = selector.select().orElse(null);
|
||||||
if (selector == null || resetFile == null) {
|
if (selector == null || resetFile == null) {
|
||||||
if (!BauSystem.DEV_SERVER) return;
|
if (!BauSystem.DEV_SERVER) return;
|
||||||
resetFile = FALLBACK_SCHEM;
|
resetFile = FALLBACK_SCHEM;
|
||||||
@@ -216,14 +210,14 @@ public class PathArea implements Region.Area {
|
|||||||
@Override
|
@Override
|
||||||
public void place(Location location, PasteBuilder pasteBuilder, boolean extension) {
|
public void place(Location location, PasteBuilder pasteBuilder, boolean extension) {
|
||||||
if (region.isGarden()) {
|
if (region.isGarden()) {
|
||||||
File resetFile = GARDEN.select(regionIdentifier, 0).orElse(null);
|
File resetFile = GARDEN.select().orElse(null);
|
||||||
if (resetFile != null) {
|
if (resetFile != null) {
|
||||||
PasteUtils.paste(resetFile, minPoint, 0);
|
PasteUtils.paste(resetFile, minPoint, 0);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
File resetFile = CENTER_NORMAL.select(regionIdentifier, 0).orElse(null);
|
File resetFile = CENTER_NORMAL.select().orElse(null);
|
||||||
if (resetFile != null) {
|
if (resetFile != null) {
|
||||||
PasteUtils.paste(resetFile, minPoint.add(7, 0, 7), 0);
|
PasteUtils.paste(resetFile, minPoint.add(7, 0, 7), 0);
|
||||||
}
|
}
|
||||||
|
|||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
public enum RotationCorrection {
|
||||||
|
Unchanged,
|
||||||
|
WithCorrection,
|
||||||
|
UsingOrdinal,
|
||||||
|
}
|
||||||
+5
-5
@@ -24,7 +24,7 @@ import de.steamwar.bausystem.region.dynamic.Tile;
|
|||||||
import de.steamwar.bausystem.region.dynamic.VariantSelector;
|
import de.steamwar.bausystem.region.dynamic.VariantSelector;
|
||||||
import de.steamwar.bausystem.shared.Pair;
|
import de.steamwar.bausystem.shared.Pair;
|
||||||
|
|
||||||
class SelectorCorner {
|
public class SelectorCorner {
|
||||||
|
|
||||||
private static final int BITS;
|
private static final int BITS;
|
||||||
private static final int SELECTOR_COUNT;
|
private static final int SELECTOR_COUNT;
|
||||||
@@ -36,7 +36,7 @@ class SelectorCorner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private VariantSelector[] selectors = new VariantSelector[SELECTOR_COUNT];
|
private VariantSelector[] selectors = new VariantSelector[SELECTOR_COUNT];
|
||||||
private PathArea.RotationCorrection[] rotationCorrections = new PathArea.RotationCorrection[SELECTOR_COUNT];
|
private RotationCorrection[] rotationCorrections = new RotationCorrection[SELECTOR_COUNT];
|
||||||
|
|
||||||
private int getIndex(RegionType.ConnectionType left, RegionType.ConnectionType right, RegionType.ConnectionType diagonal) {
|
private int getIndex(RegionType.ConnectionType left, RegionType.ConnectionType right, RegionType.ConnectionType diagonal) {
|
||||||
int index = left.ordinal();
|
int index = left.ordinal();
|
||||||
@@ -47,18 +47,18 @@ class SelectorCorner {
|
|||||||
public SelectorCorner Case(RegionType.ConnectionType left, RegionType.ConnectionType right, RegionType.ConnectionType diagonal, VariantSelector selector) {
|
public SelectorCorner Case(RegionType.ConnectionType left, RegionType.ConnectionType right, RegionType.ConnectionType diagonal, VariantSelector selector) {
|
||||||
int index = getIndex(left, right, diagonal);
|
int index = getIndex(left, right, diagonal);
|
||||||
selectors[index] = selector;
|
selectors[index] = selector;
|
||||||
rotationCorrections[index] = PathArea.RotationCorrection.Unchanged;
|
rotationCorrections[index] = RotationCorrection.Unchanged;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SelectorCorner Case(RegionType.ConnectionType left, RegionType.ConnectionType right, RegionType.ConnectionType diagonal, VariantSelector selector, PathArea.RotationCorrection rotationCorrection) {
|
public SelectorCorner Case(RegionType.ConnectionType left, RegionType.ConnectionType right, RegionType.ConnectionType diagonal, VariantSelector selector, RotationCorrection rotationCorrection) {
|
||||||
int index = getIndex(left, right, diagonal);
|
int index = getIndex(left, right, diagonal);
|
||||||
selectors[index] = selector;
|
selectors[index] = selector;
|
||||||
rotationCorrections[index] = rotationCorrection;
|
rotationCorrections[index] = rotationCorrection;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<VariantSelector, PathArea.RotationCorrection> Select(Tile tile, PathCorner corner) {
|
public Pair<VariantSelector, RotationCorrection> Select(Tile tile, PathCorner corner) {
|
||||||
RegionType.ConnectionType left = PathArea.getConnectionType(tile, corner.side1, null);
|
RegionType.ConnectionType left = PathArea.getConnectionType(tile, corner.side1, null);
|
||||||
RegionType.ConnectionType right = PathArea.getConnectionType(tile, corner.side2, null);
|
RegionType.ConnectionType right = PathArea.getConnectionType(tile, corner.side2, null);
|
||||||
RegionType.ConnectionType diagonal = PathArea.getConnectionType(tile, corner.side1, corner.side2);
|
RegionType.ConnectionType diagonal = PathArea.getConnectionType(tile, corner.side1, corner.side2);
|
||||||
|
|||||||
+2
-2
@@ -23,11 +23,11 @@ import de.steamwar.bausystem.region.RegionType;
|
|||||||
import de.steamwar.bausystem.region.dynamic.Tile;
|
import de.steamwar.bausystem.region.dynamic.Tile;
|
||||||
import de.steamwar.bausystem.region.dynamic.VariantSelector;
|
import de.steamwar.bausystem.region.dynamic.VariantSelector;
|
||||||
|
|
||||||
class SelectorSide {
|
public class SelectorSide {
|
||||||
|
|
||||||
private VariantSelector[] selectors = new VariantSelector[RegionType.ConnectionType.values().length];
|
private VariantSelector[] selectors = new VariantSelector[RegionType.ConnectionType.values().length];
|
||||||
|
|
||||||
protected SelectorSide Case(RegionType.ConnectionType type, VariantSelector selector) {
|
public SelectorSide Case(RegionType.ConnectionType type, VariantSelector selector) {
|
||||||
selectors[type.ordinal()] = selector;
|
selectors[type.ordinal()] = selector;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -105,7 +105,7 @@ public class SpecialArea implements Region.Area {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void place(Location location, PasteBuilder pasteBuilder, boolean extension) {
|
public void place(Location location, PasteBuilder pasteBuilder, boolean extension) {
|
||||||
File resetFile = resetFiles.select(regionIdentifier, 0).orElse(null);
|
File resetFile = resetFiles.select().orElse(null);
|
||||||
if (resetFile != null) PasteUtils.paste(resetFile, minPoint, 0);
|
if (resetFile != null) PasteUtils.paste(resetFile, minPoint, 0);
|
||||||
resetting = false;
|
resetting = false;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -139,7 +139,7 @@ public class FixedRegion implements Region {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete(Location location) {
|
||||||
file.delete();
|
file.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user