forked from SteamWar/SteamWar
Fix connect behavior towards SpawnRegion
This commit is contained in:
+6
-5
@@ -178,7 +178,6 @@ public class DynamicRegionEditor implements SWPlayer.Component, Listener {
|
||||
Vector direction = player.getLocation().getDirection();
|
||||
|
||||
RayAabIntersection intersection = new RayAabIntersection((float) startPos.getX(), (float) startPos.getY(), (float) startPos.getZ(), (float) direction.getX(), (float) direction.getY(), (float) direction.getZ());
|
||||
boolean hide = true;
|
||||
for (RInteraction interaction : entityServer.getEntitiesByType(RInteraction.class)) {
|
||||
float x = (float) (interaction.getX() - 0.5);
|
||||
float z = (float) (interaction.getZ() - 0.5);
|
||||
@@ -186,12 +185,14 @@ public class DynamicRegionEditor implements SWPlayer.Component, Listener {
|
||||
int tileX = (int) x;
|
||||
int tileZ = (int) z;
|
||||
if (type.visualize(area, tileX, tileZ)) {
|
||||
hide = false;
|
||||
area.hide(false);
|
||||
return;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
area.hide(hide);
|
||||
area.hide(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@@ -243,7 +244,7 @@ public class DynamicRegionEditor implements SWPlayer.Component, Listener {
|
||||
return false;
|
||||
}
|
||||
Region region = DynamicRegionSystem.INSTANCE.get(tile);
|
||||
if (region.getType().isGlobal()) {
|
||||
if (region.getType().isGlobal() || region.getType().isSpawn()) {
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
@@ -267,7 +268,7 @@ public class DynamicRegionEditor implements SWPlayer.Component, Listener {
|
||||
Tile tile = Tile.fromTile(tileX, tileZ).orElse(null);
|
||||
if (tile == null) return;
|
||||
Region region = DynamicRegionSystem.INSTANCE.get(tile);
|
||||
if (region.getType().isGlobal()) return;
|
||||
if (region.getType().isGlobal() || region.getType().isSpawn()) return;
|
||||
|
||||
if (region.getType().isPath()) {
|
||||
region.delete();
|
||||
|
||||
+17
-25
@@ -24,8 +24,6 @@ import de.steamwar.bausystem.features.region.WireframeCommand;
|
||||
import de.steamwar.bausystem.region.dynamic.*;
|
||||
import de.steamwar.bausystem.region.dynamic.global.GlobalRegion;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -158,33 +156,27 @@ public class DynamicRegionSystem implements RegionSystem {
|
||||
return regionTypeMap.getOrDefault(type, Collections.emptySet()).stream();
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@ToString
|
||||
public static class Neighbour<T extends Region> {
|
||||
public final T region;
|
||||
public final Tile tile;
|
||||
public final NeighbourDirection direction;
|
||||
public record Neighbour<T extends Region>(T region, Tile tile, NeighbourDirection direction) {
|
||||
public <O extends Region> Neighbour<O> as(Class<O> clazz) {
|
||||
if (!clazz.isInstance(region)) {
|
||||
return null;
|
||||
} else {
|
||||
return (Neighbour<O>) this;
|
||||
}
|
||||
}
|
||||
|
||||
public <O extends Region> Neighbour<O> as(Class<O> clazz) {
|
||||
if (!clazz.isInstance(region)) {
|
||||
return null;
|
||||
} else {
|
||||
return (Neighbour<O>) this;
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Neighbour<?> neighbour)) return false;
|
||||
return Objects.equals(tile, neighbour.tile) && direction == neighbour.direction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(tile, direction);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Neighbour<?> neighbour)) return false;
|
||||
return Objects.equals(tile, neighbour.tile) && direction == neighbour.direction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(tile, direction);
|
||||
}
|
||||
}
|
||||
|
||||
private Stream<Neighbour<Region>> getNeighbours(Region region, boolean noCorners, boolean fastCache, Collection<Region> regions) {
|
||||
Tile minTile = Tile.fromPoint(region.getArea().getMinPoint(false)).orElse(null);
|
||||
Tile maxTile = Tile.fromPoint(region.getArea().getMaxPoint(false)).orElse(null);
|
||||
|
||||
+9
-9
@@ -84,18 +84,18 @@ public abstract class DynamicRegion implements Region {
|
||||
// Calculate Garden State for all neighbouring PathRegions
|
||||
Set<UUID> needsFullReset = new HashSet<>();
|
||||
list.forEach(data -> {
|
||||
boolean previousGardenState = data.region.isGarden();
|
||||
data.region.calculateGardenState();
|
||||
if (data.region.isGarden() != previousGardenState) {
|
||||
needsFullReset.add(data.region.getID());
|
||||
boolean previousGardenState = data.region().isGarden();
|
||||
data.region().calculateGardenState();
|
||||
if (data.region().isGarden() != previousGardenState) {
|
||||
needsFullReset.add(data.region().getID());
|
||||
}
|
||||
});
|
||||
// Updating world state for all neighbouring PathRegions
|
||||
list.forEach(data -> {
|
||||
if (needsFullReset.contains(data.region.getID())) {
|
||||
data.region.getArea().reset(new PasteBuilder(), false);
|
||||
if (needsFullReset.contains(data.region().getID())) {
|
||||
data.region().getArea().reset(new PasteBuilder(), false);
|
||||
} else {
|
||||
data.region.update(this, data.direction.opposite());
|
||||
data.region().update(this, data.direction().opposite());
|
||||
}
|
||||
});
|
||||
// All full reset regions need to update their neighbours!
|
||||
@@ -106,8 +106,8 @@ public abstract class DynamicRegion implements Region {
|
||||
.map(neighbour -> neighbour.as(PathRegion.class))
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(data -> {
|
||||
if (data.region.isGarden()) return;
|
||||
data.region.update(dynamicRegion, data.direction.opposite());
|
||||
if (data.region().isGarden()) return;
|
||||
data.region().update(dynamicRegion, data.direction().opposite());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -33,6 +33,18 @@ import java.util.stream.Stream;
|
||||
@EqualsAndHashCode
|
||||
public class Tile {
|
||||
|
||||
public static final Tile ZERO = new Tile(0, 0);
|
||||
|
||||
public static final Tile TILE_PZ = new Tile(1, 0);
|
||||
public static final Tile TILE_NZ = new Tile(-1, 0);
|
||||
public static final Tile TILE_ZP = new Tile(0, 1);
|
||||
public static final Tile TILE_ZN = new Tile(0, -1);
|
||||
|
||||
public static final Tile TILE_PP = new Tile(1, 1);
|
||||
public static final Tile TILE_PN = new Tile(1, -1);
|
||||
public static final Tile TILE_NP = new Tile(-1, 1);
|
||||
public static final Tile TILE_NN = new Tile(-1, -1);
|
||||
|
||||
public static final int tileSize = 21;
|
||||
public static final int tileOffset = tileSize / 2;
|
||||
public static final int maxTile = 127;
|
||||
|
||||
+15
-3
@@ -28,6 +28,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.region.dynamic.spawn.SpawnRegion;
|
||||
import de.steamwar.bausystem.shared.Pair;
|
||||
import de.steamwar.bausystem.utils.PasteBuilder;
|
||||
import lombok.NonNull;
|
||||
@@ -220,19 +221,30 @@ public class PathArea extends Region.Area {
|
||||
}
|
||||
}
|
||||
|
||||
protected static RegionType.ConnectionType getConnectionType(Tile tile, PathSide side, PathSide optionalSide) {
|
||||
protected static RegionType.ConnectionType getConnectionType(Tile tile, PathSide side, PathSide optionalSide, RegionType.ConnectionType spawnPathConnection) {
|
||||
Optional<Tile> optionalTile = tile.add(side.tileOffsetX, side.tileOffsetZ);
|
||||
if (optionalSide != null) {
|
||||
optionalTile = optionalTile.flatMap(t -> t.add(optionalSide.tileOffsetX, optionalSide.tileOffsetZ));
|
||||
}
|
||||
if (optionalTile.isEmpty()) {
|
||||
return RegionType.ConnectionType.Global;
|
||||
return Global;
|
||||
}
|
||||
tile = optionalTile.get();
|
||||
Region region = DynamicRegionSystem.INSTANCE.get(tile.getCenterLocation());
|
||||
Region region = DynamicRegionSystem.INSTANCE.get(tile);
|
||||
if (region instanceof PathRegion pathRegion) {
|
||||
return pathRegion.isGarden() ? Garden : Path;
|
||||
}
|
||||
if (region instanceof SpawnRegion spawnRegion) {
|
||||
if (optionalSide == null && side.opposite().equals(spawnRegion.getPathSide())) {
|
||||
return spawnPathConnection;
|
||||
} else {
|
||||
return Closed;
|
||||
}
|
||||
}
|
||||
return region.getType().getConnectionType();
|
||||
}
|
||||
|
||||
protected static RegionType.ConnectionType getConnectionType(Tile tile, PathSide side, PathSide optionalSide) {
|
||||
return getConnectionType(tile, side, optionalSide, Path);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-6
@@ -86,12 +86,15 @@ public class PathRegion extends DynamicRegion {
|
||||
|
||||
public void calculateGardenState() {
|
||||
garden = false;
|
||||
Set<Tile> neighbours = tile.neighboursRing().collect(Collectors.toSet());
|
||||
if (neighbours.size() != 8) return;
|
||||
garden = neighbours.stream()
|
||||
.map(DynamicRegionSystem.INSTANCE::get)
|
||||
.map(Region::getType)
|
||||
.allMatch(RegionType::isPath);
|
||||
for (PathSide pathSide : PathSide.values()) {
|
||||
RegionType.ConnectionType connectionType = PathArea.getConnectionType(tile, pathSide, null, null);
|
||||
if (connectionType != RegionType.ConnectionType.Path && connectionType != RegionType.ConnectionType.Garden) return;
|
||||
}
|
||||
for (PathCorner pathCorner : PathCorner.values()) {
|
||||
RegionType.ConnectionType connectionType = PathArea.getConnectionType(tile, pathCorner.side1, pathCorner.side2, null);
|
||||
if (connectionType != RegionType.ConnectionType.Path && connectionType != RegionType.ConnectionType.Garden) return;
|
||||
}
|
||||
garden = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+9
@@ -34,4 +34,13 @@ public enum PathSide {
|
||||
public final int pasteOffsetX;
|
||||
public final int pasteOffsetZ;
|
||||
public final int rotate;
|
||||
|
||||
public PathSide opposite() {
|
||||
return switch (this) {
|
||||
case North -> South;
|
||||
case South -> North;
|
||||
case East -> West;
|
||||
case West -> East;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -59,8 +59,8 @@ class SelectorCorner {
|
||||
}
|
||||
|
||||
public Pair<VariantSelector, PathArea.RotationCorrection> Select(Tile tile, PathCorner corner) {
|
||||
RegionType.ConnectionType left = PathArea.getConnectionType(tile, corner.side1, null);
|
||||
RegionType.ConnectionType right = PathArea.getConnectionType(tile, corner.side2, null);
|
||||
RegionType.ConnectionType left = PathArea.getConnectionType(tile, corner.side1, null, RegionType.ConnectionType.Closed);
|
||||
RegionType.ConnectionType right = PathArea.getConnectionType(tile, corner.side2, null, RegionType.ConnectionType.Closed);
|
||||
RegionType.ConnectionType diagonal = PathArea.getConnectionType(tile, corner.side1, corner.side2);
|
||||
int index = getIndex(left, right, diagonal);
|
||||
return new Pair<>(selectors[index], rotationCorrections[index]);
|
||||
|
||||
+29
-5
@@ -19,32 +19,56 @@
|
||||
|
||||
package de.steamwar.bausystem.region.dynamic.spawn;
|
||||
|
||||
import de.steamwar.bausystem.region.DynamicRegionSystem;
|
||||
import de.steamwar.bausystem.region.Point;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.bausystem.region.RegionType;
|
||||
import de.steamwar.bausystem.region.dynamic.DynamicRegion;
|
||||
import de.steamwar.bausystem.region.dynamic.Tile;
|
||||
import de.steamwar.bausystem.utils.PasteBuilder;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SpawnArea extends Region.Area {
|
||||
|
||||
private final Tile tile;
|
||||
|
||||
public SpawnArea(Tile tile) {
|
||||
this.tile = tile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Point getMinPoint(boolean extension) {
|
||||
return null;
|
||||
return Point.fromLocation(tile.getMinLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Point getMaxPoint(boolean extension) {
|
||||
return null;
|
||||
return Point.fromLocation(tile.getMaxLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Point getCopyPoint(boolean extension) {
|
||||
return null;
|
||||
return Point.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(PasteBuilder pasteBuilder, boolean extension) {
|
||||
// TODO: Implement!
|
||||
super.reset(pasteBuilder, extension);
|
||||
List<DynamicRegion> regions = DynamicRegionSystem.INSTANCE.getNeighbours(DynamicRegionSystem.INSTANCE.get(Tile.ZERO))
|
||||
.map(DynamicRegionSystem.Neighbour::region)
|
||||
.toList();
|
||||
|
||||
if (regions.stream().map(DynamicRegion::getType).allMatch(RegionType::isSpawn)) {
|
||||
// TODO: Implement big spawn!
|
||||
return;
|
||||
}
|
||||
|
||||
for (DynamicRegion region : regions) {
|
||||
if (region.getArea() instanceof SpawnArea spawnArea) {
|
||||
spawnArea.place(new PasteBuilder(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+39
-3
@@ -25,20 +25,39 @@ import de.steamwar.bausystem.region.RegionBackups;
|
||||
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.RegionConstructorData;
|
||||
import de.steamwar.bausystem.region.dynamic.Tile;
|
||||
import de.steamwar.bausystem.region.dynamic.TileUtils;
|
||||
import de.steamwar.bausystem.region.dynamic.path.PathRegionData;
|
||||
import de.steamwar.bausystem.region.dynamic.path.PathSide;
|
||||
import de.steamwar.sql.GameModeConfig;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
@RegionConstructorData(
|
||||
identifier = "spawn",
|
||||
name = "Spawn",
|
||||
widthX = SpawnRegion.TILE_X,
|
||||
widthZ = SpawnRegion.TILE_Z,
|
||||
material = Material.LODESTONE,
|
||||
placeable = false
|
||||
)
|
||||
public class SpawnRegion extends DynamicRegion {
|
||||
|
||||
protected static final int TILE_X = 1;
|
||||
protected static final int TILE_Z = 1;
|
||||
|
||||
@Getter
|
||||
private final Tile tile;
|
||||
|
||||
@Getter
|
||||
private final PathSide pathSide;
|
||||
private final SpawnArea area;
|
||||
|
||||
public SpawnRegion(Tile tile) {
|
||||
this(UUID.randomUUID(), tile);
|
||||
finishCreate();
|
||||
@@ -52,8 +71,19 @@ public class SpawnRegion extends DynamicRegion {
|
||||
private SpawnRegion(UUID id, Tile tile) {
|
||||
super(id, null);
|
||||
this.tile = tile;
|
||||
if (tile.equals(Tile.TILE_PZ)) {
|
||||
pathSide = PathSide.East;
|
||||
} else if (tile.equals(Tile.TILE_NZ)) {
|
||||
pathSide = PathSide.West;
|
||||
} else if (tile.equals(Tile.TILE_ZP)) {
|
||||
pathSide = PathSide.South;
|
||||
} else if (tile.equals(Tile.TILE_ZN)) {
|
||||
pathSide = PathSide.North;
|
||||
} else {
|
||||
pathSide = null;
|
||||
}
|
||||
area = new SpawnArea(tile);
|
||||
regionData = PathRegionData.INSTANCE;
|
||||
// TODO: Initialize
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -63,12 +93,18 @@ public class SpawnRegion extends DynamicRegion {
|
||||
|
||||
@Override
|
||||
public @NonNull RegionType getType() {
|
||||
return RegionType.SPAWN;
|
||||
if (tile.equals(Tile.ZERO)) {
|
||||
return RegionType.SPAWN;
|
||||
} else if (pathSide != null) {
|
||||
return RegionType.SPAWN_PATH;
|
||||
} else {
|
||||
return RegionType.SPAWN_EXTENSION;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Area getArea() {
|
||||
return null;
|
||||
return area;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user