mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-22 08:07:42 +00:00
Added dimension takeover
- IrisDimension borrowedDimensionType reuses an existing registered dimension type instead of generating one - Pack validation rejects borrowedDimensionType values that are not namespaced registry keys - Generation contracts record the borrowed type key and capture it as an external registry definition - Borrowed types bind when the pack min equals the type min_y and the pack top fits, with both ranges in the refusal - Studio hotload rejects borrowed type changes and the world check validates borrowed ranges - Forced datapack skips generated types and presets for borrowed dimensions and accepts retained borrowed epochs - modded.json dimensionTakeovers writes a LevelStem per level key using the irisworldgen:iris generator - Takeover changes quarantine the level chunk, entity, POI, and Iris data before load and track applied state per world - Fresh levels adopt generation history with content-addressed biomes instead of legacy aliases - /iris world takeover <dimension> <pack[:dimension]|off> with help and translations in every locale
This commit is contained in:
1 parent
8afb445b1d
commit
5633eec009
52 files changed
+1365
-95
No files matched your search
@@ -63,6 +63,7 @@ import art.arcane.iris.pack.validation.CompatStatus;
|
||||
import art.arcane.iris.pack.validation.ContentGate;
|
||||
import art.arcane.iris.pack.loading.IrisData;
|
||||
import art.arcane.iris.spi.IrisLogging;
|
||||
import art.arcane.iris.spi.PlatformGenerationRegistry;
|
||||
import art.arcane.volmlib.nativelib.terrain.NativeBlockState;
|
||||
import art.arcane.iris.pack.loading.IrisRegistrant;
|
||||
import art.arcane.iris.pack.datapack.DataVersion;
|
||||
@@ -263,6 +264,8 @@ public class IrisDimension extends IrisRegistrant {
|
||||
private IrisRange dimensionHeight = new IrisRange(-64, 320);
|
||||
@Description("Define options for this dimension")
|
||||
private IrisDimensionTypeOptions dimensionOptions = new IrisDimensionTypeOptions();
|
||||
@Description("Borrow an existing registered dimension type, such as minecraft:the_end or a mod's aether:the_aether, instead of generating one from dimensionOptions. Sky, fog, lighting, and client effects then come from that type, and dimensionOptions and fullbright are ignored. dimensionHeight.min must equal the type's min_y and dimensionHeight.max must not exceed its top; a mismatch is refused when the world loads. Leave empty to generate a dimension type. Modded servers only.")
|
||||
private String borrowedDimensionType = "";
|
||||
@Description("Configure and enforce the native Minecraft world border. When omitted, Iris leaves the native border unchanged.")
|
||||
private IrisWorldBoundary worldBoundary = null;
|
||||
@ArrayType(type = IrisImageMapBinding.class)
|
||||
@@ -1105,6 +1108,17 @@ public class IrisDimension extends IrisRegistrant {
|
||||
return sanitizeDimensionTypeKeyValue(getLoadKey());
|
||||
}
|
||||
|
||||
public boolean hasBorrowedDimensionType() {
|
||||
return borrowedDimensionType != null && !borrowedDimensionType.isBlank();
|
||||
}
|
||||
|
||||
public String dimensionTypeResourceKey(PlatformGenerationRegistry registry, String packName) {
|
||||
if (hasBorrowedDimensionType()) {
|
||||
return borrowedDimensionType.trim();
|
||||
}
|
||||
return registry.dimensionTypeResourceKey(packName, getLoadKey(), getDimensionTypeKey());
|
||||
}
|
||||
|
||||
public String getCustomBiomeKey(String customBiomeId) {
|
||||
return customBiomeKey(getLoadKey(), customBiomeId);
|
||||
}
|
||||
|
||||
+21
-1
@@ -46,7 +46,9 @@ public record IrisDimensionRuntimeContract(
|
||||
Objects.requireNonNull(dimension, "dimension");
|
||||
Objects.requireNonNull(namespace, "namespace");
|
||||
return new IrisDimensionRuntimeContract(
|
||||
namespace + ":" + dimension.getDimensionTypeKey(),
|
||||
dimension.hasBorrowedDimensionType()
|
||||
? dimension.getBorrowedDimensionType().trim()
|
||||
: namespace + ":" + dimension.getDimensionTypeKey(),
|
||||
dimension.getMinHeight(),
|
||||
dimension.getMaxHeight() - dimension.getMinHeight(),
|
||||
dimension.getLogicalHeight());
|
||||
@@ -83,6 +85,24 @@ public record IrisDimensionRuntimeContract(
|
||||
throw mismatch(runtimeName, "unknown", actualMinHeight, actualHeight, -1);
|
||||
}
|
||||
|
||||
public void requireBorrowedFit(String runtimeName, IrisDimensionRuntimeContract actual) {
|
||||
Objects.requireNonNull(actual, "actual");
|
||||
String packRange = minHeight + ".." + maxHeight();
|
||||
String borrowedRange = actual.minHeight() + ".." + actual.maxHeight();
|
||||
if (!typeKey.equals(actual.typeKey())) {
|
||||
throw new IrisDimensionContractException(runtimeName + " requires borrowed dimension type " + typeKey
|
||||
+ ", but the loaded runtime uses " + actual.typeKey() + " with range " + borrowedRange
|
||||
+ ". Generation was refused before any chunk writes. Restart after the level uses " + typeKey + ".");
|
||||
}
|
||||
if (minHeight == actual.minHeight() && maxHeight() <= actual.maxHeight()) {
|
||||
return;
|
||||
}
|
||||
throw new IrisDimensionContractException(runtimeName + " borrows dimension type " + typeKey
|
||||
+ " with range " + borrowedRange + ", but the Iris pack range is " + packRange
|
||||
+ ". Generation was refused before any chunk writes. Set the pack dimensionHeight.min to "
|
||||
+ actual.minHeight() + " and keep dimensionHeight.max at or below " + actual.maxHeight() + ".");
|
||||
}
|
||||
|
||||
private IrisDimensionContractException mismatch(
|
||||
String runtimeName,
|
||||
String actualTypeKey,
|
||||
|
||||
@@ -30,8 +30,12 @@ import java.nio.file.Files;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
final class PackDimensionValidator {
|
||||
private static final String BORROWED_DIMENSION_TYPE = "borrowedDimensionType";
|
||||
private static final Pattern RESOURCE_KEY = Pattern.compile("[a-z0-9_.-]+:[a-z0-9/._-]+");
|
||||
|
||||
private PackDimensionValidator() {
|
||||
}
|
||||
|
||||
@@ -56,6 +60,7 @@ final class PackDimensionValidator {
|
||||
|
||||
validateImportedStructurePolicy(dimensionKey, dimJson, blockingErrors, warnings);
|
||||
validateDimensionHeights(packFolder, dimensionKey, dimJson, blockingErrors);
|
||||
validateBorrowedDimensionType(dimensionKey, dimJson, blockingErrors);
|
||||
validateSamplingStep(dimensionKey, dimJson, "terrainSamplingStep", 1, blockingErrors);
|
||||
validateSamplingStep(dimensionKey, dimJson, "caveDensitySamplingStep", 1, blockingErrors);
|
||||
validateSamplingStep(dimensionKey, dimJson, "biomeBoundsSamplingStep", 4, blockingErrors);
|
||||
@@ -123,6 +128,18 @@ final class PackDimensionValidator {
|
||||
}
|
||||
}
|
||||
|
||||
static void validateBorrowedDimensionType(String dimensionKey, JSONObject dimension, List<String> errors) {
|
||||
if (!dimension.has(BORROWED_DIMENSION_TYPE) || dimension.isNull(BORROWED_DIMENSION_TYPE)) {
|
||||
return;
|
||||
}
|
||||
Object value = dimension.opt(BORROWED_DIMENSION_TYPE);
|
||||
if (value instanceof String key && (key.isEmpty() || RESOURCE_KEY.matcher(key).matches())) {
|
||||
return;
|
||||
}
|
||||
errors.add("Dimension '" + dimensionKey + "' " + BORROWED_DIMENSION_TYPE
|
||||
+ " must be a namespaced dimension type key such as aether:the_aether, but was '" + value + "'.");
|
||||
}
|
||||
|
||||
static void validateObjectScaleFactor(String dimensionKey, JSONObject dimension, List<String> errors) {
|
||||
validateFiniteNumber(dimension, "allObjectScaleFactor", IrisObjectScale.MINIMUM_FACTOR,
|
||||
IrisObjectScale.MAXIMUM_FACTOR, "Dimension '" + dimensionKey + "'", errors);
|
||||
|
||||
@@ -373,14 +373,10 @@ public class StudioSVC implements IrisService {
|
||||
throw new IOException("Generation pack does not contain a loadable dimension '"
|
||||
+ dimensionKey + "'.");
|
||||
}
|
||||
String dimensionTypeKey = IrisPlatforms.get()
|
||||
.registries()
|
||||
.generationRegistry()
|
||||
.dimensionTypeResourceKey(
|
||||
data.getDataFolder().getName(),
|
||||
dimension.getLoadKey(),
|
||||
dimension.getDimensionTypeKey()
|
||||
);
|
||||
String dimensionTypeKey = dimension.dimensionTypeResourceKey(
|
||||
IrisPlatforms.get().registries().generationRegistry(),
|
||||
data.getDataFolder().getName()
|
||||
);
|
||||
GenerationEpoch.DimensionContract dimensionContract = GenerationEpochContractFactory.create(
|
||||
dimension,
|
||||
dimension.getLoadKey(),
|
||||
|
||||
+18
-9
@@ -175,15 +175,24 @@ public final class GenerationRegistryContractFactory {
|
||||
List<IrisBiome> reachableBiomes = new ArrayList<>(requiredDimension.getReachableBiomes(() -> requiredData));
|
||||
for (IrisDimension registryDimension : registryDimensions(requiredData, requiredDimension)) {
|
||||
String dimensionKey = requireText(registryDimension.getLoadKey(), "Dimension load key");
|
||||
addGeneratedDimensionType(
|
||||
definitions,
|
||||
generatedSources,
|
||||
registryDimension,
|
||||
packName,
|
||||
dimensionKey,
|
||||
requiredFixer,
|
||||
requiredGenerationRegistry
|
||||
);
|
||||
if (!registryDimension.hasBorrowedDimensionType()) {
|
||||
addGeneratedDimensionType(
|
||||
definitions,
|
||||
generatedSources,
|
||||
registryDimension,
|
||||
packName,
|
||||
dimensionKey,
|
||||
requiredFixer,
|
||||
requiredGenerationRegistry
|
||||
);
|
||||
} else if (registryDimension == requiredDimension) {
|
||||
addPlatformDefinitions(
|
||||
definitions,
|
||||
DIMENSION_TYPE_REGISTRY,
|
||||
List.of(registryDimension.dimensionTypeResourceKey(requiredGenerationRegistry, packName)),
|
||||
requiredGenerationRegistry
|
||||
);
|
||||
}
|
||||
List<IrisBiome> referencedBiomes = registryDimension == requiredDimension ? reachableBiomes : List.of();
|
||||
List<IrisBiome> registryBiomes = new ArrayList<>(registryDimension.getAllBiomes(() -> requiredData));
|
||||
registryBiomes.addAll(referencedBiomes);
|
||||
|
||||
@@ -446,6 +446,7 @@ operator_instruction = "Führe {command} in der Konsole aus oder aktiviere Cheat
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "Eine bestehende Dimension beim nächsten Neustart mit einem Iris-Pack übernehmen oder die Übernahme ausschalten"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1087,6 +1088,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "Derzeit sind kei
|
||||
loaded_iris_dimensions = "Geladene Iris-Dimensionen: {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "Verwende /iris world create <name> <pack>, um eine Dimension ohne Neustart einzubinden."
|
||||
takeover_set = "Iris-Übernahme von {dimensionId} auf Pack '{pack}', Dimension '{packDimension}' gesetzt."
|
||||
takeover_cleared = "Iris-Übernahme von {dimensionId} ausgeschaltet; der eigene Generator der Dimension kehrt beim nächsten Neustart zurück."
|
||||
takeover_not_configured = "Für {dimensionId} ist keine Iris-Übernahme konfiguriert."
|
||||
takeover_restart_required = "Neustart erforderlich: Beim nächsten Start werden die Chunk-, Entity-, POI- und Iris Mantle-Daten der Dimension in einen Wiederherstellungsordner verschoben und neu generiert. Spielerdaten bleiben erhalten."
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "Externe Datapack-Importe von Modrinth herunterladen und verwalten"
|
||||
|
||||
@@ -446,6 +446,7 @@ operator_instruction = "Ejecuta {command} desde la consola (o activa los trucos
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "Tomar el control de una dimensión existente con un pack de Iris en el próximo reinicio, o desactivarlo"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1087,6 +1088,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "No hay dimension
|
||||
loaded_iris_dimensions = "Dimensiones de Iris cargadas: {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "Usa /iris world create <name> <pack> para inyectar una sin reiniciar."
|
||||
takeover_set = "Toma de control de Iris de {dimensionId} asignada al pack '{pack}', dimensión '{packDimension}'."
|
||||
takeover_cleared = "Toma de control de Iris de {dimensionId} desactivada; el generador propio de la dimensión vuelve en el próximo reinicio."
|
||||
takeover_not_configured = "No hay ninguna toma de control de Iris configurada para {dimensionId}."
|
||||
takeover_restart_required = "Se requiere reiniciar: en el próximo inicio, los datos de chunks, entidades, POI e Iris Mantle de la dimensión se mueven a una carpeta de recuperación y se regeneran. Los datos de los jugadores se conservan."
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "Descargar y gestionar importaciones externas de datapacks (Modrinth)"
|
||||
|
||||
@@ -451,6 +451,7 @@ operator_instruction = "Juokse {command} konsolilta (tai mahdollista huijaukset
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "Ota olemassa oleva ulottuvuus haltuun Iris-paketilla seuraavassa uudelleenkäynnistyksessä tai poista haltuunotto käytöstä"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1092,6 +1093,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "Ei Iris mitat ov
|
||||
loaded_iris_dimensions = "Ladattu Iris mitat: {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "Käyttö /iris world create <name> <pack> pistääksesi yhden ilman, että aloitat alusta."
|
||||
takeover_set = "Iris-haltuunotto kohteelle {dimensionId} asetettu: paketti '{pack}', ulottuvuus '{packDimension}'."
|
||||
takeover_cleared = "Iris-haltuunotto kohteelle {dimensionId} poistettu käytöstä; ulottuvuuden oma generaattori palaa seuraavan uudelleenkäynnistyksen yhteydessä."
|
||||
takeover_not_configured = "Kohteelle {dimensionId} ei ole määritetty Iris-haltuunottoa."
|
||||
takeover_restart_required = "Uudelleenkäynnistys vaaditaan: seuraavassa käynnistyksessä ulottuvuuden chunk-, entiteetti-, POI- ja Iris Mantle -tiedot siirretään palautuskansioon ja luodaan uudelleen. Pelaajatiedot säilytetään."
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "Lataa & Hallinnoidaan ulkoisen datapaketin tuontia (Modrinth)"
|
||||
|
||||
@@ -446,6 +446,7 @@ operator_instruction = "Exécutez {command} depuis la console (ou activez les co
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "Prendre le contrôle d'une dimension existante avec un pack Iris au prochain redémarrage, ou le désactiver"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1087,6 +1088,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "Aucune dimension
|
||||
loaded_iris_dimensions = "Dimensions Iris chargées : {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "Utilisez /iris world create <name> <pack> pour en injecter une sans redémarrer."
|
||||
takeover_set = "Prise de contrôle Iris de {dimensionId} définie sur le pack '{pack}', dimension '{packDimension}'."
|
||||
takeover_cleared = "Prise de contrôle Iris de {dimensionId} désactivée ; le générateur propre à la dimension revient au prochain redémarrage."
|
||||
takeover_not_configured = "Aucune prise de contrôle Iris n'est configurée pour {dimensionId}."
|
||||
takeover_restart_required = "Redémarrage requis : au prochain démarrage, les données de chunks, d'entités, de POI et d'Iris Mantle de la dimension sont déplacées vers un dossier de récupération puis régénérées. Les données des joueurs sont conservées."
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "Télécharger et gérer les importations externes de datapacks (Modrinth)"
|
||||
|
||||
@@ -451,6 +451,7 @@ operator_instruction = "לרוץ {command} מן הקונסולה (או לאפש
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "השתלטות על ממד קיים עם חבילת Iris בהפעלה מחדש הבאה, או כיבוי ההשתלטות"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1092,6 +1093,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "לא Iris המי
|
||||
loaded_iris_dimensions = "טעון Iris ממדים: {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "שימוש בשימוש /iris world create <name> <pack> להזריק אחד מבלי להתחיל מחדש."
|
||||
takeover_set = "השתלטות Iris על {dimensionId} הוגדרה לחבילה '{pack}', ממד '{packDimension}'."
|
||||
takeover_cleared = "השתלטות Iris על {dimensionId} כובתה; המחולל המקורי של הממד יחזור בהפעלה מחדש הבאה."
|
||||
takeover_not_configured = "לא מוגדרת השתלטות Iris עבור {dimensionId}."
|
||||
takeover_restart_required = "נדרשת הפעלה מחדש: בהפעלה הבאה נתוני ה-chunk, הישויות, ה-POI וה-Iris Mantle של הממד יועברו לתיקיית שחזור וייווצרו מחדש. נתוני השחקנים נשמרים."
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "הורד הורדה & ניהול יבוא נתונים חיצוני (Modrinth)"
|
||||
|
||||
@@ -446,6 +446,7 @@ operator_instruction = "Esegui {command} dalla console oppure abilita i trucchi
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "Acquisisci una dimensione esistente con un pack Iris al prossimo riavvio, oppure disattiva l'acquisizione"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1087,6 +1088,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "Nessuna dimensio
|
||||
loaded_iris_dimensions = "Dimensioni Iris caricate: {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "Usa /iris world create <name> <pack> per iniettarne una senza riavviare."
|
||||
takeover_set = "Acquisizione Iris di {dimensionId} impostata sul pack '{pack}', dimensione '{packDimension}'."
|
||||
takeover_cleared = "Acquisizione Iris di {dimensionId} disattivata; il generatore originale della dimensione torna al prossimo riavvio."
|
||||
takeover_not_configured = "Nessuna acquisizione Iris configurata per {dimensionId}."
|
||||
takeover_restart_required = "Riavvio necessario: al prossimo avvio i dati di chunk, entità, POI e Iris Mantle della dimensione vengono spostati in una cartella di recupero e rigenerati. I dati dei giocatori vengono mantenuti."
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "Scarica e gestisci le importazioni di datapack esterni da Modrinth"
|
||||
|
||||
@@ -449,6 +449,7 @@ operator_instruction = "コンソールから {command} を実行してくださ
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "次回の再起動時に既存のディメンションを Iris パックで引き継ぐか、引き継ぎを無効にします"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1090,6 +1091,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "現在読み込
|
||||
loaded_iris_dimensions = "読み込み済み Iris ディメンション: {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "再起動せずに注入するには /iris world create <name> <pack> を使用してください。"
|
||||
takeover_set = "{dimensionId} の Iris テイクオーバーをパック '{pack}'、ディメンション '{packDimension}' に設定しました。"
|
||||
takeover_cleared = "{dimensionId} の Iris テイクオーバーを無効にしました。次回の再起動でディメンション本来のジェネレーターに戻ります。"
|
||||
takeover_not_configured = "{dimensionId} には Iris テイクオーバーが設定されていません。"
|
||||
takeover_restart_required = "再起動が必要です: 次回の起動時に、このディメンションのチャンク、エンティティ、POI、Iris Mantle データを復旧フォルダーへ移動して再生成します。プレイヤーデータは保持されます。"
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "外部データパックのインポートをダウンロードして管理します(Modrinth)"
|
||||
|
||||
@@ -449,6 +449,7 @@ operator_instruction = "콘솔에서 {command}을(를) 실행하세요(싱글
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "다음 재시작 시 기존 차원을 Iris 팩으로 인수하거나 인수를 해제합니다"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1090,6 +1091,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "현재 로드된
|
||||
loaded_iris_dimensions = "로드 중 ... Iris 크기: {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "재시작하지 않고 주입하려면 /iris world create <name> <pack>을(를) 사용하세요."
|
||||
takeover_set = "{dimensionId}의 Iris 인수를 팩 '{pack}', 차원 '{packDimension}'(으)로 설정했습니다."
|
||||
takeover_cleared = "{dimensionId}의 Iris 인수를 해제했습니다. 다음 재시작 시 차원 고유의 생성기로 돌아갑니다."
|
||||
takeover_not_configured = "{dimensionId}에 설정된 Iris 인수가 없습니다."
|
||||
takeover_restart_required = "재시작 필요: 다음 시작 시 이 차원의 청크, 엔티티, POI, Iris Mantle 데이터가 복구 폴더로 이동되고 다시 생성됩니다. 플레이어 데이터는 유지됩니다."
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "외부 데이터 팩 가져오기를 다운로드하고 관리합니다(Modrinth)"
|
||||
|
||||
@@ -451,6 +451,7 @@ operator_instruction = "Vykdyti {command} iš konsolės (arba leidžia cheats į
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "Kito paleidimo iš naujo metu perimti esamą dimensiją Iris paketu arba išjungti perėmimą"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1092,6 +1093,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "Ne Iris šiuo me
|
||||
loaded_iris_dimensions = "Įkelta Iris matmenys: {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "Naudojimas /iris world create <name> <pack> švirkšti vieną nepradedant iš naujo."
|
||||
takeover_set = "Iris perėmimas dimensijai {dimensionId} nustatytas į paketą '{pack}', dimensiją '{packDimension}'."
|
||||
takeover_cleared = "Iris perėmimas dimensijai {dimensionId} išjungtas; dimensijos nuosavas generatorius grįš kito paleidimo iš naujo metu."
|
||||
takeover_not_configured = "Dimensijai {dimensionId} nesukonfigūruotas joks Iris perėmimas."
|
||||
takeover_restart_required = "Reikia paleisti iš naujo: kito paleidimo metu dimensijos chunk, esybių, POI ir Iris Mantle duomenys perkeliami į atkūrimo aplanką ir sugeneruojami iš naujo. Žaidėjų duomenys išsaugomi."
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "Parsisiųsti & valdyti išorės importą (Modrinth)"
|
||||
|
||||
@@ -446,6 +446,7 @@ operator_instruction = "Start {command} vanaf de console (of schakel bedrog in s
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "Neem bij de volgende herstart een bestaande dimensie over met een Iris-pack, of schakel de overname uit"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1087,6 +1088,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "Nee Iris De afme
|
||||
loaded_iris_dimensions = "Geladen Iris afmetingen: {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "Gebruik /iris world create <name> <pack> om er één te injecteren zonder opnieuw te starten."
|
||||
takeover_set = "Iris-overname van {dimensionId} ingesteld op pack '{pack}', dimensie '{packDimension}'."
|
||||
takeover_cleared = "Iris-overname van {dimensionId} uitgeschakeld; de eigen generator van de dimensie keert terug bij de volgende herstart."
|
||||
takeover_not_configured = "Er is geen Iris-overname ingesteld voor {dimensionId}."
|
||||
takeover_restart_required = "Herstart vereist: bij de volgende start worden de chunk-, entiteit-, POI- en Iris Mantle-gegevens van de dimensie naar een herstelmap verplaatst en opnieuw gegenereerd. Spelergegevens blijven behouden."
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "Downloaden & de invoer van externe datapacks beheren (Modrinth)"
|
||||
|
||||
@@ -451,6 +451,7 @@ operator_instruction = "Biegnij {command} z konsoli (lub włączyć cheats w sin
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "Przejmij istniejący wymiar pakietem Iris przy następnym restarcie lub wyłącz przejęcie"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1092,6 +1093,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "Nie. Iris wymiar
|
||||
loaded_iris_dimensions = "Załadowane Iris wymiary: {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "Stosowanie /iris world create <name> <pack> wykonać wstrzyknięcie bez ponownego uruchamiania."
|
||||
takeover_set = "Przejęcie Iris wymiaru {dimensionId} ustawiono na pakiet '{pack}', wymiar '{packDimension}'."
|
||||
takeover_cleared = "Przejęcie Iris wymiaru {dimensionId} wyłączone; własny generator wymiaru wróci przy następnym restarcie."
|
||||
takeover_not_configured = "Dla {dimensionId} nie skonfigurowano przejęcia Iris."
|
||||
takeover_restart_required = "Wymagany restart: przy następnym uruchomieniu dane chunków, bytów, POI i Iris Mantle tego wymiaru zostaną przeniesione do folderu odzyskiwania i wygenerowane od nowa. Dane graczy zostają zachowane."
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "Pobierz & zarządzanie importem zewnętrznych danych (Modrinth)"
|
||||
|
||||
@@ -446,6 +446,7 @@ operator_instruction = "Executar {command} a partir do console (ou habilitar fra
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "Assumir o controlo de uma dimensão existente com um pack Iris no próximo reinício, ou desativá-lo"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1087,6 +1088,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "Não Iris as dim
|
||||
loaded_iris_dimensions = "Carregado Iris dimensões: {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "Utilização /iris world create <name> <pack> injectar um sem reiniciar."
|
||||
takeover_set = "Controlo Iris de {dimensionId} definido para o pack '{pack}', dimensão '{packDimension}'."
|
||||
takeover_cleared = "Controlo Iris de {dimensionId} desativado; o gerador próprio da dimensão regressa no próximo reinício."
|
||||
takeover_not_configured = "Não há nenhum controlo Iris configurado para {dimensionId}."
|
||||
takeover_restart_required = "Reinício necessário: no próximo arranque, os dados de chunks, entidades, POI e Iris Mantle da dimensão são movidos para uma pasta de recuperação e regenerados. Os dados dos jogadores são mantidos."
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "Baixar & gerir as importações de pacotes de dados externos (Modrinth)"
|
||||
|
||||
@@ -451,6 +451,7 @@ operator_instruction = "Беги. {command} от консоли (или вклю
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "Перехватить существующее измерение пакетом Iris при следующем перезапуске или отключить перехват"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1092,6 +1093,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "Нет. Iris В
|
||||
loaded_iris_dimensions = "загруженный Iris размеры: {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "Использовать /iris world create <name> <pack> Вводить один без перезапуска."
|
||||
takeover_set = "Перехват Iris для {dimensionId} настроен на пакет '{pack}', измерение '{packDimension}'."
|
||||
takeover_cleared = "Перехват Iris для {dimensionId} отключён; собственный генератор измерения вернётся при следующем перезапуске."
|
||||
takeover_not_configured = "Для {dimensionId} перехват Iris не настроен."
|
||||
takeover_restart_required = "Требуется перезапуск: при следующем запуске данные чанков, сущностей, POI и Iris Mantle этого измерения будут перемещены в папку восстановления и сгенерированы заново. Данные игроков сохраняются."
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "& управляет внешним импортом пакетов данных (Modrinth)"
|
||||
|
||||
@@ -451,6 +451,7 @@ operator_instruction = "{command} komutunu konsoldan çalıştırın (veya tek o
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "Bir sonraki yeniden başlatmada mevcut bir boyutu bir Iris paketiyle devral veya devralmayı kapat"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1092,6 +1093,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "Hayır Iris Boyu
|
||||
loaded_iris_dimensions = "Yüklendi Iris Boyut: {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "Kullanım Kullanımı /iris world create <name> <pack> Yeniden başlatmadan birini enjekte etmek."
|
||||
takeover_set = "{dimensionId} için Iris devralması '{pack}' paketine, '{packDimension}' boyutuna ayarlandı."
|
||||
takeover_cleared = "{dimensionId} için Iris devralması kapatıldı; boyutun kendi üreticisi bir sonraki yeniden başlatmada geri gelir."
|
||||
takeover_not_configured = "{dimensionId} için yapılandırılmış bir Iris devralması yok."
|
||||
takeover_restart_required = "Yeniden başlatma gerekli: bir sonraki başlatmada boyutun chunk, varlık, POI ve Iris Mantle verileri bir kurtarma klasörüne taşınır ve yeniden oluşturulur. Oyuncu verileri korunur."
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "Download indir & Dış veri paketi ithalatını yönetin (Modrinth)"
|
||||
|
||||
@@ -449,6 +449,7 @@ operator_instruction = "Chạy {command} từ bàn giao tiếp (hoặc kích ho
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "Tiếp quản một chiều không gian hiện có bằng gói Iris ở lần khởi động lại tiếp theo, hoặc tắt việc tiếp quản"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1090,6 +1091,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "Không Iris Kíc
|
||||
loaded_iris_dimensions = "Đã nạp Iris Kích thước: {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "Dùng /iris world create <name> <pack> tiêm một mũi mà không khởi động lại."
|
||||
takeover_set = "Đã đặt Iris tiếp quản {dimensionId} bằng gói '{pack}', chiều không gian '{packDimension}'."
|
||||
takeover_cleared = "Đã tắt Iris tiếp quản {dimensionId}; bộ tạo riêng của chiều không gian sẽ trở lại ở lần khởi động lại tiếp theo."
|
||||
takeover_not_configured = "Không có Iris tiếp quản nào được cấu hình cho {dimensionId}."
|
||||
takeover_restart_required = "Cần khởi động lại: ở lần khởi động tiếp theo, dữ liệu chunk, thực thể, POI và Iris Mantle của chiều không gian sẽ được chuyển vào thư mục khôi phục và tạo lại. Dữ liệu người chơi được giữ nguyên."
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "Tải về & Quản lý các tập dữ liệu bên ngoài (Modrinth)"
|
||||
|
||||
@@ -449,6 +449,7 @@ operator_instruction = "请从控制台执行 {command}(或在单人游戏中
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "在下次重启时用 Iris 资源包接管现有维度,或关闭接管"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1090,6 +1091,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "没有 Iris 维
|
||||
loaded_iris_dimensions = "已加载 Iris 维度 : {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "使用 /iris world create <name> <pack> 在不重新启动的情况下注入一个。"
|
||||
takeover_set = "已将 {dimensionId} 的 Iris 接管设置为资源包 '{pack}',维度 '{packDimension}'。"
|
||||
takeover_cleared = "已关闭 {dimensionId} 的 Iris 接管;下次重启后该维度将恢复使用其自身的生成器。"
|
||||
takeover_not_configured = "{dimensionId} 未配置 Iris 接管。"
|
||||
takeover_restart_required = "需要重启:下次启动时,该维度的区块、实体、POI 和 Iris Mantle 数据将移至恢复文件夹并重新生成。玩家数据将被保留。"
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "下载 & 管理外部数据包进口(Modrinth)"
|
||||
|
||||
@@ -449,6 +449,7 @@ operator_instruction = "請從主控台執行 {command}(或在單人遊戲中
|
||||
"entry.command.height" = "Print the current dimension height range"
|
||||
"entry.command.worlds" = "List loaded dimensions and identify the Iris-generated dimensions"
|
||||
"entry.command.mainworld" = "Configure or clear the Iris primary-world preset used on restart"
|
||||
"entry.command.takeover" = "在下次重新啟動時用 Iris 資源包接管現有維度,或關閉接管"
|
||||
"entry.command.object.we" = "Explain why WorldEdit selection import requires the Bukkit plugin"
|
||||
"entry.command.object.studio" = "Explain why the object studio world requires the Bukkit toolchain"
|
||||
"entry.command.object.convert" = "Explain why schematic conversion requires the Bukkit plugin"
|
||||
@@ -1090,6 +1091,10 @@ no_iris_dimensions_are_currently_loaded_create_one_with_iris = "沒有 Iris 維
|
||||
loaded_iris_dimensions = "已載入 Iris 維度 : {value}"
|
||||
message_2 = " - {dimension}"
|
||||
use_iris_world_create_name_pack_inject_one_without_restarting = "使用 /iris world create <name> <pack> 在不重新啟動的情況下注入一個。"
|
||||
takeover_set = "已將 {dimensionId} 的 Iris 接管設定為資源包 '{pack}',維度 '{packDimension}'。"
|
||||
takeover_cleared = "已關閉 {dimensionId} 的 Iris 接管;下次重新啟動後該維度將恢復使用其自身的生成器。"
|
||||
takeover_not_configured = "{dimensionId} 未設定 Iris 接管。"
|
||||
takeover_restart_required = "需要重新啟動:下次啟動時,該維度的區塊、實體、POI 與 Iris Mantle 資料將移至復原資料夾並重新生成。玩家資料將會保留。"
|
||||
|
||||
[iris.director.commanddatapack]
|
||||
"director.download_manage_external_datapack_imports_modrinth" = "下載 & 管理外部資料包進口(Modrinth)"
|
||||
|
||||
+79
@@ -6,6 +6,7 @@ import art.arcane.iris.world.IrisEnvironment;
|
||||
import org.junit.Test;
|
||||
|
||||
import static art.arcane.iris.generation.terrain.IrisDimensionTypeOptions.TriState.TRUE;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@@ -137,6 +138,84 @@ public class IrisDimensionRuntimeContractTest {
|
||||
IrisDimensionRuntimeContract.requireHotloadCompatible("Studio world", active, replacement, "iris");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expectedContractUsesTheBorrowedTypeKey() {
|
||||
IrisDimension dimension = borrowedDimension("aether:the_aether", 0, 256);
|
||||
|
||||
assertEquals("aether:the_aether", IrisDimensionRuntimeContract.expected(dimension, "iris").typeKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void borrowedTypeAcceptsAPackRangeInsideTheBorrowedRange() {
|
||||
IrisDimensionRuntimeContract expected = IrisDimensionRuntimeContract.expected(
|
||||
borrowedDimension("aether:the_aether", 0, 192), "iris");
|
||||
|
||||
expected.requireBorrowedFit("Modded level 'aether:the_aether'",
|
||||
new IrisDimensionRuntimeContract("aether:the_aether", 0, 256, 256));
|
||||
expected.requireBorrowedFit("Modded level 'aether:the_aether'",
|
||||
new IrisDimensionRuntimeContract("aether:the_aether", 0, 192, 64));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void borrowedTypeRejectsAPackTopAboveTheBorrowedTop() {
|
||||
IrisDimensionRuntimeContract expected = IrisDimensionRuntimeContract.expected(
|
||||
borrowedDimension("aether:the_aether", 0, 320), "iris");
|
||||
|
||||
assertBorrowedFitRejected(expected, new IrisDimensionRuntimeContract("aether:the_aether", 0, 256, 256),
|
||||
"0..320", "0..256");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void borrowedTypeRejectsAPackMinimumThatDiffersFromTheBorrowedMinimum() {
|
||||
IrisDimensionRuntimeContract expected = IrisDimensionRuntimeContract.expected(
|
||||
borrowedDimension("aether:the_aether", 16, 256), "iris");
|
||||
|
||||
assertBorrowedFitRejected(expected, new IrisDimensionRuntimeContract("aether:the_aether", 0, 256, 256),
|
||||
"16..256", "0..256");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void borrowedTypeRejectsALevelUsingAnotherType() {
|
||||
IrisDimensionRuntimeContract expected = IrisDimensionRuntimeContract.expected(
|
||||
borrowedDimension("aether:the_aether", 0, 256), "iris");
|
||||
|
||||
assertBorrowedFitRejected(expected, new IrisDimensionRuntimeContract("minecraft:overworld", 0, 256, 256),
|
||||
"aether:the_aether", "minecraft:overworld");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hotloadRejectsBorrowedTypeChanges() {
|
||||
IrisDimension active = hotloadDimension();
|
||||
IrisDimension replacement = hotloadDimension();
|
||||
replacement.setBorrowedDimensionType("aether:the_aether");
|
||||
|
||||
assertHotloadRejected(active, replacement, "aether:the_aether");
|
||||
}
|
||||
|
||||
private IrisDimension borrowedDimension(String typeKey, int minHeight, int maxHeight) {
|
||||
IrisDimension dimension = new IrisDimension();
|
||||
dimension.setLoadKey("skylands");
|
||||
dimension.setBorrowedDimensionType(typeKey);
|
||||
dimension.setDimensionHeight(new IrisRange(minHeight, maxHeight));
|
||||
dimension.setLogicalHeight(maxHeight - minHeight);
|
||||
return dimension;
|
||||
}
|
||||
|
||||
private void assertBorrowedFitRejected(IrisDimensionRuntimeContract expected,
|
||||
IrisDimensionRuntimeContract actual,
|
||||
String expectedFragment,
|
||||
String actualFragment) {
|
||||
try {
|
||||
expected.requireBorrowedFit("Modded level 'aether:the_aether'", actual);
|
||||
fail("A borrowed dimension type that cannot hold the pack range must be rejected");
|
||||
} catch (IrisDimensionContractException e) {
|
||||
assertTrue(e.getMessage(), e.getMessage().contains("Modded level 'aether:the_aether'"));
|
||||
assertTrue(e.getMessage(), e.getMessage().contains(expectedFragment));
|
||||
assertTrue(e.getMessage(), e.getMessage().contains(actualFragment));
|
||||
assertTrue(e.getMessage(), e.getMessage().contains("Generation was refused"));
|
||||
}
|
||||
}
|
||||
|
||||
private IrisDimensionRuntimeContract expectedContract() {
|
||||
IrisDimension dimension = new IrisDimension();
|
||||
dimension.setLoadKey("overworld");
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Servers
|
||||
* Copyright (c) 2026 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package art.arcane.iris.pack;
|
||||
|
||||
import art.arcane.volmlib.util.json.JSONObject;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class PackValidatorBorrowedDimensionTypeTest {
|
||||
@Test
|
||||
public void acceptsAbsentEmptyAndRegistryKeys() {
|
||||
assertTrue(validate("{}").isEmpty());
|
||||
assertTrue(validate("{\"borrowedDimensionType\":\"\"}").isEmpty());
|
||||
assertTrue(validate("{\"borrowedDimensionType\":\"aether:the_aether\"}").isEmpty());
|
||||
assertTrue(validate("{\"borrowedDimensionType\":\"minecraft:the_end\"}").isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rejectsValuesThatAreNotNamespacedRegistryKeys() {
|
||||
assertEquals(List.of("Dimension 'main' borrowedDimensionType must be a namespaced dimension type key such as aether:the_aether, but was 'the_aether'."),
|
||||
validate("{\"borrowedDimensionType\":\"the_aether\"}"));
|
||||
assertEquals(List.of("Dimension 'main' borrowedDimensionType must be a namespaced dimension type key such as aether:the_aether, but was 'Aether:The Aether'."),
|
||||
validate("{\"borrowedDimensionType\":\"Aether:The Aether\"}"));
|
||||
assertEquals(List.of("Dimension 'main' borrowedDimensionType must be a namespaced dimension type key such as aether:the_aether, but was '42'."),
|
||||
validate("{\"borrowedDimensionType\":42}"));
|
||||
}
|
||||
|
||||
private static List<String> validate(String json) {
|
||||
List<String> errors = new ArrayList<>();
|
||||
PackDimensionValidator.validateBorrowedDimensionType("main", new JSONObject(json), errors);
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
@@ -83,7 +83,7 @@ public class SchemaBuilderIdentityTest {
|
||||
@ClassRule
|
||||
public static final PlatformLeakGuard PLATFORM_GUARD = PlatformLeakGuard.clean();
|
||||
|
||||
private static final String EXPECTED_SCHEMA_DIGEST = "1720dcd78ce7d4ef6fc601cb8d8703d42a35625e8038ab04e98db03514df5959";
|
||||
private static final String EXPECTED_SCHEMA_DIGEST = "2db2ba19e3466b7c686adca580943c1cc832bf0b44a0568e8db86a920116cfc0";
|
||||
|
||||
private static final List<Class<?>> SCHEMA_ROOTS = List.of(
|
||||
IrisDimension.class,
|
||||
|
||||
+34
@@ -153,6 +153,40 @@ public class GenerationRegistryContractFactoryTest {
|
||||
)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void borrowedDimensionTypeIsRecordedAsAnExternalDefinitionInsteadOfAGeneratedType() throws Exception {
|
||||
File pack = temporary.newFolder("borrowed-pack");
|
||||
IrisData data = mock(IrisData.class);
|
||||
when(data.getDataFolder()).thenReturn(pack);
|
||||
when(data.getContentGate()).thenReturn(mock(ContentGate.class));
|
||||
IrisDimension dimension = spy(new IrisDimension().setBorrowedDimensionType("aether:the_aether"));
|
||||
dimension.setLoadKey("skylands");
|
||||
stubDimensions(data, dimension);
|
||||
doReturn(new KList<>()).when(dimension).getReachableBiomes(any());
|
||||
doReturn(new KList<>()).when(dimension).getAllRegions(any());
|
||||
PlatformRegistries registries = mock(PlatformRegistries.class);
|
||||
when(registries.blockTypeKeys()).thenReturn(new KList<>());
|
||||
when(registries.entityKeys()).thenReturn(new KList<>());
|
||||
FakeGenerationRegistry generationRegistry = new FakeGenerationRegistry("test-runtime");
|
||||
|
||||
GenerationRegistryContract contract = GenerationRegistryContractFactory.create(
|
||||
data,
|
||||
dimension,
|
||||
GenerationPackFingerprint.compute(pack.toPath(), GenerationPackFingerprint.CURRENT_VERSION),
|
||||
DataVersion.getLatest().get(),
|
||||
registries,
|
||||
generationRegistry
|
||||
);
|
||||
|
||||
GenerationRegistryContract.PhysicalResourceKey borrowed = key(
|
||||
GenerationRegistryContractFactory.DIMENSION_TYPE_REGISTRY, "aether:the_aether");
|
||||
assertTrue(contract.definitions().containsKey(borrowed));
|
||||
assertFalse(contract.generatedSources().containsKey(borrowed));
|
||||
assertFalse(contract.definitions().containsKey(key(
|
||||
GenerationRegistryContractFactory.DIMENSION_TYPE_REGISTRY, "test:skylands_type")));
|
||||
assertEquals("aether:the_aether", dimension.dimensionTypeResourceKey(generationRegistry, "borrowed-pack"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void duplicateLogicalBiomeIdsKeepExactDefinitionsAndChooseStableLegacyAlias() throws Exception {
|
||||
File pack = temporary.newFolder("duplicate-biomes");
|
||||
|
||||
Reference in new issue
Block a user