mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-25 13:30:08 +00:00
Give each procedural type its own schema
Shared folder mixed tree and coral schemas.
This commit is contained in:
1 parent
9d7211378d
commit
2659837007
16 files changed
+40
-29
No files matched your search
@@ -638,13 +638,17 @@ public class SchemaBuilder {
|
||||
JSONArray arr = new JSONArray();
|
||||
JSONObject str = new JSONObject();
|
||||
str.put("type", "string");
|
||||
String key = "enum-snippet-" + snippet.value();
|
||||
String key = "enum-snippet-" + snippet.value().replace('/', '-');
|
||||
str.put("$ref", "#/definitions/" + key);
|
||||
|
||||
if (!definitions.containsKey(key)) {
|
||||
JSONObject j = new JSONObject();
|
||||
JSONArray snl = new JSONArray();
|
||||
data.getPossibleSnippets(snippet.value()).forEach(snl::put);
|
||||
String folderReferencePrefix = "snippet/" + snippet.value() + "/";
|
||||
data.getPossibleSnippets(snippet.value()).forEach(reference -> {
|
||||
snl.put(folderReferencePrefix + reference.substring("snippet/".length()));
|
||||
snl.put(reference);
|
||||
});
|
||||
j.put("enum", snl);
|
||||
definitions.put(key, j);
|
||||
}
|
||||
@@ -724,7 +728,7 @@ public class SchemaBuilder {
|
||||
return "string";
|
||||
}
|
||||
|
||||
if (c.equals(KList.class)) {
|
||||
if (List.class.isAssignableFrom(c)) {
|
||||
return "array";
|
||||
}
|
||||
|
||||
|
||||
+19
-12
@@ -22,6 +22,7 @@ import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.loader.IrisData;
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
import com.volmit.iris.engine.object.IrisRegion;
|
||||
import com.volmit.iris.engine.object.annotations.Snippet;
|
||||
import com.volmit.iris.engine.object.procedural.coral.Coral;
|
||||
import com.volmit.iris.engine.object.procedural.coral.ResolvedCoral;
|
||||
import com.volmit.iris.engine.object.procedural.crystal.Crystal;
|
||||
@@ -55,15 +56,20 @@ import java.util.stream.Stream;
|
||||
*/
|
||||
public final class ProceduralObjectCatalog {
|
||||
private static final Gson DEFINITION_JSON = new Gson();
|
||||
/** The snippet folder every procedural setting shares, so all of them live under {@code snippet/procedural}. */
|
||||
/**
|
||||
* The snippet folder all procedural settings live under. Each type keeps its own subfolder because the editor
|
||||
* validates a snippet folder against a single schema.
|
||||
*/
|
||||
public static final String SNIPPET_FOLDER = "procedural";
|
||||
private static final Map<String, Class<?>> DEFINITION_TYPE_BY_FOLDER = Map.of(
|
||||
"trees", Tree.class,
|
||||
"ruins", Ruin.class,
|
||||
"formations", Formation.class,
|
||||
"coral", Coral.class,
|
||||
"fungi", Fungus.class,
|
||||
"crystals", Crystal.class);
|
||||
public static final String TREE_FOLDER = SNIPPET_FOLDER + "/trees";
|
||||
public static final String RUIN_FOLDER = SNIPPET_FOLDER + "/ruins";
|
||||
public static final String FORMATION_FOLDER = SNIPPET_FOLDER + "/formations";
|
||||
public static final String CORAL_FOLDER = SNIPPET_FOLDER + "/coral";
|
||||
public static final String FUNGUS_FOLDER = SNIPPET_FOLDER + "/fungi";
|
||||
public static final String CRYSTAL_FOLDER = SNIPPET_FOLDER + "/crystals";
|
||||
public static final String SET_FOLDER = SNIPPET_FOLDER + "/sets";
|
||||
public static final String PART_FOLDER = SNIPPET_FOLDER + "/parts";
|
||||
private static final List<Class<?>> DEFINITION_TYPES = List.of(Tree.class, Ruin.class, Formation.class, Coral.class, Fungus.class, Crystal.class);
|
||||
|
||||
private final IrisData data;
|
||||
private final KMap<String, ResolvedProceduralPlacement> byDefinition = new KMap<>();
|
||||
@@ -106,7 +112,7 @@ public final class ProceduralObjectCatalog {
|
||||
public List<Definition> definitions() {
|
||||
Map<ResolvedProceduralPlacement, String> pathByPlacement = new LinkedHashMap<>();
|
||||
Set<String> takenPaths = new HashSet<>();
|
||||
DEFINITION_TYPE_BY_FOLDER.forEach((folder, type) -> snippetDefinitions(folder, type)
|
||||
DEFINITION_TYPES.forEach(type -> snippetDefinitions(type)
|
||||
.forEach((path, definition) -> addDefinition(pathByPlacement, takenPaths, placementOf(definition), path)));
|
||||
Stream.concat(data.getRegionLoader().streamAll().map(IrisRegion::getProceduralObjects),
|
||||
data.getBiomeLoader().streamAll().map(IrisBiome::getProceduralObjects))
|
||||
@@ -132,9 +138,10 @@ public final class ProceduralObjectCatalog {
|
||||
}
|
||||
|
||||
/** The definitions in the snippet folder of one type, by their path under {@code snippet/procedural} without the extension. */
|
||||
private Map<String, Object> snippetDefinitions(String typeFolder, Class<?> type) {
|
||||
Path proceduralFolder = data.getDataFolder().toPath().resolve("snippet").resolve(SNIPPET_FOLDER);
|
||||
Path folder = proceduralFolder.resolve(typeFolder);
|
||||
private Map<String, Object> snippetDefinitions(Class<?> type) {
|
||||
Path snippetFolder = data.getDataFolder().toPath().resolve("snippet");
|
||||
Path proceduralFolder = snippetFolder.resolve(SNIPPET_FOLDER);
|
||||
Path folder = snippetFolder.resolve(type.getAnnotation(Snippet.class).value());
|
||||
if (!Files.isDirectory(folder)) {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ import java.util.List;
|
||||
* The procedural objects a region or biome declares, written as {@code "proceduralObjects": {"trees": [...], ...}}: things
|
||||
* Iris generates from scratch at world-gen time and places like object placements.
|
||||
*/
|
||||
@Snippet(ProceduralObjectCatalog.SNIPPET_FOLDER)
|
||||
@Snippet(ProceduralObjectCatalog.SET_FOLDER)
|
||||
@Desc("Procedurally generated objects placed in a biome or region. Unlike the objects block (which loads iob files), these are generated from scratch at world-gen time.")
|
||||
public final class ProceduralObjectSettings {
|
||||
private final transient AtomicCache<List<ResolvedProceduralPlacement>> resolved = new AtomicCache<>();
|
||||
|
||||
@@ -35,7 +35,7 @@ import com.volmit.iris.engine.object.annotations.Required;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Snippet(ProceduralObjectCatalog.SNIPPET_FOLDER)
|
||||
@Snippet(ProceduralObjectCatalog.CORAL_FOLDER)
|
||||
@Desc("A single procedurally generated coral reef structure. Iris bakes a pool of deterministic variants from these settings and scatters them across the seafloor at world-gen time, exactly like an object placement but generated from scratch instead of loaded from an iob file. Mirrors the procedural tree system but tuned for underwater reefs: structural blocks are waterlogged so the coral stays alive, and placement defaults to anchoring on the terrain beneath the water surface.")
|
||||
public final class Coral {
|
||||
@Desc("A human readable name used in logs and as the variant load key.")
|
||||
|
||||
@@ -35,7 +35,7 @@ import com.volmit.iris.engine.object.annotations.Required;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Snippet(ProceduralObjectCatalog.SNIPPET_FOLDER)
|
||||
@Snippet(ProceduralObjectCatalog.CRYSTAL_FOLDER)
|
||||
@Desc("A single procedurally generated crystal cluster: a budding base blob with faceted, tapered shards radiating from it (geode / amethyst-style). Iris bakes a pool of deterministic variants from these settings and scatters them at world-gen time, exactly like an object placement but generated from scratch instead of loaded from an iob file. Built for caves.")
|
||||
public final class Crystal {
|
||||
@Desc("A human readable name used in logs and as the variant load key.")
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ import com.volmit.iris.engine.object.annotations.Required;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Snippet(ProceduralObjectCatalog.SNIPPET_FOLDER)
|
||||
@Snippet(ProceduralObjectCatalog.FORMATION_FOLDER)
|
||||
@Desc("A single procedurally generated natural formation, including rock landmarks and magical glacial silhouettes. Iris bakes a pool of deterministic variants from these settings and scatters them at world-gen time, exactly like an object placement but generated from scratch instead of loaded from an iob file.")
|
||||
public final class Formation {
|
||||
@Desc("A human readable name used in logs and as the variant load key.")
|
||||
|
||||
@@ -35,7 +35,7 @@ import com.volmit.iris.engine.object.annotations.Required;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Snippet(ProceduralObjectCatalog.SNIPPET_FOLDER)
|
||||
@Snippet(ProceduralObjectCatalog.FUNGUS_FOLDER)
|
||||
@Desc("A single procedurally generated fungus (giant mushroom or shelf fungus). Iris bakes a pool of deterministic variants from these settings and scatters them at world-gen time, exactly like an object placement but generated from scratch instead of loaded from an iob file. The fungus is built as a stem column with a cap dome grown on top, mirroring the trunk-and-canopy model used by procedural trees.")
|
||||
public final class Fungus {
|
||||
@Desc("A human readable name used in logs and as the variant load key.")
|
||||
|
||||
@@ -37,7 +37,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Snippet(ProceduralObjectCatalog.SNIPPET_FOLDER)
|
||||
@Snippet(ProceduralObjectCatalog.RUIN_FOLDER)
|
||||
@Desc("A single procedurally generated ruin: a crumbling man-made structure (pillar, wall, arch, foundation slab, or rubble pile). Iris bakes a pool of deterministic variants from these settings and scatters them at world-gen time, exactly like an object placement but generated from scratch instead of loaded from an iob file. Weathering swaps blocks for mossy or cracked variants by noise, erosion deletes blocks so the shape reads as collapsed, and a buried fraction sinks the ruin into the terrain.")
|
||||
public final class Ruin {
|
||||
@Desc("A human readable name used in logs and as the variant load key (procedural/<name>#<index>).")
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.volmit.iris.engine.object.annotations.Required;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Snippet(ProceduralObjectCatalog.SNIPPET_FOLDER)
|
||||
@Snippet(ProceduralObjectCatalog.PART_FOLDER + "/ruin-decorators")
|
||||
@Desc("An accent block applied to a generated ruin after it is built and eroded, such as moss carpets on broken tops, vines on the faces, or rubble scattered around the base.")
|
||||
public final class RuinDecorator {
|
||||
@Desc("Where on the ruin this accent is placed. TOP sits on the highest block of each column, SURFACE clings to air-facing vertical faces, BASE_SCATTER rings the ground footprint around the base.")
|
||||
|
||||
@@ -37,7 +37,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Snippet(ProceduralObjectCatalog.SNIPPET_FOLDER)
|
||||
@Snippet(ProceduralObjectCatalog.TREE_FOLDER)
|
||||
@Desc("A single procedurally generated tree. Iris bakes a pool of deterministic variants from these settings and scatters them at world-gen time, exactly like an object placement but generated from scratch instead of loaded from an iob file.")
|
||||
public final class Tree {
|
||||
@Desc("A human readable name used in logs and as the variant load key.")
|
||||
|
||||
@@ -26,7 +26,7 @@ import com.volmit.iris.engine.object.annotations.MinNumber;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Snippet(ProceduralObjectCatalog.SNIPPET_FOLDER)
|
||||
@Snippet(ProceduralObjectCatalog.PART_FOLDER + "/tree-branches")
|
||||
@Desc("A branch system that throws limbs out of the trunk and places a leaf ball at each tip. When present, branches drive the canopy and only the topmost crown disc of the profile is still placed.")
|
||||
public final class TreeBranches {
|
||||
@Desc("How branch spawn chance varies over trunk height.")
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Snippet(ProceduralObjectCatalog.SNIPPET_FOLDER)
|
||||
@Snippet(ProceduralObjectCatalog.PART_FOLDER + "/tree-canopies")
|
||||
@Desc("The leaf crown of a procedural tree. Built from stacked dome-shaped discs (driven by the profile or by explicit layers) and optionally a branch system.")
|
||||
public final class TreeCanopy {
|
||||
@MinNumber(0)
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.volmit.iris.engine.object.annotations.Required;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Snippet(ProceduralObjectCatalog.SNIPPET_FOLDER)
|
||||
@Snippet(ProceduralObjectCatalog.PART_FOLDER + "/tree-decorators")
|
||||
@Desc("An accent block applied to a generated tree such as fruit on branch tips, vines on the trunk, snow on the crown, or a glowing underside.")
|
||||
public final class TreeDecorator {
|
||||
@Desc("Where this decorator is placed on the tree.")
|
||||
|
||||
@@ -23,7 +23,7 @@ import com.volmit.iris.engine.object.annotations.Snippet;
|
||||
import com.volmit.iris.engine.object.procedural.ProceduralObjectCatalog;
|
||||
import com.volmit.iris.engine.object.annotations.MinNumber;
|
||||
|
||||
@Snippet(ProceduralObjectCatalog.SNIPPET_FOLDER)
|
||||
@Snippet(ProceduralObjectCatalog.PART_FOLDER + "/tree-layers")
|
||||
@Desc("An explicit canopy disc at a given vertical offset and radius. Define a list of these to bypass the profile and sculpt the crown by hand.")
|
||||
public final class TreeLayer {
|
||||
@Desc("The vertical offset of this disc, measured in blocks above the trunk base.")
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ import com.volmit.iris.engine.object.annotations.MinNumber;
|
||||
import com.volmit.iris.engine.object.annotations.RegistryListBlockType;
|
||||
import com.volmit.iris.engine.object.annotations.Required;
|
||||
|
||||
@Snippet(ProceduralObjectCatalog.SNIPPET_FOLDER)
|
||||
@Snippet(ProceduralObjectCatalog.PART_FOLDER + "/tree-secondary-leaves")
|
||||
@Desc("A weighted accent leaf or foliage block scattered through the canopy (blossoms, shroomlight, berries).")
|
||||
public final class TreeSecondaryLeaf {
|
||||
@Required
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import com.volmit.iris.engine.object.procedural.ProceduralObjectCatalog;
|
||||
import com.volmit.iris.engine.object.annotations.MaxNumber;
|
||||
import com.volmit.iris.engine.object.annotations.MinNumber;
|
||||
|
||||
@Snippet(ProceduralObjectCatalog.SNIPPET_FOLDER)
|
||||
@Snippet(ProceduralObjectCatalog.PART_FOLDER + "/tree-sub-branches")
|
||||
@Desc("One recursive level of sub-branches sprouting from each primary branch tip.")
|
||||
public final class TreeSubBranches {
|
||||
@MinNumber(1)
|
||||
|
||||
Reference in new issue
Block a user