mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-22 20:25:56 +00:00
expose most of the dimension type options
This commit is contained in:
parent
aad1d3815a
commit
2008975a8a
@ -23,9 +23,7 @@ import com.volmit.iris.core.loader.IrisData;
|
|||||||
import com.volmit.iris.core.nms.INMS;
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.core.nms.datapack.DataVersion;
|
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||||
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
import com.volmit.iris.engine.object.*;
|
||||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
|
||||||
import com.volmit.iris.engine.object.IrisDimension;
|
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.collection.KSet;
|
import com.volmit.iris.util.collection.KSet;
|
||||||
@ -296,7 +294,7 @@ public class ServerConfigurator {
|
|||||||
int logicalHeight = data.get(2);
|
int logicalHeight = data.get(2);
|
||||||
if (minY == Integer.MAX_VALUE || maxY == Integer.MIN_VALUE || Integer.MIN_VALUE == logicalHeight)
|
if (minY == Integer.MAX_VALUE || maxY == Integer.MIN_VALUE || Integer.MIN_VALUE == logicalHeight)
|
||||||
return null;
|
return null;
|
||||||
return fixer.createDimension(dimension, minY, maxY, logicalHeight).toString(4);
|
return fixer.createDimension(dimension, minY, maxY - minY, logicalHeight, null).toString(4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,25 @@
|
|||||||
package com.volmit.iris.core.nms.datapack;
|
package com.volmit.iris.core.nms.datapack;
|
||||||
|
|
||||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
|
import com.volmit.iris.engine.object.IrisDimensionTypeOptions;
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public interface IDataFixer {
|
public interface IDataFixer {
|
||||||
|
|
||||||
default JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) {
|
default JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) {
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONObject rawDimension(Dimension dimension);
|
JSONObject resolve(Dimension dimension, @Nullable IrisDimensionTypeOptions options);
|
||||||
|
|
||||||
default JSONObject createDimension(Dimension dimension, int minY, int maxY, int logicalHeight) {
|
void fixDimension(Dimension dimension, JSONObject json);
|
||||||
JSONObject obj = rawDimension(dimension);
|
|
||||||
|
default JSONObject createDimension(Dimension base, int minY, int height, int logicalHeight, @Nullable IrisDimensionTypeOptions options) {
|
||||||
|
JSONObject obj = resolve(base, options);
|
||||||
obj.put("min_y", minY);
|
obj.put("min_y", minY);
|
||||||
obj.put("height", maxY - minY);
|
obj.put("height", height);
|
||||||
obj.put("logical_height", logicalHeight);
|
obj.put("logical_height", logicalHeight);
|
||||||
|
fixDimension(base, obj);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,81 +1,104 @@
|
|||||||
package com.volmit.iris.core.nms.datapack.v1192;
|
package com.volmit.iris.core.nms.datapack.v1192;
|
||||||
|
|
||||||
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
||||||
|
import com.volmit.iris.engine.object.IrisDimensionTypeOptions;
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.volmit.iris.engine.object.IrisDimensionTypeOptions.TriState.*;
|
||||||
|
|
||||||
public class DataFixerV1192 implements IDataFixer {
|
public class DataFixerV1192 implements IDataFixer {
|
||||||
|
private static final Map<Dimension, IrisDimensionTypeOptions> OPTIONS = Map.of(
|
||||||
|
Dimension.OVERWORLD, new IrisDimensionTypeOptions(
|
||||||
|
FALSE,
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
1d,
|
||||||
|
0f,
|
||||||
|
null,
|
||||||
|
192,
|
||||||
|
0),
|
||||||
|
Dimension.NETHER, new IrisDimensionTypeOptions(
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
TRUE,
|
||||||
|
8d,
|
||||||
|
0.1f,
|
||||||
|
18000L,
|
||||||
|
null,
|
||||||
|
15),
|
||||||
|
Dimension.END, new IrisDimensionTypeOptions(
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
1d,
|
||||||
|
0f,
|
||||||
|
6000L,
|
||||||
|
null,
|
||||||
|
0)
|
||||||
|
);
|
||||||
|
|
||||||
private static final Map<Dimension, String> DIMENSIONS = Map.of(
|
private static final Map<Dimension, String> DIMENSIONS = Map.of(
|
||||||
Dimension.OVERWORLD, """
|
Dimension.OVERWORLD, """
|
||||||
{
|
{
|
||||||
"ambient_light": 0.0,
|
|
||||||
"bed_works": true,
|
|
||||||
"coordinate_scale": 1.0,
|
|
||||||
"effects": "minecraft:overworld",
|
"effects": "minecraft:overworld",
|
||||||
"has_ceiling": false,
|
|
||||||
"has_raids": true,
|
|
||||||
"has_skylight": true,
|
|
||||||
"infiniburn": "#minecraft:infiniburn_overworld",
|
"infiniburn": "#minecraft:infiniburn_overworld",
|
||||||
"monster_spawn_block_light_limit": 0,
|
|
||||||
"monster_spawn_light_level": {
|
"monster_spawn_light_level": {
|
||||||
"type": "minecraft:uniform",
|
"type": "minecraft:uniform",
|
||||||
"value": {
|
"value": {
|
||||||
"max_inclusive": 7,
|
"max_inclusive": 7,
|
||||||
"min_inclusive": 0
|
"min_inclusive": 0
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"natural": true,
|
|
||||||
"piglin_safe": false,
|
|
||||||
"respawn_anchor_works": false,
|
|
||||||
"ultrawarm": false
|
|
||||||
}""",
|
}""",
|
||||||
Dimension.NETHER, """
|
Dimension.NETHER, """
|
||||||
{
|
{
|
||||||
"ambient_light": 0.1,
|
|
||||||
"bed_works": false,
|
|
||||||
"coordinate_scale": 8.0,
|
|
||||||
"effects": "minecraft:the_nether",
|
"effects": "minecraft:the_nether",
|
||||||
"fixed_time": 18000,
|
|
||||||
"has_ceiling": true,
|
|
||||||
"has_raids": false,
|
|
||||||
"has_skylight": false,
|
|
||||||
"infiniburn": "#minecraft:infiniburn_nether",
|
"infiniburn": "#minecraft:infiniburn_nether",
|
||||||
"monster_spawn_block_light_limit": 15,
|
|
||||||
"monster_spawn_light_level": 7,
|
"monster_spawn_light_level": 7,
|
||||||
"natural": false,
|
|
||||||
"piglin_safe": true,
|
|
||||||
"respawn_anchor_works": true,
|
|
||||||
"ultrawarm": true
|
|
||||||
}""",
|
}""",
|
||||||
Dimension.END, """
|
Dimension.END, """
|
||||||
{
|
{
|
||||||
"ambient_light": 0.0,
|
|
||||||
"bed_works": false,
|
|
||||||
"coordinate_scale": 1.0,
|
|
||||||
"effects": "minecraft:the_end",
|
"effects": "minecraft:the_end",
|
||||||
"fixed_time": 6000,
|
|
||||||
"has_ceiling": false,
|
|
||||||
"has_raids": true,
|
|
||||||
"has_skylight": false,
|
|
||||||
"infiniburn": "#minecraft:infiniburn_end",
|
"infiniburn": "#minecraft:infiniburn_end",
|
||||||
"monster_spawn_block_light_limit": 0,
|
|
||||||
"monster_spawn_light_level": {
|
"monster_spawn_light_level": {
|
||||||
"type": "minecraft:uniform",
|
"type": "minecraft:uniform",
|
||||||
"value": {
|
"value": {
|
||||||
"max_inclusive": 7,
|
"max_inclusive": 7,
|
||||||
"min_inclusive": 0
|
"min_inclusive": 0
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"natural": false,
|
|
||||||
"piglin_safe": false,
|
|
||||||
"respawn_anchor_works": false,
|
|
||||||
"ultrawarm": false
|
|
||||||
}"""
|
}"""
|
||||||
);
|
);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JSONObject rawDimension(Dimension dimension) {
|
public JSONObject resolve(Dimension dimension, @Nullable IrisDimensionTypeOptions options) {
|
||||||
return new JSONObject(DIMENSIONS.get(dimension));
|
return options == null ? OPTIONS.get(dimension).toJson() : options.resolve(OPTIONS.get(dimension)).toJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fixDimension(Dimension dimension, JSONObject json) {
|
||||||
|
var missing = new JSONObject(DIMENSIONS.get(dimension));
|
||||||
|
for (String key : missing.keySet()) {
|
||||||
|
if (json.has(key)) continue;
|
||||||
|
json.put(key, missing.get(key));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,13 +45,12 @@ public class DataFixerV1206 extends DataFixerV1192 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JSONObject rawDimension(Dimension dimension) {
|
public void fixDimension(Dimension dimension, JSONObject json) {
|
||||||
JSONObject json = super.rawDimension(dimension);
|
super.fixDimension(dimension, json);
|
||||||
if (!(json.get("monster_spawn_light_level") instanceof JSONObject lightLevel))
|
if (!(json.get("monster_spawn_light_level") instanceof JSONObject lightLevel))
|
||||||
return json;
|
return;
|
||||||
var value = (JSONObject) lightLevel.remove("value");
|
var value = (JSONObject) lightLevel.remove("value");
|
||||||
lightLevel.put("max_inclusive", value.get("max_inclusive"));
|
lightLevel.put("max_inclusive", value.get("max_inclusive"));
|
||||||
lightLevel.put("min_inclusive", value.get("min_inclusive"));
|
lightLevel.put("min_inclusive", value.get("min_inclusive"));
|
||||||
return json;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@ import com.volmit.iris.engine.object.annotations.*;
|
|||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KSet;
|
import com.volmit.iris.util.collection.KSet;
|
||||||
import com.volmit.iris.util.data.DataProvider;
|
import com.volmit.iris.util.data.DataProvider;
|
||||||
import com.volmit.iris.util.data.Varint;
|
|
||||||
import com.volmit.iris.util.io.IO;
|
import com.volmit.iris.util.io.IO;
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
import com.volmit.iris.util.math.Position2;
|
import com.volmit.iris.util.math.Position2;
|
||||||
@ -47,10 +46,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.World.Environment;
|
import org.bukkit.World.Environment;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.*;
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@ -166,6 +162,8 @@ public class IrisDimension extends IrisRegistrant {
|
|||||||
private int fluidHeight = 63;
|
private int fluidHeight = 63;
|
||||||
@Desc("Define the min and max Y bounds of this dimension. Please keep in mind that Iris internally generates from 0 to (max - min). \n\nFor example at -64 to 320, Iris is internally generating to 0 to 384, then on outputting chunks, it shifts it down by the min height (64 blocks). The default is -64 to 320. \n\nThe fluid height is placed at (fluid height + min height). So a fluid height of 63 would actually show up in the world at 1.")
|
@Desc("Define the min and max Y bounds of this dimension. Please keep in mind that Iris internally generates from 0 to (max - min). \n\nFor example at -64 to 320, Iris is internally generating to 0 to 384, then on outputting chunks, it shifts it down by the min height (64 blocks). The default is -64 to 320. \n\nThe fluid height is placed at (fluid height + min height). So a fluid height of 63 would actually show up in the world at 1.")
|
||||||
private IrisRange dimensionHeight = new IrisRange(-64, 320);
|
private IrisRange dimensionHeight = new IrisRange(-64, 320);
|
||||||
|
@Desc("Define options for this dimension")
|
||||||
|
private IrisDimensionTypeOptions dimensionOptions = new IrisDimensionTypeOptions();
|
||||||
@RegistryListResource(IrisBiome.class)
|
@RegistryListResource(IrisBiome.class)
|
||||||
@Desc("Keep this either undefined or empty. Setting any biome name into this will force iris to only generate the specified biome. Great for testing.")
|
@Desc("Keep this either undefined or empty. Setting any biome name into this will force iris to only generate the specified biome. Great for testing.")
|
||||||
private String focus = "";
|
private String focus = "";
|
||||||
@ -415,21 +413,20 @@ public class IrisDimension extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getDimensionTypeKey() {
|
public String getDimensionTypeKey() {
|
||||||
return getDimensionTypeKey(getBaseDimension(), getMinHeight(), getMaxHeight(), getLogicalHeight());
|
return getDimensionType().key();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IrisDimensionType getDimensionType() {
|
||||||
|
return new IrisDimensionType(getBaseDimension(), getDimensionOptions(), getLogicalHeight(), getMaxHeight() - getMinHeight(), getMinHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void installDimensionType(IDataFixer fixer, KList<File> folders) {
|
public void installDimensionType(IDataFixer fixer, KList<File> folders) {
|
||||||
String key = getDimensionTypeKey();
|
IrisDimensionType type = getDimensionType();
|
||||||
String json = fixer.createDimension(
|
String json = type.toJson(fixer);
|
||||||
getBaseDimension(),
|
|
||||||
getMinHeight(),
|
|
||||||
getMaxHeight(),
|
|
||||||
getLogicalHeight()
|
|
||||||
).toString(4);
|
|
||||||
|
|
||||||
Iris.verbose(" Installing Data Pack Dimension Type: \"iris:" + key + '"');
|
Iris.verbose(" Installing Data Pack Dimension Type: \"iris:" + type.key() + '"');
|
||||||
for (File datapacks : folders) {
|
for (File datapacks : folders) {
|
||||||
File output = new File(datapacks, "iris/data/iris/dimension_type/" + key + ".json");
|
File output = new File(datapacks, "iris/data/iris/dimension_type/" + type.key() + ".json");
|
||||||
output.getParentFile().mkdirs();
|
output.getParentFile().mkdirs();
|
||||||
try {
|
try {
|
||||||
IO.writeAll(output, json);
|
IO.writeAll(output, json);
|
||||||
@ -485,20 +482,6 @@ public class IrisDimension extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getDimensionTypeKey(Dimension dimension, int minY, int maxY, int logicalHeight) {
|
|
||||||
var stream = new ByteArrayOutputStream(13);
|
|
||||||
try (var dos = new DataOutputStream(stream)) {
|
|
||||||
dos.writeByte(dimension.ordinal());
|
|
||||||
Varint.writeUnsignedVarInt(logicalHeight, dos);
|
|
||||||
Varint.writeUnsignedVarInt(maxY - minY, dos);
|
|
||||||
Varint.writeSignedVarInt(minY, dos);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("This is impossible", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return IO.encode(stream.toByteArray()).replace("=", ".").toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void write(File datapacks, String type, String json) {
|
private static void write(File datapacks, String type, String json) {
|
||||||
if (json == null) return;
|
if (json == null) return;
|
||||||
File dimTypeVanilla = new File(datapacks, "iris/data/minecraft/dimension_type/" + type + ".json");
|
File dimTypeVanilla = new File(datapacks, "iris/data/minecraft/dimension_type/" + type + ".json");
|
||||||
|
@ -0,0 +1,91 @@
|
|||||||
|
package com.volmit.iris.engine.object;
|
||||||
|
|
||||||
|
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
||||||
|
import com.volmit.iris.util.data.Varint;
|
||||||
|
import com.volmit.iris.util.io.IO;
|
||||||
|
import lombok.*;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
@Accessors(fluent = true, chain = true)
|
||||||
|
@EqualsAndHashCode
|
||||||
|
public final class IrisDimensionType {
|
||||||
|
@NonNull
|
||||||
|
private final String key;
|
||||||
|
@NonNull
|
||||||
|
private final IDataFixer.Dimension base;
|
||||||
|
@NonNull
|
||||||
|
private final IrisDimensionTypeOptions options;
|
||||||
|
private final int logicalHeight;
|
||||||
|
private final int height;
|
||||||
|
private final int minY;
|
||||||
|
|
||||||
|
public IrisDimensionType(
|
||||||
|
@NonNull IDataFixer.Dimension base,
|
||||||
|
@NonNull IrisDimensionTypeOptions options,
|
||||||
|
int logicalHeight,
|
||||||
|
int height,
|
||||||
|
int minY
|
||||||
|
) {
|
||||||
|
if (logicalHeight > height) throw new IllegalArgumentException("Logical height cannot be greater than height");
|
||||||
|
if (logicalHeight < 0) throw new IllegalArgumentException("Logical height cannot be less than zero");
|
||||||
|
if (height < 16 || height > 4064 ) throw new IllegalArgumentException("Height must be between 16 and 4064");
|
||||||
|
if ((height & 15) != 0) throw new IllegalArgumentException("Height must be a multiple of 16");
|
||||||
|
if (minY < -2032 || minY > 2031) throw new IllegalArgumentException("Min Y must be between -2032 and 2031");
|
||||||
|
if ((minY & 15) != 0) throw new IllegalArgumentException("Min Y must be a multiple of 16");
|
||||||
|
|
||||||
|
this.base = base;
|
||||||
|
this.options = options;
|
||||||
|
this.logicalHeight = logicalHeight;
|
||||||
|
this.height = height;
|
||||||
|
this.minY = minY;
|
||||||
|
this.key = createKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IrisDimensionType fromKey(String key) {
|
||||||
|
var stream = new ByteArrayInputStream(IO.decode(key.replace(".", "=").toUpperCase()));
|
||||||
|
try (var din = new DataInputStream(stream)) {
|
||||||
|
return new IrisDimensionType(
|
||||||
|
IDataFixer.Dimension.values()[din.readUnsignedByte()],
|
||||||
|
new IrisDimensionTypeOptions().read(din),
|
||||||
|
Varint.readUnsignedVarInt(din),
|
||||||
|
Varint.readUnsignedVarInt(din),
|
||||||
|
Varint.readSignedVarInt(din)
|
||||||
|
);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("This is impossible", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toJson(IDataFixer fixer) {
|
||||||
|
return fixer.createDimension(
|
||||||
|
base,
|
||||||
|
minY,
|
||||||
|
height,
|
||||||
|
logicalHeight,
|
||||||
|
options.copy()
|
||||||
|
).toString(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createKey() {
|
||||||
|
var stream = new ByteArrayOutputStream(41);
|
||||||
|
try (var dos = new DataOutputStream(stream)) {
|
||||||
|
dos.writeByte(base.ordinal());
|
||||||
|
options.write(dos);
|
||||||
|
Varint.writeUnsignedVarInt(logicalHeight, dos);
|
||||||
|
Varint.writeUnsignedVarInt(height, dos);
|
||||||
|
Varint.writeSignedVarInt(minY, dos);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("This is impossible", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return IO.encode(stream.toByteArray()).replace("=", ".").toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IrisDimensionTypeOptions options() {
|
||||||
|
return options.copy();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,320 @@
|
|||||||
|
package com.volmit.iris.engine.object;
|
||||||
|
|
||||||
|
import com.volmit.iris.engine.object.annotations.Desc;
|
||||||
|
import com.volmit.iris.engine.object.annotations.MaxNumber;
|
||||||
|
import com.volmit.iris.engine.object.annotations.MinNumber;
|
||||||
|
import com.volmit.iris.util.data.Varint;
|
||||||
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
import lombok.*;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.DataInput;
|
||||||
|
import java.io.DataOutput;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static com.volmit.iris.engine.object.IrisDimensionTypeOptions.TriState.*;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Accessors(fluent = true, chain = true)
|
||||||
|
@Desc("Optional options for the dimension type")
|
||||||
|
public class IrisDimensionTypeOptions {
|
||||||
|
@MinNumber(0.00001)
|
||||||
|
@MaxNumber(30000000)
|
||||||
|
@Desc("The multiplier applied to coordinates when leaving the dimension. Value between 0.00001 and 30000000.0 (both inclusive).")
|
||||||
|
private double coordinateScale = -1;
|
||||||
|
@MinNumber(0)
|
||||||
|
@MaxNumber(1)
|
||||||
|
@Desc("How much light the dimension has. When set to 0, it completely follows the light level; when set to 1, there is no ambient lighting.")
|
||||||
|
private float ambientLight = -1;
|
||||||
|
@Nullable
|
||||||
|
@MinNumber(0)
|
||||||
|
@MaxNumber(Long.MAX_VALUE)
|
||||||
|
@Desc("If this is set to an int, the time of the day is the specified value. To ensure a normal time cycle, set it to null.")
|
||||||
|
private Long fixedTime = -1L;
|
||||||
|
@Nullable
|
||||||
|
@MinNumber(-2032)
|
||||||
|
@MaxNumber(2031)
|
||||||
|
@Desc("Optional value between -2032 and 2031. If set, determines the lower edge of the clouds. If set to null, clouds are disabled in the dimension.")
|
||||||
|
private Integer cloudHeight = -1;
|
||||||
|
@MinNumber(0)
|
||||||
|
@MaxNumber(15)
|
||||||
|
@Desc("Value between 0 and 15 (both inclusive). Maximum block light required when the monster spawns.")
|
||||||
|
private int monsterSpawnBlockLightLimit = -1;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Desc("Whether the dimensions behaves like the nether (water evaporates and sponges dry) or not. Also lets stalactites drip lava and causes lava to spread faster and thinner.")
|
||||||
|
private TriState ultrawarm = DEFAULT;
|
||||||
|
@NonNull
|
||||||
|
@Desc("When false, compasses spin randomly, and using a bed to set the respawn point or sleep, is disabled. When true, nether portals can spawn zombified piglins, and creaking hearts can spawn creakings.")
|
||||||
|
private TriState natural = DEFAULT;
|
||||||
|
@NonNull
|
||||||
|
@Desc("When false, Piglins and hoglins shake and transform to zombified entities.")
|
||||||
|
private TriState piglinSafe = DEFAULT;
|
||||||
|
@NonNull
|
||||||
|
@Desc("When false, the respawn anchor blows up when trying to set spawn point.")
|
||||||
|
private TriState respawnAnchorWorks = DEFAULT;
|
||||||
|
@NonNull
|
||||||
|
@Desc("When false, the bed blows up when trying to sleep.")
|
||||||
|
private TriState bedWorks = DEFAULT;
|
||||||
|
@NonNull
|
||||||
|
@Desc("Whether players with the Bad Omen effect can cause a raid.")
|
||||||
|
private TriState raids = DEFAULT;
|
||||||
|
@NonNull
|
||||||
|
@Desc("Whether the dimension has skylight or not.")
|
||||||
|
private TriState skylight = DEFAULT;
|
||||||
|
@NonNull
|
||||||
|
@Desc("Whether the dimension has a bedrock ceiling. Note that this is only a logical ceiling. It is unrelated with whether the dimension really has a block ceiling.")
|
||||||
|
private TriState ceiling = DEFAULT;
|
||||||
|
|
||||||
|
public IrisDimensionTypeOptions(
|
||||||
|
@NonNull TriState ultrawarm,
|
||||||
|
@NonNull TriState natural,
|
||||||
|
@NonNull TriState piglinSafe,
|
||||||
|
@NonNull TriState respawnAnchorWorks,
|
||||||
|
@NonNull TriState bedWorks,
|
||||||
|
@NonNull TriState raids,
|
||||||
|
@NonNull TriState skylight,
|
||||||
|
@NonNull TriState ceiling,
|
||||||
|
double coordinateScale,
|
||||||
|
float ambientLight,
|
||||||
|
@Nullable Long fixedTime,
|
||||||
|
@Nullable Integer cloudHeight,
|
||||||
|
int monsterSpawnBlockLightLimit
|
||||||
|
) {
|
||||||
|
if (coordinateScale != -1 && (coordinateScale < 0.00001 || coordinateScale > 30000000))
|
||||||
|
throw new IllegalArgumentException("Coordinate scale must be between 0.00001 and 30000000");
|
||||||
|
if (ambientLight != -1 && (ambientLight < 0 || ambientLight > 1))
|
||||||
|
throw new IllegalArgumentException("Ambient light must be between 0 and 1");
|
||||||
|
if (cloudHeight != null && cloudHeight != -1 && (cloudHeight < -2032 || cloudHeight > 2031))
|
||||||
|
throw new IllegalArgumentException("Cloud height must be between -2032 and 2031");
|
||||||
|
if (monsterSpawnBlockLightLimit != -1 && (monsterSpawnBlockLightLimit < 0 || monsterSpawnBlockLightLimit > 15))
|
||||||
|
throw new IllegalArgumentException("Monster spawn block light limit must be between 0 and 15");
|
||||||
|
|
||||||
|
this.ultrawarm = ultrawarm;
|
||||||
|
this.natural = natural;
|
||||||
|
this.piglinSafe = piglinSafe;
|
||||||
|
this.respawnAnchorWorks = respawnAnchorWorks;
|
||||||
|
this.bedWorks = bedWorks;
|
||||||
|
this.raids = raids;
|
||||||
|
this.skylight = skylight;
|
||||||
|
this.ceiling = ceiling;
|
||||||
|
this.coordinateScale = coordinateScale;
|
||||||
|
this.ambientLight = ambientLight;
|
||||||
|
this.fixedTime = fixedTime;
|
||||||
|
this.cloudHeight = cloudHeight;
|
||||||
|
this.monsterSpawnBlockLightLimit = monsterSpawnBlockLightLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IrisDimensionTypeOptions coordinateScale(double coordinateScale) {
|
||||||
|
if (coordinateScale != -1 && (coordinateScale < 0.00001 || coordinateScale > 30000000))
|
||||||
|
throw new IllegalArgumentException("Coordinate scale must be between 0.00001 and 30000000");
|
||||||
|
this.coordinateScale = coordinateScale;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IrisDimensionTypeOptions ambientLight(float ambientLight) {
|
||||||
|
if (ambientLight != -1 && (ambientLight < 0 || ambientLight > 1))
|
||||||
|
throw new IllegalArgumentException("Ambient light must be between 0 and 1");
|
||||||
|
this.ambientLight = ambientLight;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IrisDimensionTypeOptions cloudHeight(@Nullable Integer cloudHeight) {
|
||||||
|
if (cloudHeight != null && cloudHeight != -1 && (cloudHeight < -2032 || cloudHeight > 2031))
|
||||||
|
throw new IllegalArgumentException("Cloud height must be between -2032 and 2031");
|
||||||
|
this.cloudHeight = cloudHeight;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IrisDimensionTypeOptions monsterSpawnBlockLightLimit(int monsterSpawnBlockLightLimit) {
|
||||||
|
if (monsterSpawnBlockLightLimit != -1 && (monsterSpawnBlockLightLimit < 0 || monsterSpawnBlockLightLimit > 15))
|
||||||
|
throw new IllegalArgumentException("Monster spawn block light limit must be between 0 and 15");
|
||||||
|
this.monsterSpawnBlockLightLimit = monsterSpawnBlockLightLimit;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(DataOutput dos) throws IOException {
|
||||||
|
int bits = 0;
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
for (TriState state : new TriState[]{
|
||||||
|
ultrawarm,
|
||||||
|
natural,
|
||||||
|
skylight,
|
||||||
|
ceiling,
|
||||||
|
piglinSafe,
|
||||||
|
bedWorks,
|
||||||
|
respawnAnchorWorks,
|
||||||
|
raids
|
||||||
|
}) {
|
||||||
|
if (state == DEFAULT) {
|
||||||
|
index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bits |= (short) (1 << index++);
|
||||||
|
if (state == TRUE)
|
||||||
|
bits |= (short) (1 << index++);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (coordinateScale != -1)
|
||||||
|
bits |= (1 << index++);
|
||||||
|
if (ambientLight != -1)
|
||||||
|
bits |= (1 << index++);
|
||||||
|
if (monsterSpawnBlockLightLimit != -1)
|
||||||
|
bits |= (1 << index++);
|
||||||
|
if (fixedTime != null) {
|
||||||
|
bits |= (1 << index++);
|
||||||
|
if (fixedTime != -1L)
|
||||||
|
bits |= (1 << index++);
|
||||||
|
}
|
||||||
|
if (cloudHeight != null) {
|
||||||
|
bits |= (1 << index++);
|
||||||
|
if (cloudHeight != -1)
|
||||||
|
bits |= (1 << index);
|
||||||
|
}
|
||||||
|
|
||||||
|
Varint.writeSignedVarInt(bits, dos);
|
||||||
|
|
||||||
|
if (coordinateScale != -1)
|
||||||
|
Varint.writeUnsignedVarLong(Double.doubleToLongBits(coordinateScale), dos);
|
||||||
|
if (ambientLight != -1)
|
||||||
|
Varint.writeUnsignedVarInt(Float.floatToIntBits(ambientLight), dos);
|
||||||
|
if (monsterSpawnBlockLightLimit != -1)
|
||||||
|
Varint.writeSignedVarInt(monsterSpawnBlockLightLimit, dos);
|
||||||
|
if (fixedTime != null && fixedTime != -1L)
|
||||||
|
Varint.writeSignedVarLong(fixedTime, dos);
|
||||||
|
if (cloudHeight != null && cloudHeight != -1)
|
||||||
|
Varint.writeSignedVarInt(cloudHeight, dos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IrisDimensionTypeOptions read(DataInput dis) throws IOException {
|
||||||
|
TriState[] states = new TriState[8];
|
||||||
|
Arrays.fill(states, DEFAULT);
|
||||||
|
|
||||||
|
int bits = Varint.readSignedVarInt(dis);
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
if ((bits & (1 << index++)) == 0)
|
||||||
|
continue;
|
||||||
|
states[i] = (bits & (1 << index++)) == 0 ? FALSE : TRUE;
|
||||||
|
}
|
||||||
|
ultrawarm = states[0];
|
||||||
|
natural = states[1];
|
||||||
|
skylight = states[2];
|
||||||
|
ceiling = states[3];
|
||||||
|
piglinSafe = states[4];
|
||||||
|
bedWorks = states[5];
|
||||||
|
respawnAnchorWorks = states[6];
|
||||||
|
raids = states[7];
|
||||||
|
|
||||||
|
coordinateScale = (bits & (1 << index++)) != 0 ? Double.longBitsToDouble(Varint.readUnsignedVarLong(dis)) : -1;
|
||||||
|
ambientLight = (bits & (1 << index++)) != 0 ? Float.intBitsToFloat(Varint.readUnsignedVarInt(dis)) : -1;
|
||||||
|
monsterSpawnBlockLightLimit = (bits & (1 << index++)) != 0 ? Varint.readSignedVarInt(dis) : -1;
|
||||||
|
fixedTime = (bits & (1 << index++)) != 0 ? (bits & (1 << index)) != 0 ? Varint.readSignedVarLong(dis) : -1L : null;
|
||||||
|
cloudHeight = (bits & (1 << index++)) != 0 ? (bits & (1 << index)) != 0 ? Varint.readSignedVarInt(dis) : -1 : null;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IrisDimensionTypeOptions resolve(IrisDimensionTypeOptions other) {
|
||||||
|
if (ultrawarm == DEFAULT)
|
||||||
|
ultrawarm = other.ultrawarm;
|
||||||
|
if (natural == DEFAULT)
|
||||||
|
natural = other.natural;
|
||||||
|
if (piglinSafe == DEFAULT)
|
||||||
|
piglinSafe = other.piglinSafe;
|
||||||
|
if (respawnAnchorWorks == DEFAULT)
|
||||||
|
respawnAnchorWorks = other.respawnAnchorWorks;
|
||||||
|
if (bedWorks == DEFAULT)
|
||||||
|
bedWorks = other.bedWorks;
|
||||||
|
if (raids == DEFAULT)
|
||||||
|
raids = other.raids;
|
||||||
|
if (skylight == DEFAULT)
|
||||||
|
skylight = other.skylight;
|
||||||
|
if (ceiling == DEFAULT)
|
||||||
|
ceiling = other.ceiling;
|
||||||
|
if (coordinateScale == -1)
|
||||||
|
coordinateScale = other.coordinateScale;
|
||||||
|
if (ambientLight == -1)
|
||||||
|
ambientLight = other.ambientLight;
|
||||||
|
if (fixedTime != null && fixedTime == -1L)
|
||||||
|
fixedTime = other.fixedTime;
|
||||||
|
if (cloudHeight != null && cloudHeight == -1)
|
||||||
|
cloudHeight = other.cloudHeight;
|
||||||
|
if (monsterSpawnBlockLightLimit == -1)
|
||||||
|
monsterSpawnBlockLightLimit = other.monsterSpawnBlockLightLimit;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject toJson() {
|
||||||
|
if (!isComplete()) throw new IllegalStateException("Cannot serialize incomplete options");
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("ultrawarm", ultrawarm.bool());
|
||||||
|
json.put("natural", natural.bool());
|
||||||
|
json.put("piglin_safe", piglinSafe.bool());
|
||||||
|
json.put("respawn_anchor_works", respawnAnchorWorks.bool());
|
||||||
|
json.put("bed_works", bedWorks.bool());
|
||||||
|
json.put("has_raids", raids.bool());
|
||||||
|
json.put("has_skylight", skylight.bool());
|
||||||
|
json.put("has_ceiling", ceiling.bool());
|
||||||
|
json.put("coordinate_scale", coordinateScale);
|
||||||
|
json.put("ambient_light", ambientLight);
|
||||||
|
json.put("monster_spawn_block_light_limit", monsterSpawnBlockLightLimit);
|
||||||
|
if (fixedTime != null) json.put("fixed_time", fixedTime);
|
||||||
|
if (cloudHeight != null) json.put("cloud_height", cloudHeight);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IrisDimensionTypeOptions copy() {
|
||||||
|
return new IrisDimensionTypeOptions(
|
||||||
|
ultrawarm,
|
||||||
|
natural,
|
||||||
|
piglinSafe,
|
||||||
|
respawnAnchorWorks,
|
||||||
|
bedWorks,
|
||||||
|
raids,
|
||||||
|
skylight,
|
||||||
|
ceiling,
|
||||||
|
coordinateScale,
|
||||||
|
ambientLight,
|
||||||
|
fixedTime,
|
||||||
|
cloudHeight,
|
||||||
|
monsterSpawnBlockLightLimit
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isComplete() {
|
||||||
|
return ultrawarm != DEFAULT
|
||||||
|
&& natural != DEFAULT
|
||||||
|
&& piglinSafe != DEFAULT
|
||||||
|
&& respawnAnchorWorks != DEFAULT
|
||||||
|
&& bedWorks != DEFAULT
|
||||||
|
&& raids != DEFAULT
|
||||||
|
&& skylight != DEFAULT
|
||||||
|
&& ceiling != DEFAULT
|
||||||
|
&& coordinateScale != -1
|
||||||
|
&& ambientLight != -1
|
||||||
|
&& monsterSpawnBlockLightLimit != -1
|
||||||
|
&& (fixedTime == null || fixedTime != -1L)
|
||||||
|
&& (cloudHeight == null || cloudHeight != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Desc("Allows reusing the behavior of the base dimension")
|
||||||
|
public enum TriState {
|
||||||
|
@Desc("Follow the behavior of the base dimension")
|
||||||
|
DEFAULT,
|
||||||
|
@Desc("True")
|
||||||
|
TRUE,
|
||||||
|
@Desc("False")
|
||||||
|
FALSE;
|
||||||
|
|
||||||
|
public boolean bool() {
|
||||||
|
return this == TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user