forked from SteamWar/SteamWar
Improve update propagation performance
This commit is contained in:
+1
-1
@@ -53,7 +53,7 @@ public class DynamicRegionCommand extends SWCommand {
|
|||||||
|
|
||||||
dynamicRegion.getArea().reset(new PasteBuilder(new PasteBuilder.FileProvider(dynamicRegion.getArea().getResetFile())), false);
|
dynamicRegion.getArea().reset(new PasteBuilder(new PasteBuilder.FileProvider(dynamicRegion.getArea().getResetFile())), false);
|
||||||
// TODO: This here still has some kind of error!aww
|
// TODO: This here still has some kind of error!aww
|
||||||
DynamicRegionSystem.INSTANCE.getNeighbours(dynamicRegion).forEach(r -> r.update(dynamicRegion));
|
dynamicRegion.updateNeighbours();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register({"dynamic", "delete"})
|
@Register({"dynamic", "delete"})
|
||||||
|
|||||||
+28
-16
@@ -20,12 +20,11 @@
|
|||||||
package de.steamwar.bausystem.region;
|
package de.steamwar.bausystem.region;
|
||||||
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.region.dynamic.DynamicRegion;
|
import de.steamwar.bausystem.region.dynamic.*;
|
||||||
import de.steamwar.bausystem.region.dynamic.DynamicRegionRepository;
|
|
||||||
import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
|
|
||||||
import de.steamwar.bausystem.region.dynamic.Tile;
|
|
||||||
import de.steamwar.bausystem.region.dynamic.global.GlobalRegion;
|
import de.steamwar.bausystem.region.dynamic.global.GlobalRegion;
|
||||||
|
import de.steamwar.bausystem.shared.Pair;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@@ -92,7 +91,7 @@ public class DynamicRegionSystem implements RegionSystem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull Location getWorldSpawn() {
|
public @NonNull Location getWorldSpawn() {
|
||||||
return null;
|
return Bukkit.getWorlds().get(0).getSpawnLocation(); // TODO: Temporary
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -139,29 +138,40 @@ public class DynamicRegionSystem implements RegionSystem {
|
|||||||
return regionMap.values().stream();
|
return regionMap.values().stream();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stream<Region> getNeighbours(Region region, boolean noCorners, boolean fastCache, Collection<Region> regions) {
|
private Stream<Pair<Region, NeighbourDirection>> getNeighbours(Region region, boolean noCorners, boolean fastCache, Collection<Region> regions) {
|
||||||
Point minPoint = region.getArea().getMinPoint(false).subtract(TILE_SIZE_ADJUSTED, 0, TILE_SIZE_ADJUSTED);
|
Point minPoint = region.getArea().getMinPoint(false).subtract(TILE_SIZE_ADJUSTED, 0, TILE_SIZE_ADJUSTED);
|
||||||
Point maxPoint = region.getArea().getMaxPoint(false).add(Tile.tileSize, 0, Tile.tileSize);
|
Point maxPoint = region.getArea().getMaxPoint(false).add(Tile.tileSize, 0, Tile.tileSize);
|
||||||
Set<Region> neighbours = new HashSet<>();
|
Set<Pair<Region, NeighbourDirection>> neighbours = new HashSet<>();
|
||||||
|
|
||||||
for (int x = minPoint.getX() + (noCorners ? TILE_SIZE_ADJUSTED : 0); x <= maxPoint.getX() - (noCorners ? Tile.tileSize : 0); x += Tile.tileSize) {
|
for (int x = minPoint.getX() + (noCorners ? TILE_SIZE_ADJUSTED : 0); x <= maxPoint.getX() - (noCorners ? Tile.tileSize : 0); x += Tile.tileSize) {
|
||||||
neighbours.add(get(x, minPoint.getZ(), fastCache, regions));
|
NeighbourDirection minZ = NeighbourDirection.North;
|
||||||
neighbours.add(get(x, maxPoint.getZ(), fastCache, regions));
|
if (!noCorners) {
|
||||||
|
if (x == minPoint.getX()) minZ = NeighbourDirection.NorthWest;
|
||||||
|
if (x > maxPoint.getX() - TILE_SIZE_ADJUSTED) minZ = NeighbourDirection.NorthEast;
|
||||||
|
}
|
||||||
|
neighbours.add(new Pair<>(get(x, minPoint.getZ(), fastCache, regions), minZ));
|
||||||
|
|
||||||
|
NeighbourDirection maxZ = NeighbourDirection.South;
|
||||||
|
if (!noCorners) {
|
||||||
|
if (x == minPoint.getX()) maxZ = NeighbourDirection.SouthWest;
|
||||||
|
if (x > maxPoint.getX() - TILE_SIZE_ADJUSTED) maxZ = NeighbourDirection.SouthEast;
|
||||||
|
}
|
||||||
|
neighbours.add(new Pair<>(get(x, maxPoint.getZ(), fastCache, regions), maxZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int z = minPoint.getZ() + TILE_SIZE_ADJUSTED; z <= maxPoint.getZ() - Tile.tileSize; z += Tile.tileSize) {
|
for (int z = minPoint.getZ() + TILE_SIZE_ADJUSTED; z <= maxPoint.getZ() - Tile.tileSize; z += Tile.tileSize) {
|
||||||
neighbours.add(get(minPoint.getX(), z, fastCache, regions));
|
neighbours.add(new Pair<>(get(minPoint.getX(), z, fastCache, regions), NeighbourDirection.West));
|
||||||
neighbours.add(get(maxPoint.getX(), z, fastCache, regions));
|
neighbours.add(new Pair<>(get(maxPoint.getX(), z, fastCache, regions), NeighbourDirection.East));
|
||||||
}
|
}
|
||||||
|
|
||||||
neighbours.remove(getGlobalRegion());
|
neighbours.removeIf(data -> data.getKey().getType().isGlobal());
|
||||||
return neighbours.stream();
|
return neighbours.stream();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stream<DynamicRegion> getNeighbours(Region region) {
|
public Stream<Pair<DynamicRegion, NeighbourDirection>> getNeighbours(Region region) {
|
||||||
return getNeighbours(region, false, true, regionMap.values())
|
return getNeighbours(region, false, true, regionMap.values())
|
||||||
.filter(DynamicRegion.class::isInstance)
|
.filter(data -> data.getKey() instanceof DynamicRegion)
|
||||||
.map(DynamicRegion.class::cast);
|
.map(data -> new Pair<>((DynamicRegion) data.getKey(), data.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -175,7 +185,9 @@ public class DynamicRegionSystem implements RegionSystem {
|
|||||||
while (!current.isEmpty()) {
|
while (!current.isEmpty()) {
|
||||||
Region r = current.removeFirst();
|
Region r = current.removeFirst();
|
||||||
if (!connected.add(r)) continue;
|
if (!connected.add(r)) continue;
|
||||||
getNeighbours(r, true, false, regions).forEach(current::add);
|
getNeighbours(r, true, false, regions)
|
||||||
|
.map(Pair::getKey)
|
||||||
|
.forEach(current::add);
|
||||||
}
|
}
|
||||||
|
|
||||||
return connected.stream();
|
return connected.stream();
|
||||||
|
|||||||
+9
-10
@@ -19,21 +19,14 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.region.dynamic;
|
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.DynamicRegionSystem;
|
import de.steamwar.bausystem.region.DynamicRegionSystem;
|
||||||
import de.steamwar.bausystem.region.Point;
|
import de.steamwar.bausystem.region.Point;
|
||||||
import de.steamwar.bausystem.region.Region;
|
import de.steamwar.bausystem.region.Region;
|
||||||
import de.steamwar.bausystem.region.RegionData;
|
import de.steamwar.bausystem.region.RegionData;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public abstract class DynamicRegion implements Region {
|
public abstract class DynamicRegion implements Region {
|
||||||
|
|
||||||
@@ -55,7 +48,14 @@ public abstract class DynamicRegion implements Region {
|
|||||||
|
|
||||||
public abstract void init();
|
public abstract void init();
|
||||||
|
|
||||||
public void update(DynamicRegion updateFrom) {
|
public final void updateNeighbours() {
|
||||||
|
DynamicRegionSystem.INSTANCE.getNeighbours(this)
|
||||||
|
.forEach(data -> {
|
||||||
|
data.getKey().update(this, data.getValue().opposite());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(DynamicRegion updateFrom, NeighbourDirection direction) {
|
||||||
// TODO: Implement further
|
// TODO: Implement further
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,8 +73,7 @@ public abstract class DynamicRegion implements Region {
|
|||||||
Point maxPoint = getArea().getMaxPoint(false);
|
Point maxPoint = getArea().getMaxPoint(false);
|
||||||
PasteUtils.reset(minPoint, maxPoint);
|
PasteUtils.reset(minPoint, maxPoint);
|
||||||
|
|
||||||
DynamicRegionSystem.INSTANCE.getNeighbours(this).collect(Collectors.toList())
|
this.updateNeighbours();
|
||||||
.forEach(r -> r.update(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import de.steamwar.bausystem.region.dynamic.path.PathCorner;
|
||||||
|
import de.steamwar.bausystem.region.dynamic.path.PathSide;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum NeighbourDirection {
|
||||||
|
North(0, -1, Set.of(PathSide.North), Set.of(PathCorner.NorthEast, PathCorner.NorthWest)),
|
||||||
|
South(0, 1, Set.of(PathSide.South), Set.of(PathCorner.SouthEast, PathCorner.SouthWest)),
|
||||||
|
West(-1, 0, Set.of(PathSide.West), Set.of(PathCorner.NorthWest, PathCorner.SouthWest)),
|
||||||
|
East(1, 0, Set.of(PathSide.East), Set.of(PathCorner.NorthEast, PathCorner.SouthEast)),
|
||||||
|
NorthWest(-1, -1, Set.of(), Set.of(PathCorner.NorthWest)),
|
||||||
|
NorthEast(1, -1, Set.of(), Set.of(PathCorner.NorthEast)),
|
||||||
|
SouthWest(-1, 1, Set.of(), Set.of(PathCorner.SouthWest)),
|
||||||
|
SouthEast(1, 1, Set.of(), Set.of(PathCorner.SouthEast)),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final int tileOffsetX;
|
||||||
|
private final int tileOffsetZ;
|
||||||
|
private final Set<PathSide> sideUpdates;
|
||||||
|
private final Set<PathCorner> cornerUpdates;
|
||||||
|
|
||||||
|
public NeighbourDirection opposite() {
|
||||||
|
return switch (this) {
|
||||||
|
case North -> South;
|
||||||
|
case South -> North;
|
||||||
|
case East -> West;
|
||||||
|
case West -> East;
|
||||||
|
case NorthWest -> SouthEast;
|
||||||
|
case NorthEast -> SouthWest;
|
||||||
|
case SouthWest -> NorthEast;
|
||||||
|
case SouthEast -> NorthWest;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -129,4 +129,9 @@ public class Tile {
|
|||||||
public long getId() {
|
public long getId() {
|
||||||
return getID(tileX, tileZ);
|
return getID(tileX, tileZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return tileX + ":" + tileZ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+44
-66
@@ -30,7 +30,6 @@ import de.steamwar.bausystem.region.dynamic.VariantSelector;
|
|||||||
import de.steamwar.bausystem.shared.Pair;
|
import de.steamwar.bausystem.shared.Pair;
|
||||||
import de.steamwar.bausystem.utils.PasteBuilder;
|
import de.steamwar.bausystem.utils.PasteBuilder;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -66,37 +65,6 @@ public class PathArea implements Region.Area {
|
|||||||
.Case(Path, Path, Global, CORNER_INNER_GLOBAL, RotationCorrection.UsingOrdinal)
|
.Case(Path, Path, Global, CORNER_INNER_GLOBAL, RotationCorrection.UsingOrdinal)
|
||||||
;
|
;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
protected enum Side {
|
|
||||||
North(0, -1, 7, 0, 0),
|
|
||||||
South(0, 1, 7, 14, 180),
|
|
||||||
West(-1, 0, 0, 7, 90),
|
|
||||||
East(1, 0, 14, 7, 270),
|
|
||||||
;
|
|
||||||
|
|
||||||
private final int tileOffsetX;
|
|
||||||
private final int tileOffsetZ;
|
|
||||||
private final int pasteOffsetX;
|
|
||||||
private final int pasteOffsetZ;
|
|
||||||
private final int rotate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
protected enum Corner {
|
|
||||||
NorthEast(Side.North, Side.East, 14, 0, 0, -90),
|
|
||||||
NorthWest(Side.North, Side.West, 0, 0, 0, 90),
|
|
||||||
SouthWest(Side.South, Side.West, 0, 14, 180, -90),
|
|
||||||
SouthEast(Side.South, Side.East, 14, 14, 180, 90),
|
|
||||||
;
|
|
||||||
|
|
||||||
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 {
|
protected enum RotationCorrection {
|
||||||
Unchanged,
|
Unchanged,
|
||||||
WithCorrection,
|
WithCorrection,
|
||||||
@@ -140,6 +108,45 @@ public class PathArea implements Region.Area {
|
|||||||
return null; // I know what I do!
|
return null; // I know what I do!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reset(PathSide side) {
|
||||||
|
File resetFile = null;
|
||||||
|
VariantSelector selector = SELECTOR_SIDE.Select(tile, side);
|
||||||
|
if (selector != null) resetFile = selector.select(regionIdentifier, side.ordinal() + side.rotate).orElse(null);
|
||||||
|
if (selector == null || resetFile == null) {
|
||||||
|
if (!BauSystem.DEV_SERVER) return;
|
||||||
|
resetFile = FALLBACK_SCHEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
PasteUtils.paste(resetFile, minPoint.add(side.pasteOffsetX, 0, side.pasteOffsetZ), side.rotate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset(PathCorner corner) {
|
||||||
|
File resetFile = null;
|
||||||
|
Pair<VariantSelector, RotationCorrection> pair = SELECTOR_CORNER.Select(tile, corner);
|
||||||
|
VariantSelector selector = pair.getKey();
|
||||||
|
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 == null) {
|
||||||
|
if (!BauSystem.DEV_SERVER) return;
|
||||||
|
resetFile = FALLBACK_SCHEM;
|
||||||
|
rotationCorrection = RotationCorrection.Unchanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset(PasteBuilder pasteBuilder, boolean extension) {
|
public void reset(PasteBuilder pasteBuilder, boolean extension) {
|
||||||
if (region.isGarden()) {
|
if (region.isGarden()) {
|
||||||
@@ -151,45 +158,16 @@ public class PathArea implements Region.Area {
|
|||||||
PasteUtils.paste(resetFile, minPoint.add(7, 0, 7), 0);
|
PasteUtils.paste(resetFile, minPoint.add(7, 0, 7), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Side side : Side.values()) {
|
for (PathSide side : PathSide.values()) {
|
||||||
VariantSelector selector = SELECTOR_SIDE.Select(tile, side);
|
reset(side);
|
||||||
if (selector != null) resetFile = selector.select(regionIdentifier, side.ordinal() + side.rotate).orElse(null);
|
|
||||||
if (selector == null || resetFile == null) {
|
|
||||||
if (!BauSystem.DEV_SERVER) continue;
|
|
||||||
resetFile = FALLBACK_SCHEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
PasteUtils.paste(resetFile, minPoint.add(side.pasteOffsetX, 0, side.pasteOffsetZ), side.rotate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Corner corner : Corner.values()) {
|
for (PathCorner corner : PathCorner.values()) {
|
||||||
Pair<VariantSelector, RotationCorrection> pair = SELECTOR_CORNER.Select(tile, corner);
|
reset(corner);
|
||||||
VariantSelector selector = pair.getKey();
|
|
||||||
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 == null) {
|
|
||||||
if (!BauSystem.DEV_SERVER) continue;
|
|
||||||
resetFile = FALLBACK_SCHEM;
|
|
||||||
rotationCorrection = RotationCorrection.Unchanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static RegionType.ConnectionType getConnectionType(Tile tile, Side side, Side optionalSide) {
|
protected static RegionType.ConnectionType getConnectionType(Tile tile, PathSide side, PathSide optionalSide) {
|
||||||
Optional<Tile> optionalTile = tile.add(side.tileOffsetX, side.tileOffsetZ);
|
Optional<Tile> optionalTile = tile.add(side.tileOffsetX, side.tileOffsetZ);
|
||||||
if (optionalSide != null) {
|
if (optionalSide != null) {
|
||||||
optionalTile = optionalTile.flatMap(t -> t.add(optionalSide.tileOffsetX, optionalSide.tileOffsetZ));
|
optionalTile = optionalTile.flatMap(t -> t.add(optionalSide.tileOffsetX, optionalSide.tileOffsetZ));
|
||||||
|
|||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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 lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public enum PathCorner {
|
||||||
|
NorthEast(PathSide.North, PathSide.East, 14, 0, 0, -90),
|
||||||
|
NorthWest(PathSide.North, PathSide.West, 0, 0, 0, 90),
|
||||||
|
SouthWest(PathSide.South, PathSide.West, 0, 14, 180, -90),
|
||||||
|
SouthEast(PathSide.South, PathSide.East, 14, 14, 180, 90),
|
||||||
|
;
|
||||||
|
|
||||||
|
public final PathSide side1;
|
||||||
|
public final PathSide side2;
|
||||||
|
public final int pasteOffsetX;
|
||||||
|
public final int pasteOffsetZ;
|
||||||
|
public final int rotate;
|
||||||
|
public final int rotateCorrection;
|
||||||
|
}
|
||||||
+8
-7
@@ -20,10 +20,7 @@
|
|||||||
package de.steamwar.bausystem.region.dynamic.path;
|
package de.steamwar.bausystem.region.dynamic.path;
|
||||||
|
|
||||||
import de.steamwar.bausystem.region.*;
|
import de.steamwar.bausystem.region.*;
|
||||||
import de.steamwar.bausystem.region.dynamic.DynamicRegion;
|
import de.steamwar.bausystem.region.dynamic.*;
|
||||||
import de.steamwar.bausystem.region.dynamic.DynamicRegionRepository;
|
|
||||||
import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
|
|
||||||
import de.steamwar.bausystem.region.dynamic.Tile;
|
|
||||||
import de.steamwar.sql.GameModeConfig;
|
import de.steamwar.sql.GameModeConfig;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@@ -52,10 +49,14 @@ public class PathRegion extends DynamicRegion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(DynamicRegion updateFrom) {
|
public void update(DynamicRegion updateFrom, NeighbourDirection direction) {
|
||||||
gardenCache = null;
|
gardenCache = null;
|
||||||
// TODO: Improve
|
for (PathSide side : direction.getSideUpdates()) {
|
||||||
area.reset(null, false);
|
area.reset(side);
|
||||||
|
}
|
||||||
|
for (PathCorner corner : direction.getCornerUpdates()) {
|
||||||
|
area.reset(corner);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Boolean gardenCache = null;
|
private Boolean gardenCache = null;
|
||||||
|
|||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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 lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public enum PathSide {
|
||||||
|
North(0, -1, 7, 0, 0),
|
||||||
|
South(0, 1, 7, 14, 180),
|
||||||
|
West(-1, 0, 0, 7, 90),
|
||||||
|
East(1, 0, 14, 7, 270),
|
||||||
|
;
|
||||||
|
|
||||||
|
public final int tileOffsetX;
|
||||||
|
public final int tileOffsetZ;
|
||||||
|
public final int pasteOffsetX;
|
||||||
|
public final int pasteOffsetZ;
|
||||||
|
public final int rotate;
|
||||||
|
}
|
||||||
+1
-1
@@ -58,7 +58,7 @@ class SelectorCorner {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<VariantSelector, PathArea.RotationCorrection> Select(Tile tile, PathArea.Corner corner) {
|
public Pair<VariantSelector, PathArea.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);
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ class SelectorSide {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VariantSelector Select(Tile tile, PathArea.Side side) {
|
public VariantSelector Select(Tile tile, PathSide side) {
|
||||||
RegionType.ConnectionType type = PathArea.getConnectionType(tile, side, null);
|
RegionType.ConnectionType type = PathArea.getConnectionType(tile, side, null);
|
||||||
return selectors[type.ordinal()];
|
return selectors[type.ordinal()];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user