mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-27 06:20:02 +00:00
d
d
This commit is contained in:
1 parent
70d355621c
commit
ce8c4ff578
18 files changed
+1958
-180
No files matched your search
@@ -69,9 +69,14 @@ public final class IrisStructureLocator {
|
||||
private static final Pattern NAMESPACED_RESOURCE_KEY = Pattern.compile("[a-z0-9_.-]+:[a-z0-9/._-]+");
|
||||
|
||||
private static final Cache<Engine, PlacementIndex> INDEX_CACHE = Caffeine.newBuilder().weakKeys().build();
|
||||
private static final Cache<Engine, LocatableIndex> LOCATABLE_INDEX_CACHE =
|
||||
Caffeine.newBuilder().weakKeys().build();
|
||||
private static final PlacementIndex EMPTY_INDEX = new PlacementIndex(
|
||||
Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), Collections.emptySet(),
|
||||
Collections.emptySet(), Collections.emptyList());
|
||||
private static final LocatableIndex EMPTY_LOCATABLE_INDEX = new LocatableIndex(
|
||||
Collections.emptySet(), Collections.emptySet(), Collections.emptySet(),
|
||||
Collections.emptySet(), Collections.emptySet(), Collections.emptySet());
|
||||
private static final LocateResult NOT_FOUND_RESULT = new LocateResult(LocateStatus.NOT_FOUND, 0, 0, 0);
|
||||
private static final LocateResult SEARCH_LIMIT_RESULT =
|
||||
new LocateResult(LocateStatus.SEARCH_LIMIT_REACHED, 0, 0, 0);
|
||||
@@ -97,6 +102,39 @@ public final class IrisStructureLocator {
|
||||
|| placementIndex.vanillaAliases.contains(normalizedKey);
|
||||
}
|
||||
|
||||
public static boolean hasLocatablePlacement(Engine engine, String key) {
|
||||
if (engine == null || key == null || key.isBlank()) {
|
||||
return false;
|
||||
}
|
||||
return locatableIndex(engine).normalizedKeys().contains(normalize(key));
|
||||
}
|
||||
|
||||
public static boolean hasLocatableEditablePlacement(Engine engine, String key) {
|
||||
if (engine == null || key == null || key.isBlank()) {
|
||||
return false;
|
||||
}
|
||||
return locatableIndex(engine).normalizedEditableKeys().contains(normalize(key));
|
||||
}
|
||||
|
||||
public static boolean hasLocatableNativePlacement(Engine engine, String key) {
|
||||
if (engine == null || key == null || key.isBlank()) {
|
||||
return false;
|
||||
}
|
||||
return locatableIndex(engine).normalizedNativeKeys().contains(normalize(key));
|
||||
}
|
||||
|
||||
public static Set<String> locatableKeys(Engine engine) {
|
||||
return locatableIndex(engine).keys();
|
||||
}
|
||||
|
||||
public static Set<String> locatableEditableKeys(Engine engine) {
|
||||
return locatableIndex(engine).editableKeys();
|
||||
}
|
||||
|
||||
public static Set<String> locatableNativeKeys(Engine engine) {
|
||||
return locatableIndex(engine).nativeKeys();
|
||||
}
|
||||
|
||||
public static boolean hasNativePlacement(Engine engine, String key) {
|
||||
if (engine == null || key == null || key.isBlank()) {
|
||||
return false;
|
||||
@@ -126,6 +164,7 @@ public final class IrisStructureLocator {
|
||||
public static void invalidate(Engine engine) {
|
||||
if (engine != null) {
|
||||
INDEX_CACHE.invalidate(engine);
|
||||
LOCATABLE_INDEX_CACHE.invalidate(engine);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -796,7 +835,8 @@ public final class IrisStructureLocator {
|
||||
List<IrisStructurePlacement> concentricRings = new ArrayList<>();
|
||||
boolean hasDensity = false;
|
||||
for (IrisStructurePlacement placement : index(engine).placements) {
|
||||
if (!matches(placement, key, engine.getData())) {
|
||||
if (!isSearchablePlacement(engine, placement)
|
||||
|| !matches(placement, key, engine.getData())) {
|
||||
continue;
|
||||
}
|
||||
if (placement.getDistribution() == StructureDistribution.RANDOM_SPREAD) {
|
||||
@@ -805,7 +845,7 @@ public final class IrisStructureLocator {
|
||||
StructurePlacementGrid.placementSalt(placement)));
|
||||
} else if (placement.getDistribution() == StructureDistribution.CONCENTRIC_RINGS) {
|
||||
concentricRings.add(placement);
|
||||
} else if (isSearchableDensityPlacement(engine, placement)) {
|
||||
} else if (placement.getDistribution() == StructureDistribution.DENSITY) {
|
||||
hasDensity = true;
|
||||
}
|
||||
}
|
||||
@@ -813,8 +853,18 @@ public final class IrisStructureLocator {
|
||||
}
|
||||
|
||||
static boolean isSearchableDensityPlacement(Engine engine, IrisStructurePlacement placement) {
|
||||
if (engine == null || placement == null || placement.getDistribution() != StructureDistribution.DENSITY
|
||||
|| !(placement.getDensity() > 0.0) || engine.getHeight() <= 0) {
|
||||
return placement != null
|
||||
&& placement.getDistribution() == StructureDistribution.DENSITY
|
||||
&& isSearchablePlacement(engine, placement);
|
||||
}
|
||||
|
||||
static boolean isSearchablePlacement(Engine engine, IrisStructurePlacement placement) {
|
||||
if (engine == null || placement == null || placement.getDistribution() == null
|
||||
|| engine.getHeight() <= 0) {
|
||||
return false;
|
||||
}
|
||||
if (placement.getDistribution() == StructureDistribution.DENSITY
|
||||
&& !(placement.getDensity() > 0.0)) {
|
||||
return false;
|
||||
}
|
||||
long worldMin = (long) engine.getMinHeight() + (placement.isUnderground() ? 1L : 0L);
|
||||
@@ -952,6 +1002,64 @@ public final class IrisStructureLocator {
|
||||
return INDEX_CACHE.get(engine, ignored -> build(engine));
|
||||
}
|
||||
|
||||
private static LocatableIndex locatableIndex(Engine engine) {
|
||||
if (engine == null) {
|
||||
return EMPTY_LOCATABLE_INDEX;
|
||||
}
|
||||
return LOCATABLE_INDEX_CACHE.get(engine, ignored -> buildLocatableIndex(engine));
|
||||
}
|
||||
|
||||
private static LocatableIndex buildLocatableIndex(Engine engine) {
|
||||
IrisData data = engine.getData();
|
||||
Set<String> keys = new LinkedHashSet<>();
|
||||
Set<String> normalizedKeys = new LinkedHashSet<>();
|
||||
Set<String> editableKeys = new LinkedHashSet<>();
|
||||
Set<String> normalizedEditableKeys = new LinkedHashSet<>();
|
||||
Set<String> nativeKeys = new LinkedHashSet<>();
|
||||
Set<String> normalizedNativeKeys = new LinkedHashSet<>();
|
||||
for (IrisStructurePlacement placement : index(engine).placements) {
|
||||
if (!isSearchablePlacement(engine, placement)) {
|
||||
continue;
|
||||
}
|
||||
if (placement.hasNativeStructures()) {
|
||||
for (IrisNativeStructure source : placement.getNativeStructures()) {
|
||||
addLocatableKey(source.getStructure(), keys, normalizedKeys);
|
||||
addLocatableKey(source.getStructure(), nativeKeys, normalizedNativeKeys);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for (String structureKey : placement.getStructures()) {
|
||||
IrisStructure structure = data.load(IrisStructure.class, structureKey, false);
|
||||
if (structure == null) {
|
||||
throw new IllegalStateException(
|
||||
"Iris structure placement references missing structure '" + structureKey + "'");
|
||||
}
|
||||
addLocatableKey(structureKey, keys, normalizedKeys);
|
||||
addLocatableKey(structureKey, editableKeys, normalizedEditableKeys);
|
||||
addLocatableKey(structure.getLoadKey(), keys, normalizedKeys);
|
||||
addLocatableKey(structure.getLoadKey(), editableKeys, normalizedEditableKeys);
|
||||
addLocatableKey(structure.getVanillaSource(), keys, normalizedKeys);
|
||||
addLocatableKey(structure.getVanillaSource(), editableKeys, normalizedEditableKeys);
|
||||
}
|
||||
}
|
||||
return new LocatableIndex(
|
||||
Collections.unmodifiableSet(keys),
|
||||
Collections.unmodifiableSet(normalizedKeys),
|
||||
Collections.unmodifiableSet(editableKeys),
|
||||
Collections.unmodifiableSet(normalizedEditableKeys),
|
||||
Collections.unmodifiableSet(nativeKeys),
|
||||
Collections.unmodifiableSet(normalizedNativeKeys));
|
||||
}
|
||||
|
||||
private static void addLocatableKey(String key, Set<String> keys, Set<String> normalizedKeys) {
|
||||
if (key == null || key.isBlank()) {
|
||||
return;
|
||||
}
|
||||
String trimmedKey = key.trim();
|
||||
keys.add(trimmedKey);
|
||||
normalizedKeys.add(normalize(trimmedKey));
|
||||
}
|
||||
|
||||
private static PlacementIndex build(Engine engine) {
|
||||
IrisData data = engine.getData();
|
||||
Set<String> loadKeys = new LinkedHashSet<>();
|
||||
@@ -1112,6 +1220,11 @@ public final class IrisStructureLocator {
|
||||
List<IrisStructurePlacement> concentricRings, boolean hasDensity) {
|
||||
}
|
||||
|
||||
private record LocatableIndex(Set<String> keys, Set<String> normalizedKeys,
|
||||
Set<String> editableKeys, Set<String> normalizedEditableKeys,
|
||||
Set<String> nativeKeys, Set<String> normalizedNativeKeys) {
|
||||
}
|
||||
|
||||
private record ResolvedStart(int originX, int baseY, int originZ) {
|
||||
}
|
||||
|
||||
|
||||
+88
-30
@@ -18,42 +18,57 @@
|
||||
|
||||
package art.arcane.iris.util.common.director.specialhandlers;
|
||||
|
||||
import art.arcane.iris.core.nms.INMS;
|
||||
import art.arcane.iris.engine.framework.Engine;
|
||||
import art.arcane.iris.engine.framework.IrisStructureLocator;
|
||||
import art.arcane.volmlib.util.collection.KList;
|
||||
import art.arcane.iris.engine.framework.NativeStructureGenerationPolicy;
|
||||
import art.arcane.iris.engine.framework.StructureReachability;
|
||||
import art.arcane.iris.engine.object.IrisNativeStructureDecision;
|
||||
import art.arcane.iris.engine.object.NativeStructureGenerationStatus;
|
||||
import art.arcane.iris.spi.IrisPlatforms;
|
||||
import art.arcane.iris.spi.PlatformStructureHooks;
|
||||
import art.arcane.iris.util.common.director.DirectorParameterHandler;
|
||||
import art.arcane.volmlib.util.collection.KList;
|
||||
import art.arcane.volmlib.util.director.exceptions.DirectorParsingException;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class StructureHandler implements DirectorParameterHandler<String> {
|
||||
@Override
|
||||
public KList<String> getPossibilities() {
|
||||
KList<String> keys = new KList<>();
|
||||
|
||||
try {
|
||||
for (String k : INMS.get().getStructureKeys()) {
|
||||
if (k != null && !k.isEmpty()) {
|
||||
keys.addIfMissing(k);
|
||||
}
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
Engine activeEngine = engine();
|
||||
if (activeEngine == null) {
|
||||
return new KList<>();
|
||||
}
|
||||
|
||||
try {
|
||||
Engine e = engine();
|
||||
if (e != null) {
|
||||
for (String k : IrisStructureLocator.placedKeys(e)) {
|
||||
if (k != null && !k.isEmpty()) {
|
||||
keys.addIfMissing(k);
|
||||
}
|
||||
}
|
||||
boolean nativeGenerationEnabled = nativeStructureGenerationEnabled();
|
||||
PlatformStructureHooks structureHooks = IrisPlatforms.get().structureHooks();
|
||||
Map<String, String> registeredKeys = distinctKeys(structureHooks.structureKeys());
|
||||
Set<String> reachableKeys = StructureReachability.reachableKeys(activeEngine);
|
||||
Map<String, String> suggestions = new LinkedHashMap<>();
|
||||
|
||||
for (Map.Entry<String, String> entry : registeredKeys.entrySet()) {
|
||||
if (isEligibleRegisteredKey(activeEngine, entry.getValue(), entry.getKey(), reachableKeys,
|
||||
nativeGenerationEnabled)) {
|
||||
suggestions.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
||||
return keys;
|
||||
Set<String> locatableKeys = IrisStructureLocator.locatableEditableKeys(activeEngine);
|
||||
for (String key : locatableKeys) {
|
||||
String normalizedKey = normalizeKey(key);
|
||||
if (!normalizedKey.isEmpty()
|
||||
&& !registeredKeys.containsKey(normalizedKey)
|
||||
&& !IrisStructureLocator.hasNativePlacement(activeEngine, key)) {
|
||||
suggestions.putIfAbsent(normalizedKey, key.trim());
|
||||
}
|
||||
}
|
||||
|
||||
return new KList<>(suggestions.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,15 +79,12 @@ public class StructureHandler implements DirectorParameterHandler<String> {
|
||||
@Override
|
||||
public String parse(String in, boolean force) throws DirectorParsingException {
|
||||
KList<String> options = getPossibilities(in);
|
||||
|
||||
if (options.isEmpty()) {
|
||||
return in;
|
||||
}
|
||||
try {
|
||||
return options.stream().filter((i) -> toString(i).equalsIgnoreCase(in)).collect(Collectors.toList()).get(0);
|
||||
} catch (Throwable e) {
|
||||
return in;
|
||||
for (String option : options) {
|
||||
if (option.equalsIgnoreCase(in)) {
|
||||
return option;
|
||||
}
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,4 +98,50 @@ public class StructureHandler implements DirectorParameterHandler<String> {
|
||||
|
||||
return f == null ? "minecraft_ancient_city" : f;
|
||||
}
|
||||
|
||||
protected boolean nativeStructureGenerationEnabled() {
|
||||
Player activePlayer = player();
|
||||
return activePlayer != null && activePlayer.getWorld().canGenerateStructures();
|
||||
}
|
||||
|
||||
private static Map<String, String> distinctKeys(List<String> keys) {
|
||||
Map<String, String> distinct = new LinkedHashMap<>();
|
||||
for (String key : keys) {
|
||||
String normalizedKey = normalizeKey(key);
|
||||
if (!normalizedKey.isEmpty()) {
|
||||
distinct.putIfAbsent(normalizedKey, key.trim());
|
||||
}
|
||||
}
|
||||
return distinct;
|
||||
}
|
||||
|
||||
private static boolean isEligibleRegisteredKey(Engine engine, String key, String normalizedKey,
|
||||
Set<String> reachableKeys, boolean nativeGenerationEnabled) {
|
||||
IrisNativeStructureDecision decision = NativeStructureGenerationPolicy.resolve(engine, key, false);
|
||||
boolean nativePlacement = IrisStructureLocator.hasNativePlacement(engine, key);
|
||||
boolean locatableNativePlacement = nativePlacement
|
||||
&& IrisStructureLocator.hasLocatableNativePlacement(engine, key);
|
||||
boolean locatableEditableReplacement = !nativePlacement
|
||||
&& decision.status() == NativeStructureGenerationStatus.REPLACED_BY_IRIS
|
||||
&& IrisStructureLocator.hasLocatableEditablePlacement(engine, key);
|
||||
return isEligibleRegisteredKey(
|
||||
decision, nativePlacement, locatableNativePlacement, locatableEditableReplacement,
|
||||
reachableKeys.contains(normalizedKey), nativeGenerationEnabled);
|
||||
}
|
||||
|
||||
static boolean isEligibleRegisteredKey(IrisNativeStructureDecision decision, boolean nativePlacement,
|
||||
boolean locatableNativePlacement,
|
||||
boolean locatableEditableReplacement,
|
||||
boolean reachable, boolean nativeGenerationEnabled) {
|
||||
if (decision.status() == NativeStructureGenerationStatus.REPLACED_BY_IRIS) {
|
||||
return locatableEditableReplacement
|
||||
|| nativeGenerationEnabled && nativePlacement && locatableNativePlacement;
|
||||
}
|
||||
return nativeGenerationEnabled && decision.generate()
|
||||
&& (reachable || (nativePlacement && locatableNativePlacement));
|
||||
}
|
||||
|
||||
private static String normalizeKey(String key) {
|
||||
return key == null ? "" : key.trim().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user