This commit is contained in:
cyberpwn 2022-07-02 13:40:55 -04:00
parent 3339f77e1c
commit 6285651194
24 changed files with 869 additions and 44 deletions

View File

@ -24,8 +24,8 @@ allprojects {
compileOnly 'org.projectlombok:lombok:1.18.24' compileOnly 'org.projectlombok:lombok:1.18.24'
annotationProcessor 'org.projectlombok:lombok:1.18.24' annotationProcessor 'org.projectlombok:lombok:1.18.24'
implementation 'art.arcane.source:Source:22.6.9' implementation 'art.arcane.source:Source:22.6.9'
implementation 'art.arcane:Amulet:22.6.9' implementation 'art.arcane:Amulet:22.7.1'
implementation 'com.github.ben-manes.caffeine:caffeine:3.0.6' implementation 'com.github.ben-manes.caffeine:caffeine:3.1.1'
annotationProcessor 'systems.manifold:manifold-ext:2022.1.18' annotationProcessor 'systems.manifold:manifold-ext:2022.1.18'
testAnnotationProcessor 'systems.manifold:manifold-ext:2022.1.18' testAnnotationProcessor 'systems.manifold:manifold-ext:2022.1.18'
implementation 'systems.manifold:manifold-rt:2022.1.18' implementation 'systems.manifold:manifold-rt:2022.1.18'

View File

@ -5,4 +5,4 @@ api-version: 1.19
libraries: libraries:
- org.apache-extras.beanshell:bsh:2.0b6 - org.apache-extras.beanshell:bsh:2.0b6
- com.google.code.gson:gson:2.8.9 - com.google.code.gson:gson:2.8.9
- com.github.ben-manes.caffeine:caffeine:3.0.6 - com.github.ben-manes.caffeine:caffeine:3.1.1

View File

@ -5,11 +5,25 @@ import art.arcane.amulet.io.JarLoader;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapterFactory; import com.google.gson.TypeAdapterFactory;
import com.volmit.iris.engine.dimension.IrisAuthor;
import com.volmit.iris.engine.dimension.IrisBiome;
import com.volmit.iris.engine.dimension.IrisChance;
import com.volmit.iris.engine.dimension.IrisDecorator;
import com.volmit.iris.engine.dimension.IrisDimension;
import com.volmit.iris.engine.dimension.IrisDimensionMeta;
import com.volmit.iris.engine.dimension.IrisGenerator; import com.volmit.iris.engine.dimension.IrisGenerator;
import com.volmit.iris.engine.dimension.IrisPalette;
import com.volmit.iris.engine.dimension.IrisRange;
import com.volmit.iris.engine.dimension.IrisResolvable;
import com.volmit.iris.engine.dimension.IrisSeed;
import com.volmit.iris.engine.dimension.IrisSeedSetMode;
import com.volmit.iris.engine.dimension.IrisSurface;
import com.volmit.iris.engine.dimension.IrisSurfaceLayer;
import com.volmit.iris.engine.editor.Resolvable; import com.volmit.iris.engine.editor.Resolvable;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
@Data @Data
@ -25,6 +39,7 @@ public class EngineEditor {
.filter(Objects::nonNull) .filter(Objects::nonNull)
.filter(i -> !i.isInterface() && !i.isEnum()) .filter(i -> !i.isInterface() && !i.isEnum())
.filter(i -> i.isAssignableFrom(Resolvable.class) || Resolvable.class.isAssignableFrom(i)) .filter(i -> i.isAssignableFrom(Resolvable.class) || Resolvable.class.isAssignableFrom(i))
.filter(i -> !i.equals(IrisResolvable.class))
.map(i -> J.attempt(() -> (Resolvable) i.getDeclaredConstructor().newInstance(), null)).toList(), List.of()); .map(i -> J.attempt(() -> (Resolvable) i.getDeclaredConstructor().newInstance(), null)).toList(), List.of());
GsonBuilder gsonBuilder = new GsonBuilder(); GsonBuilder gsonBuilder = new GsonBuilder();
resolvableTypes.forEach(i -> i.apply(gsonBuilder)); resolvableTypes.forEach(i -> i.apply(gsonBuilder));
@ -32,5 +47,69 @@ public class EngineEditor {
i("Registered " + resolvableTypes.size() + " Mutators with " + resolvableTypes.stream().filter(i -> i instanceof TypeAdapterFactory).count() + " Type Adapter Factories"); i("Registered " + resolvableTypes.size() + " Mutators with " + resolvableTypes.stream().filter(i -> i instanceof TypeAdapterFactory).count() + " Type Adapter Factories");
i(gson.toJson(gson.fromJson("Noise.simplex(seed)", IrisGenerator.class))); i(gson.toJson(gson.fromJson("Noise.simplex(seed)", IrisGenerator.class)));
System.out.println(gson.toJson(IrisDimension.builder()
.biome(IrisBiome.builder()
.name("Plains")
.surface(IrisSurface.builder()
.decorator(IrisDecorator.builder()
.palette(IrisPalette.flat("minecraft:grass"))
.chance(IrisChance.half(IrisGenerator.builder()
.java("Noise.static(seed)")
.seed(IrisSeed.builder()
.offset(67)
.build())
.build()))
.build())
.layer(IrisSurfaceLayer.builder()
.palette(IrisPalette.flat("minecraft:grass_block"))
.thickness(IrisRange.flat(1))
.build())
.layer(IrisSurfaceLayer.builder()
.palette(IrisPalette.builder()
.block("minecraft:dirt")
.block("minecraft:coarse_dirt")
.build())
.thickness(IrisRange.builder()
.min(3)
.max(5)
.generator(IrisGenerator.builder()
.java("Noise.simplex(seed).warp(Noise.perlin(seed+1), 0.5, 9)")
.seed(IrisSeed.builder()
.offset(446)
.mode(IrisSeedSetMode.WORLD_OFFSET)
.build())
.build())
.build())
.build())
.layer(IrisSurfaceLayer.builder()
.palette(IrisPalette.builder()
.block("minecraft:stone")
.block("minecraft:granite")
.build())
.thickness(IrisRange.builder()
.min(3)
.max(7)
.generator(IrisGenerator.builder()
.java("Noise.simplex(seed).warp(Noise.perlin(seed+1), 0.5, 9)")
.seed(IrisSeed.builder()
.offset(123)
.mode(IrisSeedSetMode.WORLD_OFFSET)
.build())
.build())
.build())
.build())
.build())
.build())
.meta(IrisDimensionMeta.builder()
.name("Overworld")
.description("The overworld generates stuff")
.version("3.0.0")
.author(IrisAuthor.builder()
.name("cyberpwn")
.social(Map.of("discord", "cyberpwn#1337"))
.build())
.build())
.build()));
} }
} }

View File

@ -4,6 +4,7 @@ import com.volmit.iris.engine.editor.Resolvable;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@ -13,8 +14,10 @@ import java.util.Map;
@NoArgsConstructor @NoArgsConstructor
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@EqualsAndHashCode(callSuper=false)
@Accessors(fluent = true, chain = true) @Accessors(fluent = true, chain = true)
public class IrisDimensionAuthor implements Resolvable @Resolvable.Entity(id = "author")
public class IrisAuthor extends IrisResolvable
{ {
private String name; private String name;
private Map<String, String> social; private Map<String, String> social;

View File

@ -1,17 +1,27 @@
package com.volmit.iris.engine.dimension; package com.volmit.iris.engine.dimension;
import com.google.gson.stream.JsonToken;
import com.volmit.iris.engine.editor.Resolvable; import com.volmit.iris.engine.editor.Resolvable;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.util.ArrayList;
import java.util.List;
@Builder @Builder
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@EqualsAndHashCode(callSuper=false)
@Accessors(fluent = true, chain = true) @Accessors(fluent = true, chain = true)
public class IrisBiome implements Resolvable { @Resolvable.Entity(id = "biome")
public class IrisBiome extends IrisResolvable {
private String name; private String name;
@Builder.Default
private IrisSurface surface = new IrisSurface();
} }

View File

@ -0,0 +1,73 @@
package com.volmit.iris.engine.dimension;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.volmit.iris.engine.editor.Resolvable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.IOException;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper=false)
@Accessors(fluent = true, chain = true)
@Resolvable.Entity(id = "chance", jsonTypes = {JsonToken.STRING, JsonToken.BEGIN_OBJECT})
public class IrisChance extends IrisResolvable implements TypeAdapterFactory {
@Builder.Default
@TokenConstructor(JsonToken.NUMBER)
private double threshold = 0.5;
@TokenConstructor(JsonToken.STRING)
@Builder.Default
private IrisGenerator generator = IrisGenerator.WHITE;
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
if(!type.getRawType().equals(getClass())) {
return null;
}
return new TypeAdapter<>() {
public void write(JsonWriter out, T value) {writeSafeJson(delegate, out, value);}
@SuppressWarnings("unchecked")
public T read(JsonReader in) throws IOException {
JsonToken token = in.peek();
if(token == JsonToken.STRING) {
return (T) IrisChance.half(gson.fromJson(in.nextString(), IrisGenerator.class));
}
return delegate.read(in);
}
};
}
public static IrisChance half(IrisGenerator generator) {
return IrisChance.builder()
.threshold(0.5)
.generator(generator)
.build();
}
public static IrisChance white(double chance) {
return IrisChance.builder()
.threshold(chance)
.generator(IrisGenerator.WHITE)
.build();
}
}

View File

@ -0,0 +1,28 @@
package com.volmit.iris.engine.dimension;
import com.volmit.iris.engine.editor.Resolvable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.Singular;
import lombok.experimental.Accessors;
import java.util.ArrayList;
import java.util.List;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper=false)
@Accessors(fluent = true, chain = true)
@Resolvable.Entity(id = "decorator")
public class IrisDecorator extends IrisResolvable {
@Builder.Default
private IrisPalette palette = IrisPalette.flat("minecraft:grass");
@Builder.Default
private IrisChance chance = IrisChance.white(0.25);
}

View File

@ -4,16 +4,26 @@ import com.volmit.iris.engine.editor.Resolvable;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Singular;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.util.ArrayList;
import java.util.List;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@EqualsAndHashCode(callSuper=false)
@Accessors(fluent = true, chain = true) @Accessors(fluent = true, chain = true)
public class IrisDimension implements Resolvable @Resolvable.Entity(id = "dimension")
{ public class IrisDimension extends IrisResolvable {
@Builder.Default @Builder.Default
private IrisDimensionMeta meta = new IrisDimensionMeta(); private IrisDimensionMeta meta = new IrisDimensionMeta();
@Singular
@Type(IrisBiome.class)
private List<IrisBiome> biomes = new ArrayList<>();
} }

View File

@ -4,6 +4,7 @@ import com.volmit.iris.engine.editor.Resolvable;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Singular; import lombok.Singular;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@ -15,12 +16,15 @@ import java.util.List;
@NoArgsConstructor @NoArgsConstructor
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@EqualsAndHashCode(callSuper=false)
@Accessors(fluent = true, chain = true) @Accessors(fluent = true, chain = true)
public class IrisDimensionMeta implements Resolvable @Resolvable.Entity(id = "dimension-meta")
public class IrisDimensionMeta extends IrisResolvable
{ {
private String name; private String name;
private String description; private String description;
private String version; private String version;
@Singular @Singular
private List<IrisDimensionAuthor> authors = new ArrayList<>(); @Resolvable.Type(IrisAuthor.class)
private List<IrisAuthor> authors = new ArrayList<>();
} }

View File

@ -14,6 +14,7 @@ import com.volmit.iris.engine.editor.Resolvable;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@ -24,13 +25,19 @@ import java.io.IOException;
@NoArgsConstructor @NoArgsConstructor
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@EqualsAndHashCode(callSuper=false)
@Accessors(fluent = true, chain = true) @Accessors(fluent = true, chain = true)
public class IrisGenerator implements Resolvable, TypeAdapterFactory { @Resolvable.Entity(id = "generator", jsonTypes = {JsonToken.STRING, JsonToken.BEGIN_OBJECT})
public class IrisGenerator extends IrisResolvable implements TypeAdapterFactory {
public static final IrisGenerator NATURAL = IrisGenerator.builder().java("art.arcane.source.api.util.NoisePreset.NATURAL.create(seed)").build();
public static final IrisGenerator WHITE = IrisGenerator.builder().java("Noise.white(seed)").build();
public static final IrisGenerator FLAT = IrisGenerator.builder().java("Noise.flat(seed)").build();
@Builder.Default @Builder.Default
private String java = "art.arcane.source.api.util.NoisePreset.NATURAL.create(seed)"; private String java = "art.arcane.source.api.util.NoisePreset.NATURAL.create(seed)";
@Builder.Default @Builder.Default
private IrisSeedSet seed = new IrisSeedSet(); private IrisSeed seed = new IrisSeed();
public NoisePlane getNoisePlane(long seed) public NoisePlane getNoisePlane(long seed)
{ {
@ -53,11 +60,11 @@ public class IrisGenerator implements Resolvable, TypeAdapterFactory {
return new TypeAdapter<>() { return new TypeAdapter<>() {
public void write(JsonWriter out, T value) {writeSafeJson(delegate, out, value);} public void write(JsonWriter out, T value) {writeSafeJson(delegate, out, value);}
@SuppressWarnings("unchecked")
public T read(JsonReader in) throws IOException { public T read(JsonReader in) throws IOException {
JsonToken token = in.peek(); JsonToken token = in.peek();
if(token == JsonToken.STRING) if(token == JsonToken.STRING) {
{
return (T) IrisGenerator.builder().java(in.nextString()).build(); return (T) IrisGenerator.builder().java(in.nextString()).build();
} }

View File

@ -0,0 +1,74 @@
package com.volmit.iris.engine.dimension;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.volmit.iris.engine.editor.Resolvable;
import com.volmit.iris.platform.PlatformBlock;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.Singular;
import lombok.ToString;
import lombok.experimental.Accessors;
import org.apache.commons.lang3.builder.ToStringExclude;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper=false)
@Accessors(fluent = true, chain = true)
@Resolvable.Entity(id = "palette")
public class IrisPalette extends IrisResolvable implements TypeAdapterFactory {
@Singular
@PlatformType(PlatformBlock.class)
@TokenConstructor(JsonToken.STRING)
private List<String> blocks = new ArrayList<>();
@Builder.Default
private IrisGenerator generator = IrisGenerator.WHITE;
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
if(!type.getRawType().equals(getClass())) {
return null;
}
return new TypeAdapter<>() {
public void write(JsonWriter out, T value) {
writeSafeJson(delegate, out, value);
}
@SuppressWarnings("unchecked")
public T read(JsonReader in) throws IOException {
JsonToken token = in.peek();
if(token == JsonToken.STRING) {
return (T) IrisPalette.flat(in.nextString());
}
return delegate.read(in);
}
};
}
public static IrisPalette flat(String block){
return IrisPalette.builder()
.block(block)
.generator(IrisGenerator.FLAT)
.build();
}
}

View File

@ -0,0 +1,70 @@
package com.volmit.iris.engine.dimension;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.volmit.iris.engine.editor.Resolvable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.IOException;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper=false)
@Accessors(fluent = true, chain = true)
@Resolvable.Entity(id = "range", jsonTypes = {JsonToken.NUMBER, JsonToken.BEGIN_OBJECT})
public class IrisRange extends IrisResolvable implements TypeAdapterFactory {
@Builder.Default
@TokenConstructor(JsonToken.NUMBER)
private double max = 1;
@Builder.Default
private double min = 1;
@Builder.Default
private IrisGenerator generator = IrisGenerator.NATURAL;
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
if(!type.getRawType().equals(getClass())) {
return null;
}
return new TypeAdapter<>() {
public void write(JsonWriter out, T value) {writeSafeJson(delegate, out, value);}
@SuppressWarnings("unchecked")
public T read(JsonReader in) throws IOException {
JsonToken token = in.peek();
if(token == JsonToken.NUMBER) {
double d = in.nextDouble();
return (T) IrisRange.builder().min(d).max(d).generator(IrisGenerator.FLAT).build();
}
return delegate.read(in);
}
};
}
public static IrisRange flat(double v) {
return IrisRange.builder()
.max(v)
.min(v)
.generator(IrisGenerator.FLAT)
.build();
}
}

View File

@ -0,0 +1,15 @@
package com.volmit.iris.engine.dimension;
import com.volmit.iris.engine.editor.Resolvable;
import com.volmit.iris.platform.PlatformNamespaceKey;
import lombok.Data;
@Data
public class IrisResolvable implements Resolvable {
private PlatformNamespaceKey key;
@Override
public PlatformNamespaceKey getKey() {
return null;
}
}

View File

@ -0,0 +1,86 @@
package com.volmit.iris.engine.dimension;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.volmit.iris.engine.Engine;
import com.volmit.iris.engine.editor.Resolvable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.IOException;
@Data
@NoArgsConstructor
@Builder
@AllArgsConstructor
@EqualsAndHashCode(callSuper=false)
@Accessors(fluent = true, chain = true)
@Resolvable.Entity(id = "seed", jsonTypes = {JsonToken.NUMBER, JsonToken.STRING, JsonToken.BEGIN_OBJECT})
public class IrisSeed extends IrisResolvable implements TypeAdapterFactory {
@Builder.Default
private IrisSeedSetMode mode = IrisSeedSetMode.LOCAL_OFFSET;
@Builder.Default
@TokenConstructor(JsonToken.NUMBER)
private long offset = 0;
@TokenConstructor(JsonToken.STRING)
private String hashOffset;
public long getOffset() {
if(hashOffset != null && hashOffset.isNotEmpty()) {
return hashOffset.hashCode() + offset;
}
return offset;
}
public double getSeed(Engine engine, long localSeed) {
return switch(mode)
{
case WORLD -> engine.getSeedManager().getWorldSeed();
case LOCAL -> localSeed;
case LOCAL_OFFSET -> localSeed + getOffset();
case RAW -> getOffset();
case WORLD_OFFSET -> engine.getSeedManager().getWorldSeed() + getOffset();
case RANDOM -> (Math.random() * Long.MAX_VALUE) + (Math.random() * Long.MAX_VALUE);
};
}
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
if(!type.getRawType().equals(getClass())) {
return null;
}
return new TypeAdapter<>() {
public void write(JsonWriter out, T value) {writeSafeJson(delegate, out, value);}
@SuppressWarnings("unchecked")
public T read(JsonReader in) throws IOException {
JsonToken token = in.peek();
if(token == JsonToken.STRING) {
return (T) IrisSeed.builder().hashOffset(in.nextString()).build();
}
if(token == JsonToken.NUMBER) {
return (T) IrisSeed.builder().offset(Double.doubleToLongBits(in.nextDouble())).build();
}
return delegate.read(in);
}
};
}
}

View File

@ -1,30 +0,0 @@
package com.volmit.iris.engine.dimension;
import com.volmit.iris.engine.Engine;
import com.volmit.iris.engine.editor.Resolvable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(fluent = true, chain = true)
public class IrisSeedSet implements Resolvable {
private IrisSeedSetMode mode = IrisSeedSetMode.LOCAL_OFFSET;
private long offset = 1337;
public double getSeed(Engine engine, long localSeed)
{
return switch(mode)
{
case WORLD -> engine.getSeedManager().getWorldSeed();
case LOCAL -> localSeed;
case LOCAL_OFFSET -> localSeed + offset;
case RAW -> offset;
case WORLD_OFFSET -> engine.getSeedManager().getWorldSeed() + offset;
case RANDOM -> (Math.random() * Long.MAX_VALUE) + (Math.random() * Long.MAX_VALUE);
};
}
}

View File

@ -0,0 +1,39 @@
package com.volmit.iris.engine.dimension;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.volmit.iris.engine.editor.Resolvable;
import com.volmit.iris.platform.PlatformBlock;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.Singular;
import lombok.experimental.Accessors;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper=false)
@Accessors(fluent = true, chain = true)
@Resolvable.Entity(id = "surface-layer")
public class IrisSurface extends IrisResolvable {
@Singular
@Type(IrisSurfaceLayer.class)
private List<IrisSurfaceLayer> layers = new ArrayList<>();
@Singular
@Type(IrisDecorator.class)
private List<IrisDecorator> decorators = new ArrayList<>();
}

View File

@ -0,0 +1,27 @@
package com.volmit.iris.engine.dimension;
import com.google.gson.stream.JsonToken;
import com.volmit.iris.engine.editor.Resolvable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.util.List;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper=false)
@Accessors(fluent = true, chain = true)
@Resolvable.Entity(id = "surface-layer")
public class IrisSurfaceLayer extends IrisResolvable {
@Builder.Default
private IrisPalette palette = IrisPalette.flat("minecraft:stone");
@Builder.Default
private IrisRange thickness = IrisRange.flat(1);
}

View File

@ -1,13 +1,21 @@
package com.volmit.iris.engine.editor; package com.volmit.iris.engine.editor;
import art.arcane.amulet.format.Form;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter; import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory; import com.google.gson.TypeAdapterFactory;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter; import com.google.gson.stream.JsonWriter;
import com.volmit.iris.platform.PlatformNamespaced;
import lombok.AllArgsConstructor;
import java.io.IOException; import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public interface Resolvable { public interface Resolvable extends PlatformNamespaced {
default void apply(GsonBuilder builder) { default void apply(GsonBuilder builder) {
if(this instanceof TypeAdapterFactory f) { if(this instanceof TypeAdapterFactory f) {
builder.registerTypeAdapterFactory(f); builder.registerTypeAdapterFactory(f);
@ -25,4 +33,50 @@ public interface Resolvable {
} }
} }
} }
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface Entity {
String id();
String name() default "";
String namePlural() default "";
JsonToken[] jsonTypes() default JsonToken.BEGIN_OBJECT;
@AllArgsConstructor
@lombok.Data
class ResolverEntityData
{
private final Entity annotation;
public String getId() {
return annotation.id();
}
public String getName() {
return annotation.name().isEmpty() ? Form.capitalizeWords(getId().replaceAll("\\Q-\\E", " ")) : annotation.name();
}
public String getNamePlural() {
return annotation.namePlural().isEmpty() ? getName() + "s" : annotation.namePlural();
}
}
}
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface TokenConstructor {
JsonToken[] value();
}
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface Type {
Class<? extends Resolvable> value();
}
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface PlatformType {
Class<? extends PlatformNamespaced> value();
}
} }

View File

@ -0,0 +1,62 @@
package com.volmit.iris.engine.editor.pak;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class PakInputStream extends InputStream {
private final File folder;
private final String name;
private final int pakSize;
private int read;
private int currentPakNumber;
private InputStream currentPakStream;
public PakInputStream(File folder, String name, int pakSize) throws IOException {
this.pakSize = pakSize;
this.folder = folder;
this.name = name;
this.read = 0;
this.currentPakNumber = 0;
this.currentPakStream = readPakFile(currentPakNumber);
}
private InputStream readPakFile(int number) throws IOException {
File f = new File(folder, name + number + ".pak");
if(!f.exists()) {
return null;
}
return new FileInputStream(f);
}
@Override
public int read() throws IOException {
if(currentPakStream == null) {
return -1;
}
if(read++ == pakSize) {
currentPakStream.close();
currentPakStream = readPakFile(++currentPakNumber);
if(currentPakStream == null)
{
return -1;
}
read = 1;
}
return currentPakStream.read();
}
public void close() throws IOException {
if(currentPakStream != null) {
currentPakStream.close();
}
}
}

View File

@ -0,0 +1,22 @@
package com.volmit.iris.engine.editor.pak;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.Singular;
import lombok.experimental.Accessors;
import java.util.List;
@NoArgsConstructor
@Data
@AllArgsConstructor
@Builder
@Accessors(chain = true, fluent = true)
public class PakMetadata {
private String namespace;
@Singular
private List<PakResourceMetadata> resources;
private long pakSize;
}

View File

@ -0,0 +1,57 @@
package com.volmit.iris.engine.editor.pak;
import lombok.Getter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class PakOutputStream extends OutputStream {
@Getter
private final File folder;
@Getter
private final String name;
private OutputStream currentPakOutput;
private int currentPakNumber;
@Getter
private final long pakSize;
@Getter
private int written;
@Getter
private final List<File> writtenFiles;
public PakOutputStream(File folder, String name, long pakSize) throws IOException {
folder.mkdirs();
this.writtenFiles = new ArrayList<>();
this.written = 0;
this.name = name;
this.currentPakNumber = 0;
this.currentPakOutput = writePakFile(0);
this.pakSize = pakSize;
this.folder = folder;
}
private OutputStream writePakFile(int number) throws IOException {
File f = new File(folder, name + number + ".pak");
writtenFiles.add(f);
return new FileOutputStream(f);
}
@Override
public void write(int b) throws IOException {
if(written++ == pakSize) {
currentPakOutput.close();
currentPakOutput = writePakFile(++currentPakNumber);
written = 1;
}
currentPakOutput.write(b);
}
public void close() throws IOException {
currentPakOutput.close();
}
}

View File

@ -0,0 +1,51 @@
package com.volmit.iris.engine.editor.pak;
import com.volmit.iris.engine.editor.Resolvable;
import com.volmit.iris.platform.PlatformNamespaceKey;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.function.Consumer;
import java.util.function.Supplier;
@NoArgsConstructor
@Builder
@Data
@AllArgsConstructor
public class PakResourceInput {
private Class<? extends Resolvable> type;
private PlatformNamespaceKey key;
private Supplier<InputStream> reader;
private long size;
public long write(OutputStream out) throws IOException {
InputStream in = reader.get();
long w = in.transferTo(out);
in.close();
return w;
}
public static PakResourceInput file(PlatformNamespaceKey key, Class<? extends Resolvable> type, File f) {
return PakResourceInput.builder()
.size(f.length())
.key(key)
.type(type)
.reader(() -> {
try {
return new FileInputStream(f);
} catch(FileNotFoundException e) {
throw new RuntimeException(e);
}
})
.build();
}
}

View File

@ -0,0 +1,22 @@
package com.volmit.iris.engine.editor.pak;
import com.volmit.iris.engine.editor.Resolvable;
import com.volmit.iris.platform.PlatformNamespaceKey;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@NoArgsConstructor
@Data
@AllArgsConstructor
@Builder
@Accessors(chain = true, fluent = true)
public class PakResourceMetadata
{
private String type;
private String key;
private long start;
private long length;
}

View File

@ -0,0 +1,62 @@
package com.volmit.iris.engine.editor.pak;
import art.arcane.amulet.io.nbt.nbt.io.NBTUtil;
import art.arcane.amulet.io.nbt.nbt.io.NamedTag;
import art.arcane.amulet.io.nbt.objects.NBTObjectSerializer;
import art.arcane.amulet.io.nbt.objects.UnserializableClassException;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import static art.arcane.amulet.MagicalSugar.*;
public class PakWriter {
private final List<PakResourceInput> resources;
private final File folder;
private final PakOutputStream output;
private final String name;
private final long pakSize;
public PakWriter(File folder, String name, long pakSize) throws IOException {
folder.mkdirs();
this.name = name;
this.folder = folder;
this.pakSize = pakSize;
output = new PakOutputStream(folder, name, pakSize);
resources = new ArrayList<>();
}
public PakWriter(File folder, String name) throws IOException {
this(folder, name, 1MB);
}
public void write() throws IOException, UnserializableClassException, IllegalAccessException {
PakMetadata.PakMetadataBuilder meta = PakMetadata.builder().namespace(name).pakSize(pakSize);
long totalWritten = 0;
for(PakResourceInput i : resources) {
long written = i.write(output);
meta.resource(PakResourceMetadata.builder()
.key(i.getKey().toString())
.type(i.getType().getCanonicalName())
.start(totalWritten)
.length(written)
.build());
totalWritten += written;
}
NBTUtil.write(new NamedTag("Package " + name, NBTObjectSerializer.serialize(meta.build())), new File(folder, name + ".dat"), true);
output.close();
}
public PakWriter resource(PakResourceInput input)
{
resources.add(input);
return this;
}
}