mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-05-20 08:40:26 +00:00
Compare commits
97 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6146c8db06 | |||
| 4388003f35 | |||
| a385a43250 | |||
| 3cd6aead64 | |||
| 4f33b11828 | |||
| f5bbaa3c3a | |||
| 4fd84a3f2d | |||
| bed67c211d | |||
| 2c8d3416ab | |||
| 5e43f0afef | |||
| 02fdcee705 | |||
| 4165224c51 | |||
| 710bbc33c9 | |||
| 1929239015 | |||
| 3ca90808f0 | |||
| 9d91440997 | |||
| f98062d417 | |||
| 4432ae4867 | |||
| 16c951838b | |||
| 144c932703 | |||
| e56b8856fa | |||
| 04f6d18198 | |||
| 071f9d39af | |||
| d2107fd258 | |||
| df3e623530 | |||
| f0d03d4538 | |||
| 84fe8792d6 | |||
| 67fc2ba4dc | |||
| 8d63c40e2f | |||
| b0bc37c34d | |||
| f2c5c15650 | |||
| f5de88215c | |||
| 8a6ad95947 | |||
| cc14c716bf | |||
| ece5213a87 | |||
| a01f700653 | |||
| 0ca7171bae | |||
| 6261f0849c | |||
| 4fc24f022f | |||
| 61ed302137 | |||
| 1496f2c929 | |||
| 40a938be19 | |||
| da16f65ea2 | |||
| d45256b2f7 | |||
| 16d8e8f29d | |||
| a58b2a5193 | |||
| 6042f1c036 | |||
| af2ac64cd4 | |||
| 4bad8f702c | |||
| 76f12e0cb8 | |||
| ce9fb53df4 | |||
| 1f01b99d29 | |||
| 18a24562ec | |||
| 2f2d43e1b8 | |||
| 6c8a7da254 | |||
| ca4461ba2a | |||
| c6df3c302b | |||
| 328ebf5aa9 | |||
| 2c476a25d9 | |||
| b432a4e01d | |||
| f73eadda76 | |||
| 1acdad5c6b | |||
| 732a894945 | |||
| bbf0915bc9 | |||
| 5f70ecb943 | |||
| 2e709dace6 | |||
| c97f25cb95 | |||
| 28c689d16f | |||
| a34946cece | |||
| 4acd0de6fa | |||
| 2443fff0a4 | |||
| cd767a648c | |||
| d490324bfc | |||
| 5fa7007d45 | |||
| 2d0e4a83b0 | |||
| e68f928e38 | |||
| 4a3678cea9 | |||
| 6ff0903d83 | |||
| 133df45968 | |||
| 1f937a2ae0 | |||
| d861d3e849 | |||
| 3d4aec4abb | |||
| 62e589870d | |||
| 2b125414c9 | |||
| 59d7632927 | |||
| d81f886e8c | |||
| b29ba2db70 | |||
| 02a7363f01 | |||
| 0efb0916e6 | |||
| 82fbf796da | |||
| 94bf67d09d | |||
| f86d4bae32 | |||
| c7cecaebe6 | |||
| 70b1c3bbf3 | |||
| e9b145b6c3 | |||
| 99d848b394 | |||
| 4828d51da4 |
@@ -51,6 +51,15 @@ fun Project.configureDependencies() {
|
||||
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") {
|
||||
name = "Sonatype Snapshots"
|
||||
}
|
||||
maven("https://repo.opencollab.dev/maven-releases/") {
|
||||
name = "OpenCollab Releases"
|
||||
}
|
||||
maven("https://repo.opencollab.dev/maven-snapshots/") {
|
||||
name = "OpenCollab Snapshots"
|
||||
}
|
||||
maven("https://storehouse.okaeri.eu/repository/maven-public/") {
|
||||
name = "Okaeri"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -133,7 +133,6 @@ fun Project.configureDistribution() {
|
||||
version = project.version
|
||||
relocate("org.apache.commons", "com.dfsek.terra.lib.commons")
|
||||
relocate("org.objectweb.asm", "com.dfsek.terra.lib.asm")
|
||||
relocate("com.dfsek.paralithic", "com.dfsek.terra.lib.paralithic")
|
||||
relocate("org.json", "com.dfsek.terra.lib.json")
|
||||
relocate("org.yaml", "com.dfsek.terra.lib.yaml")
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ object Versions {
|
||||
|
||||
object Libraries {
|
||||
const val tectonic = "4.2.1"
|
||||
const val paralithic = "0.7.1"
|
||||
const val paralithic = "0.8.1"
|
||||
const val strata = "1.3.2"
|
||||
|
||||
const val cloud = "2.0.0"
|
||||
@@ -77,4 +77,8 @@ object Versions {
|
||||
const val logback = "1.5.8"
|
||||
const val picocli = "4.7.6"
|
||||
}
|
||||
|
||||
object Allay {
|
||||
const val api = "0114e0b290"
|
||||
}
|
||||
}
|
||||
+6
-3
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.dfsek.terra.addons.noise;
|
||||
|
||||
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -88,6 +89,8 @@ public class NoiseAddon implements AddonInitializer {
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(addon, ConfigPackPreLoadEvent.class)
|
||||
.then(event -> {
|
||||
ParseOptions expressionParseOptions = event.getPack().getExpressionParseOptions();
|
||||
|
||||
CheckedRegistry<Supplier<ObjectTemplate<NoiseSampler>>> noiseRegistry = event.getPack().getOrCreateRegistry(
|
||||
NOISE_SAMPLER_TOKEN);
|
||||
event.getPack()
|
||||
@@ -98,7 +101,7 @@ public class NoiseAddon implements AddonInitializer {
|
||||
.applyLoader(DistanceSampler.DistanceFunction.class,
|
||||
(type, o, loader, depthTracker) -> DistanceSampler.DistanceFunction.valueOf((String) o))
|
||||
.applyLoader(DimensionApplicableNoiseSampler.class, DimensionApplicableNoiseSampler::new)
|
||||
.applyLoader(FunctionTemplate.class, FunctionTemplate::new)
|
||||
.applyLoader(FunctionTemplate.class, () -> new FunctionTemplate(expressionParseOptions))
|
||||
.applyLoader(CubicSpline.Point.class, CubicSplinePointTemplate::new)
|
||||
.applyLoader(DerivativeNoiseSampler.class, DerivativeNoiseSamplerTemplate::new);
|
||||
|
||||
@@ -156,9 +159,9 @@ public class NoiseAddon implements AddonInitializer {
|
||||
|
||||
Map<String, DimensionApplicableNoiseSampler> packSamplers = new LinkedHashMap<>();
|
||||
Map<String, FunctionTemplate> packFunctions = new LinkedHashMap<>();
|
||||
noiseRegistry.register(addon.key("EXPRESSION"), () -> new ExpressionFunctionTemplate(packSamplers, packFunctions));
|
||||
noiseRegistry.register(addon.key("EXPRESSION"), () -> new ExpressionFunctionTemplate(packSamplers, packFunctions, expressionParseOptions));
|
||||
noiseRegistry.register(addon.key("EXPRESSION_NORMALIZER"),
|
||||
() -> new ExpressionNormalizerTemplate(packSamplers, packFunctions));
|
||||
() -> new ExpressionNormalizerTemplate(packSamplers, packFunctions, expressionParseOptions));
|
||||
|
||||
NoiseConfigPackTemplate template = event.loadTemplate(new NoiseConfigPackTemplate());
|
||||
packSamplers.putAll(template.getSamplers());
|
||||
|
||||
+3
@@ -7,7 +7,10 @@ import com.dfsek.terra.addons.noise.samplers.CacheSampler;
|
||||
import com.dfsek.terra.addons.noise.samplers.LinearHeightmapSampler;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus.Experimental;
|
||||
|
||||
|
||||
@Experimental
|
||||
public class CacheSamplerTemplate extends SamplerTemplate<CacheSampler> {
|
||||
@Value("sampler")
|
||||
@Default
|
||||
|
||||
+11
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.dfsek.terra.addons.noise.config.templates;
|
||||
|
||||
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
@@ -20,6 +21,8 @@ import com.dfsek.terra.api.config.meta.Meta;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class FunctionTemplate implements ObjectTemplate<FunctionTemplate> {
|
||||
private final ParseOptions parseOptions;
|
||||
|
||||
@Value("arguments")
|
||||
private List<String> args;
|
||||
|
||||
@@ -30,6 +33,10 @@ public class FunctionTemplate implements ObjectTemplate<FunctionTemplate> {
|
||||
@Default
|
||||
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>();
|
||||
|
||||
public FunctionTemplate(ParseOptions parseOptions) {
|
||||
this.parseOptions = parseOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionTemplate get() {
|
||||
return this;
|
||||
@@ -47,6 +54,10 @@ public class FunctionTemplate implements ObjectTemplate<FunctionTemplate> {
|
||||
return functions;
|
||||
}
|
||||
|
||||
public ParseOptions getParseOptions() {
|
||||
return parseOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(this == o) return true;
|
||||
|
||||
+6
-2
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.dfsek.terra.addons.noise.config.templates.noise;
|
||||
|
||||
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
@@ -29,6 +30,7 @@ import static com.dfsek.terra.addons.noise.paralithic.FunctionUtil.convertFuncti
|
||||
public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFunction> {
|
||||
private final Map<String, DimensionApplicableNoiseSampler> globalSamplers;
|
||||
private final Map<String, FunctionTemplate> globalFunctions;
|
||||
private final ParseOptions parseOptions;
|
||||
@Value("variables")
|
||||
@Default
|
||||
private @Meta Map<String, @Meta Double> vars = new HashMap<>();
|
||||
@@ -42,9 +44,11 @@ public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFuncti
|
||||
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>();
|
||||
|
||||
public ExpressionFunctionTemplate(Map<String, DimensionApplicableNoiseSampler> globalSamplers,
|
||||
Map<String, FunctionTemplate> globalFunctions) {
|
||||
Map<String, FunctionTemplate> globalFunctions,
|
||||
ParseOptions parseOptions) {
|
||||
this.globalSamplers = globalSamplers;
|
||||
this.globalFunctions = globalFunctions;
|
||||
this.parseOptions = parseOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -54,7 +58,7 @@ public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFuncti
|
||||
var mergedSamplers = new HashMap<>(globalSamplers);
|
||||
mergedSamplers.putAll(samplers);
|
||||
try {
|
||||
return new ExpressionFunction(convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars);
|
||||
return new ExpressionFunction(convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars, parseOptions);
|
||||
} catch(ParseException e) {
|
||||
throw new RuntimeException("Failed to parse expression.", e);
|
||||
}
|
||||
|
||||
+6
-2
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.dfsek.terra.addons.noise.config.templates.normalizer;
|
||||
|
||||
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
@@ -29,6 +30,7 @@ public class ExpressionNormalizerTemplate extends NormalizerTemplate<ExpressionN
|
||||
|
||||
private final Map<String, DimensionApplicableNoiseSampler> globalSamplers;
|
||||
private final Map<String, FunctionTemplate> globalFunctions;
|
||||
private final ParseOptions parseOptions;
|
||||
|
||||
@Value("expression")
|
||||
private @Meta String expression;
|
||||
@@ -46,9 +48,11 @@ public class ExpressionNormalizerTemplate extends NormalizerTemplate<ExpressionN
|
||||
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>();
|
||||
|
||||
public ExpressionNormalizerTemplate(Map<String, DimensionApplicableNoiseSampler> globalSamplers,
|
||||
Map<String, FunctionTemplate> globalFunctions) {
|
||||
Map<String, FunctionTemplate> globalFunctions,
|
||||
ParseOptions parseOptions) {
|
||||
this.globalSamplers = globalSamplers;
|
||||
this.globalFunctions = globalFunctions;
|
||||
this.parseOptions = parseOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,7 +62,7 @@ public class ExpressionNormalizerTemplate extends NormalizerTemplate<ExpressionN
|
||||
var mergedSamplers = new HashMap<>(globalSamplers);
|
||||
mergedSamplers.putAll(samplers);
|
||||
try {
|
||||
return new ExpressionNormalizer(function, convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars);
|
||||
return new ExpressionNormalizer(function, convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars, parseOptions);
|
||||
} catch(ParseException e) {
|
||||
throw new RuntimeException("Failed to parse expression.", e);
|
||||
}
|
||||
|
||||
+17
-3
@@ -2,10 +2,12 @@ package com.dfsek.terra.addons.noise.normalizer;
|
||||
|
||||
import com.dfsek.paralithic.Expression;
|
||||
import com.dfsek.paralithic.eval.parser.Parser;
|
||||
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.paralithic.functions.Function;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
@@ -15,12 +17,24 @@ public class ExpressionNormalizer extends Normalizer {
|
||||
|
||||
private final Expression expression;
|
||||
|
||||
public ExpressionNormalizer(NoiseSampler sampler, Map<String, Function> functions, String eq, Map<String, Double> vars)
|
||||
public ExpressionNormalizer(NoiseSampler sampler, Map<String, Function> functions, String eq, Map<String, Double> vars, ParseOptions parseOptions)
|
||||
throws ParseException {
|
||||
super(sampler);
|
||||
Parser p = new Parser();
|
||||
|
||||
Parser p = new Parser(parseOptions);
|
||||
Scope scope = new Scope();
|
||||
scope.addInvocationVariable("in");
|
||||
|
||||
// 'in' was used as the invocation variable but conflicts with
|
||||
// the new 'in' keyword in Paralithic used to denote the end of a let
|
||||
// expression. To maintain backwards compatibility but also enable the use
|
||||
// of let expressions, if they're enabled then use the longer 'input'
|
||||
// invocation variable instead.
|
||||
if (parseOptions.useLetExpressions()) {
|
||||
scope.addInvocationVariable("input");
|
||||
} else {
|
||||
scope.addInvocationVariable("in");
|
||||
}
|
||||
|
||||
vars.forEach(scope::create);
|
||||
functions.forEach(p::registerFunction);
|
||||
expression = p.parse(eq, scope);
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public class UserDefinedFunction implements DynamicFunction {
|
||||
public static UserDefinedFunction newInstance(FunctionTemplate template) throws ParseException {
|
||||
UserDefinedFunction function = CACHE.get(template);
|
||||
if(function == null) {
|
||||
Parser parser = new Parser();
|
||||
Parser parser = new Parser(template.getParseOptions());
|
||||
Scope parent = new Scope();
|
||||
|
||||
Scope functionScope = new Scope().withParent(parent);
|
||||
|
||||
+2
@@ -11,10 +11,12 @@ import com.dfsek.terra.api.util.generic.pair.Pair.Mutable;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
import com.github.benmanes.caffeine.cache.Scheduler;
|
||||
import org.jetbrains.annotations.ApiStatus.Experimental;
|
||||
|
||||
import static com.dfsek.terra.api.util.cache.CacheUtils.CACHE_EXECUTOR;
|
||||
|
||||
|
||||
@Experimental
|
||||
public class CacheSampler implements NoiseSampler {
|
||||
|
||||
private final NoiseSampler sampler;
|
||||
|
||||
+3
-2
@@ -9,6 +9,7 @@ package com.dfsek.terra.addons.noise.samplers.noise;
|
||||
|
||||
import com.dfsek.paralithic.Expression;
|
||||
import com.dfsek.paralithic.eval.parser.Parser;
|
||||
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.paralithic.functions.Function;
|
||||
@@ -24,8 +25,8 @@ import com.dfsek.terra.addons.noise.paralithic.noise.SeedContext;
|
||||
public class ExpressionFunction extends NoiseFunction {
|
||||
private final Expression expression;
|
||||
|
||||
public ExpressionFunction(Map<String, Function> functions, String eq, Map<String, Double> vars) throws ParseException {
|
||||
Parser p = new Parser();
|
||||
public ExpressionFunction(Map<String, Function> functions, String eq, Map<String, Double> vars, ParseOptions parseOptions) throws ParseException {
|
||||
Parser p = new Parser(parseOptions);
|
||||
Scope scope = new Scope();
|
||||
|
||||
scope.addInvocationVariable("x");
|
||||
|
||||
+9
-1
@@ -2,6 +2,7 @@ package com.dfsek.terra.addons.numberpredicate;
|
||||
|
||||
import com.dfsek.paralithic.Expression;
|
||||
import com.dfsek.paralithic.eval.parser.Parser;
|
||||
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
|
||||
import com.dfsek.paralithic.eval.parser.Scope;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.tectonic.api.depth.DepthTracker;
|
||||
@@ -15,6 +16,13 @@ import java.util.function.DoublePredicate;
|
||||
|
||||
|
||||
public class DoublePredicateLoader implements TypeLoader<DoublePredicate> {
|
||||
|
||||
private final ParseOptions parseOptions;
|
||||
|
||||
public DoublePredicateLoader(ParseOptions parseOptions) {
|
||||
this.parseOptions = parseOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DoublePredicate load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader,
|
||||
DepthTracker depthTracker) throws LoadException {
|
||||
@@ -22,7 +30,7 @@ public class DoublePredicateLoader implements TypeLoader<DoublePredicate> {
|
||||
Scope scope = new Scope();
|
||||
scope.addInvocationVariable("value");
|
||||
try {
|
||||
Expression expression = new Parser().parse(expressionString, scope);
|
||||
Expression expression = new Parser(parseOptions).parse(expressionString, scope);
|
||||
return d -> expression.evaluate(d) != 0; // Paralithic expressions treat '!= 0' as true
|
||||
} catch(ParseException e) {
|
||||
throw new LoadException("Failed to parse double predicate expression", e, depthTracker);
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ public class NumberPredicateAddon implements AddonInitializer {
|
||||
plugin.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(addon, ConfigPackPreLoadEvent.class)
|
||||
.then(event -> event.getPack().applyLoader(DoublePredicate.class, new DoublePredicateLoader()))
|
||||
.then(event -> event.getPack().applyLoader(DoublePredicate.class, new DoublePredicateLoader(event.getPack().getExpressionParseOptions())))
|
||||
.priority(50)
|
||||
.failThrough();
|
||||
}
|
||||
|
||||
+27
-12
@@ -1,6 +1,11 @@
|
||||
package com.dfsek.terra.addons.generation.structure;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
|
||||
import com.dfsek.terra.addons.generation.structure.config.BiomeStructuresTemplate;
|
||||
import com.dfsek.terra.addons.generation.structure.config.StructureGenerationStageTemplate;
|
||||
import com.dfsek.terra.addons.generation.structure.config.StructureLayerGridDescription;
|
||||
import com.dfsek.terra.addons.generation.structure.config.StructureLayerGridDescription.Template;
|
||||
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
||||
import com.dfsek.terra.api.Platform;
|
||||
import com.dfsek.terra.api.addon.BaseAddon;
|
||||
@@ -8,11 +13,17 @@ import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent;
|
||||
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
|
||||
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||
import com.dfsek.terra.api.inject.annotations.Inject;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.api.world.chunk.generation.util.provider.GenerationStageProvider;
|
||||
import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
||||
public class StructureGenerationAddon implements AddonInitializer {
|
||||
public static final TypeKey<Supplier<ObjectTemplate<GenerationStage>>> STAGE_TYPE_KEY = new TypeKey<>() {
|
||||
};
|
||||
|
||||
@Inject
|
||||
private Platform platform;
|
||||
|
||||
@@ -24,20 +35,24 @@ public class StructureGenerationAddon implements AddonInitializer {
|
||||
platform.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(addon, ConfigPackPreLoadEvent.class)
|
||||
.then(event -> event.getPack()
|
||||
.getOrCreateRegistry(GenerationStageProvider.class)
|
||||
.register(addon.key("STRUCTURE"), pack -> new StructureGenerationStage(platform)))
|
||||
.failThrough();
|
||||
|
||||
platform.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(addon, ConfigurationLoadEvent.class)
|
||||
.then(event -> {
|
||||
if(event.is(Biome.class)) {
|
||||
event.getLoadedObject(Biome.class).getContext().put(event.load(new BiomeStructuresTemplate()).get());
|
||||
}
|
||||
event.getPack().applyLoader(StructureLayerGridDescription.class, Template::new);
|
||||
|
||||
event.getPack()
|
||||
.getOrCreateRegistry(STAGE_TYPE_KEY)
|
||||
.register(addon.key("STRUCTURE"), StructureGenerationStageTemplate::new);
|
||||
})
|
||||
.failThrough();
|
||||
|
||||
// platform.getEventManager()
|
||||
// .getHandler(FunctionalEventHandler.class)
|
||||
// .register(addon, ConfigurationLoadEvent.class)
|
||||
// .then(event -> {
|
||||
// if(event.is(Biome.class)) {
|
||||
// event.getLoadedObject(Biome.class).getContext().put(event.load(new BiomeStructuresTemplate()).get());
|
||||
// }
|
||||
// })
|
||||
// .failThrough();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+21
-3
@@ -1,17 +1,35 @@
|
||||
package com.dfsek.terra.addons.generation.structure;
|
||||
|
||||
import com.dfsek.terra.api.Platform;
|
||||
import com.dfsek.terra.addons.generation.structure.impl.StructureLayerGrid;
|
||||
import com.dfsek.terra.addons.generation.structure.impl.WorldChunk;
|
||||
import com.dfsek.terra.api.world.chunk.Chunk;
|
||||
import com.dfsek.terra.api.world.chunk.generation.ProtoWorld;
|
||||
import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage;
|
||||
|
||||
|
||||
public class StructureGenerationStage implements GenerationStage {
|
||||
private final Platform platform;
|
||||
private final StructureLayerGrid lastLayer;
|
||||
|
||||
public StructureGenerationStage(Platform platform) { this.platform = platform; }
|
||||
public StructureGenerationStage(StructureLayerGrid lastLayer) {
|
||||
this.lastLayer = lastLayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populate(ProtoWorld world) {
|
||||
int chunkX = world.centerChunkX();
|
||||
int chunkZ = world.centerChunkZ();
|
||||
System.out.printf("Populating X%d Y%d%n", chunkX, chunkZ);
|
||||
long seed = world.getSeed();
|
||||
|
||||
Chunk writeChunk = new WorldChunk(world, chunkX, chunkZ);
|
||||
Chunk populatedChunk = lastLayer.getChunk(world, chunkX, chunkZ, seed);
|
||||
|
||||
for(int x = 0; x < 16; x++) {
|
||||
for(int z = 0; z < 16; z++) {
|
||||
for (int y = world.getMinHeight(); y <= world.getMaxHeight(); ++y) {
|
||||
writeChunk.setBlock(x, y, z, populatedChunk.getBlock(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.dfsek.terra.addons.generation.structure.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
|
||||
import com.dfsek.terra.addons.generation.structure.StructureGenerationStage;
|
||||
import com.dfsek.terra.addons.generation.structure.impl.StructureLayerGrid;
|
||||
import com.dfsek.terra.addons.generation.structure.impl.StructureLayerGridImpl;
|
||||
import com.dfsek.terra.addons.generation.structure.impl.WorldStructureLayerGrid;
|
||||
import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class StructureGenerationStageTemplate implements ObjectTemplate<GenerationStage> {
|
||||
@Value("layers")
|
||||
@Default
|
||||
List<StructureLayerGridDescription> layers = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public GenerationStage get() {
|
||||
StructureLayerGrid layer = new WorldStructureLayerGrid();
|
||||
for (StructureLayerGridDescription description : layers) {
|
||||
layer = new StructureLayerGridImpl(layer, description.size(), description.padding(), description.structures(), description.distribution());
|
||||
}
|
||||
return new StructureGenerationStage(layer);
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.dfsek.terra.addons.generation.structure.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.structure.Structure;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
|
||||
public record StructureLayerGridDescription(int padding, int size, ProbabilityCollection<Structure> structures, NoiseSampler distribution) {
|
||||
public static class Template implements ObjectTemplate<StructureLayerGridDescription> {
|
||||
|
||||
@Value("padding")
|
||||
private int padding;
|
||||
|
||||
@Value("size")
|
||||
private int size;
|
||||
|
||||
@Value("structures.structures")
|
||||
private ProbabilityCollection<Structure> structures;
|
||||
|
||||
@Value("structures.distribution")
|
||||
private NoiseSampler distribution;
|
||||
|
||||
@Override
|
||||
public StructureLayerGridDescription get() {
|
||||
return new StructureLayerGridDescription(padding, size, structures, distribution);
|
||||
}
|
||||
}
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
package com.dfsek.terra.addons.generation.structure.impl;
|
||||
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.world.ServerWorld;
|
||||
import com.dfsek.terra.api.world.chunk.Chunk;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
public class CopyOnWriteDelegatedChunk implements Chunk {
|
||||
|
||||
private Chunk delegate;
|
||||
private boolean writeOccurred;
|
||||
|
||||
public CopyOnWriteDelegatedChunk(Chunk delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, BlockState data, boolean physics) {
|
||||
if (!writeOccurred) {
|
||||
writeOccurred = true;
|
||||
delegate = new OverlayChunk(delegate);
|
||||
}
|
||||
// TODO - Tiered caching
|
||||
// First sparse impl using hashmap, if number of set blocks exceeds certain threshold,
|
||||
// then swap delegate to vertically segmented chunk using BlockState[vertChunk][x][z][y]
|
||||
delegate.setBlock(x, y, z, data, physics);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull BlockState getBlock(int x, int y, int z) {
|
||||
return delegate.getBlock(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return delegate.getX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getZ() {
|
||||
return delegate.getZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerWorld getWorld() {
|
||||
return delegate.getWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return delegate.getHandle();
|
||||
}
|
||||
|
||||
public static class OverlayChunk implements Chunk {
|
||||
|
||||
private final Chunk delegate;
|
||||
private final int worldMinHeight;
|
||||
private final BlockState[][][] blocks;
|
||||
|
||||
public OverlayChunk(Chunk delegate) {
|
||||
this.delegate = delegate;
|
||||
ServerWorld world = delegate.getWorld();
|
||||
this.worldMinHeight = world.getMinHeight();
|
||||
this.blocks = new BlockState[16][16][world.getMaxHeight() - worldMinHeight];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, BlockState data, boolean physics) {
|
||||
blocks[x][z][y - worldMinHeight] = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull BlockState getBlock(int x, int y, int z) {
|
||||
BlockState state = blocks[x][z][y - worldMinHeight];
|
||||
if (state == null) return delegate.getBlock(x, y, z);
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return delegate.getX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getZ() {
|
||||
return delegate.getZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerWorld getWorld() {
|
||||
return delegate.getWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return delegate.getHandle();
|
||||
}
|
||||
}
|
||||
}
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
package com.dfsek.terra.addons.generation.structure.impl;
|
||||
|
||||
import com.dfsek.terra.api.block.entity.BlockEntity;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.entity.Entity;
|
||||
import com.dfsek.terra.api.entity.EntityType;
|
||||
import com.dfsek.terra.api.structure.Structure;
|
||||
import com.dfsek.terra.api.util.Rotation;
|
||||
import com.dfsek.terra.api.util.cache.SeededVector2Key;
|
||||
import com.dfsek.terra.api.util.vector.Vector3Int;
|
||||
import com.dfsek.terra.api.world.WritableWorld;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.chunk.Chunk;
|
||||
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
|
||||
|
||||
import com.dfsek.terra.api.world.chunk.generation.ProtoWorld;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a section of the world that contains at most a single structure within the structure layer
|
||||
*/
|
||||
public class StructureCell {
|
||||
|
||||
private final Chunk[][] chunks;
|
||||
private final int size;
|
||||
private final int chunkOriginX;
|
||||
|
||||
private final int chunkOriginZ;
|
||||
|
||||
public StructureCell(StructureLayerGridImpl layer, ProtoWorld world, SeededVector2Key gridPos) {
|
||||
System.out.println("Generating structure cell");
|
||||
this.size = layer.getGridSizeChunks();
|
||||
|
||||
this.chunkOriginX = gridPos.x * size;
|
||||
this.chunkOriginZ = gridPos.z * size;
|
||||
|
||||
this.chunks = new Chunk[size][size];
|
||||
|
||||
for (int x = 0; x < size; ++x) {
|
||||
for (int z = 0; z < size; ++z) {
|
||||
int chunkX = chunkOriginX + x;
|
||||
int chunkZ = chunkOriginZ + z;
|
||||
chunks[x][z] = new CopyOnWriteDelegatedChunk(layer.getPrevious().getChunk(world, chunkX, chunkZ, gridPos.seed));
|
||||
}
|
||||
}
|
||||
int minCoord = (chunkOriginX + layer.getPadding()) * 16;
|
||||
int maxCoord = (chunkOriginZ + layer.getGridSizeChunks() - layer.getPadding()) * 16;
|
||||
// TODO - Make these random within the range
|
||||
int structureX = (minCoord + maxCoord) / 2;
|
||||
int structureZ = (minCoord + maxCoord) / 2;
|
||||
int structureY = (world.getMinHeight() + world.getMaxHeight()) / 2;
|
||||
Vector3Int structureOrigin = Vector3Int.of(structureX, structureY, structureZ);
|
||||
|
||||
Structure structure = layer.getStructures().get(layer.getDistribution(), structureOrigin, gridPos.seed);
|
||||
|
||||
WorldView worldView = new WorldView(world);
|
||||
structure.generate(structureOrigin, worldView, null /* TODO */, Rotation.NONE /* TODO */);
|
||||
}
|
||||
|
||||
public Chunk getChunk(int chunkX, int chunkZ) {
|
||||
return getChunkLocal(chunkX - chunkOriginX, chunkZ - chunkOriginZ);
|
||||
}
|
||||
|
||||
private Chunk getChunkLocal(int ix, int iz) {
|
||||
if (ix < 0 || ix >= size || iz < 0 || iz >= size)
|
||||
throw new IndexOutOfBoundsException("Attempted to retrieve chunk outside of structure cell bounds");
|
||||
return chunks[ix][iz];
|
||||
}
|
||||
|
||||
class WorldView implements WritableWorld {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(WorldView.class);
|
||||
|
||||
private final ProtoWorld worldDelegate;
|
||||
|
||||
private WorldView(ProtoWorld world) {
|
||||
this.worldDelegate = world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockState(int x, int y, int z, BlockState data, boolean physics) {
|
||||
int chunkX = x >> 4;
|
||||
int chunkZ = z >> 4;
|
||||
Chunk chunk = getChunkSafe(chunkX, chunkZ);
|
||||
int xInChunk = x - chunkX << 4;
|
||||
int zInChunk = z - chunkZ << 4;
|
||||
chunk.setBlock(xInChunk, y, zInChunk, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity spawnEntity(double x, double y, double z, EntityType entityType) {
|
||||
return worldDelegate.spawnEntity(x, y, z, entityType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(int x, int y, int z) {
|
||||
int chunkX = x >> 4;
|
||||
int chunkZ = z >> 4;
|
||||
Chunk chunk = getChunkSafe(chunkX, chunkZ);
|
||||
int xInChunk = x - chunkX << 4;
|
||||
int zInChunk = z - chunkZ << 4;
|
||||
return chunk.getBlock(xInChunk, y, zInChunk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity getBlockEntity(int x, int y, int z) {
|
||||
return worldDelegate.getBlockEntity(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkGenerator getGenerator() {
|
||||
return worldDelegate.getGenerator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider getBiomeProvider() {
|
||||
return worldDelegate.getBiomeProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigPack getPack() {
|
||||
return worldDelegate.getPack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return worldDelegate.getSeed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return worldDelegate.getMaxHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return worldDelegate.getMinHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return worldDelegate.getHandle();
|
||||
}
|
||||
|
||||
private Chunk getChunkSafe(int chunkX, int chunkZ) {
|
||||
try {
|
||||
return getChunk(chunkX, chunkZ);
|
||||
} catch(IndexOutOfBoundsException e) {
|
||||
logger.warn("Chunk accessed outside permissible structure boundaries, this may cause unexpected behaviour");
|
||||
return new WorldChunk(worldDelegate, chunkX, chunkZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.dfsek.terra.addons.generation.structure.impl;
|
||||
|
||||
import com.dfsek.terra.api.world.chunk.Chunk;
|
||||
import com.dfsek.terra.api.world.chunk.generation.ProtoWorld;
|
||||
|
||||
|
||||
public interface StructureLayerGrid {
|
||||
Chunk getChunk(ProtoWorld world, int chunkX, int chunkZ, long seed);
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
package com.dfsek.terra.addons.generation.structure.impl;
|
||||
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.structure.Structure;
|
||||
import com.dfsek.terra.api.util.cache.SeededVector2Key;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.chunk.Chunk;
|
||||
|
||||
import com.dfsek.terra.api.world.chunk.generation.ProtoWorld;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
|
||||
|
||||
public class StructureLayerGridImpl implements StructureLayerGrid {
|
||||
|
||||
private final StructureLayerGrid previous;
|
||||
private final Cache<SeededVector2Key, StructureCell> structureCells;
|
||||
|
||||
private final int padding;
|
||||
private final int cellSize;
|
||||
|
||||
protected ProbabilityCollection<Structure> getStructures() {
|
||||
return structures;
|
||||
}
|
||||
|
||||
protected NoiseSampler getDistribution() {
|
||||
return distribution;
|
||||
}
|
||||
|
||||
private final ProbabilityCollection<Structure> structures;
|
||||
private final NoiseSampler distribution;
|
||||
|
||||
public StructureLayerGridImpl(StructureLayerGrid previous, int size, int padding, ProbabilityCollection<Structure> structures,
|
||||
NoiseSampler distribution) {
|
||||
this.previous = previous;
|
||||
this.padding = padding;
|
||||
this.structures = structures;
|
||||
this.distribution = distribution;
|
||||
this.cellSize = 1 + (size + padding) * 2;
|
||||
this.structureCells = Caffeine.newBuilder()
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunk(ProtoWorld world, int chunkX, int chunkZ, long seed) {
|
||||
int cellX = Math.floorMod(chunkX, cellSize);
|
||||
int cellZ = Math.floorMod(chunkZ, cellSize);
|
||||
SeededVector2Key lookupPos = new SeededVector2Key(cellX, cellZ, seed);
|
||||
StructureCell cell = structureCells.get(lookupPos, pos -> new StructureCell(this, world, pos));
|
||||
return cell.getChunk(chunkX, chunkZ);
|
||||
}
|
||||
|
||||
protected int getGridSizeChunks() {
|
||||
return cellSize;
|
||||
}
|
||||
|
||||
protected StructureLayerGrid getPrevious() {
|
||||
return previous;
|
||||
}
|
||||
|
||||
protected int getPadding() {
|
||||
return padding;
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package com.dfsek.terra.addons.generation.structure.impl;
|
||||
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.world.ServerWorld;
|
||||
import com.dfsek.terra.api.world.WritableWorld;
|
||||
import com.dfsek.terra.api.world.chunk.Chunk;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
/**
|
||||
* Temp class that just delegates chunk operations to the world on a block-by-block basis
|
||||
*/
|
||||
public class WorldChunk implements Chunk {
|
||||
|
||||
private final WritableWorld world;
|
||||
private final int x;
|
||||
private final int z;
|
||||
|
||||
public WorldChunk(WritableWorld world, int x, int z) {
|
||||
this.world = world;
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, BlockState data, boolean physics) {
|
||||
world.setBlockState(x, y, z, data, physics);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull BlockState getBlock(int x, int y, int z) {
|
||||
return world.getBlockState(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerWorld getWorld() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.dfsek.terra.addons.generation.structure.impl;
|
||||
|
||||
import com.dfsek.terra.api.world.chunk.Chunk;
|
||||
import com.dfsek.terra.api.world.chunk.generation.ProtoWorld;
|
||||
|
||||
|
||||
public class WorldStructureLayerGrid implements StructureLayerGrid {
|
||||
@Override
|
||||
public Chunk getChunk(ProtoWorld world, int chunkX, int chunkZ, long seed) {
|
||||
return new WorldChunk(world, chunkX, chunkZ);
|
||||
}
|
||||
}
|
||||
@@ -8,4 +8,5 @@ dependencies {
|
||||
|
||||
api("com.github.ben-manes.caffeine", "caffeine", Versions.Libraries.caffeine)
|
||||
|
||||
api("com.dfsek", "paralithic", Versions.Libraries.paralithic)
|
||||
}
|
||||
@@ -13,6 +13,8 @@ import ca.solostudios.strata.version.VersionRange;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
|
||||
|
||||
import com.dfsek.terra.api.addon.BaseAddon;
|
||||
import com.dfsek.terra.api.properties.PropertyHolder;
|
||||
import com.dfsek.terra.api.registry.key.Keyed;
|
||||
@@ -49,6 +51,8 @@ public interface ConfigPack extends LoaderRegistrar,
|
||||
|
||||
Version getVersion();
|
||||
|
||||
ParseOptions getExpressionParseOptions();
|
||||
|
||||
<T> ConfigPack registerShortcut(TypeKey<T> clazz, String shortcut, ShortcutLoader<T> loader);
|
||||
|
||||
default <T> ConfigPack registerShortcut(Class<T> clazz, String shortcut, ShortcutLoader<T> loader) {
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.dfsek.terra.config;
|
||||
|
||||
import ca.solostudios.strata.version.Version;
|
||||
import ca.solostudios.strata.version.VersionRange;
|
||||
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
|
||||
import com.dfsek.tectonic.api.TypeRegistry;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -31,6 +32,7 @@ import com.dfsek.terra.api.tectonic.LoaderRegistrar;
|
||||
import com.dfsek.terra.api.util.Range;
|
||||
import com.dfsek.terra.api.util.collection.MaterialSet;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.config.loaders.ExpressionParserOptionsTemplate;
|
||||
import com.dfsek.terra.config.loaders.LinkedHashMapLoader;
|
||||
import com.dfsek.terra.config.loaders.MaterialSetLoader;
|
||||
import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader;
|
||||
@@ -53,7 +55,8 @@ public class GenericLoaders implements LoaderRegistrar {
|
||||
.registerLoader(Version.class, new VersionLoader())
|
||||
.registerLoader(MaterialSet.class, new MaterialSetLoader())
|
||||
.registerLoader(VersionRange.class, new VersionRangeLoader())
|
||||
.registerLoader(LinkedHashMap.class, new LinkedHashMapLoader());
|
||||
.registerLoader(LinkedHashMap.class, new LinkedHashMapLoader())
|
||||
.registerLoader(ParseOptions.class, ExpressionParserOptionsTemplate::new);
|
||||
|
||||
if(platform != null) {
|
||||
registry.registerLoader(BaseAddon.class, platform.getAddons())
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.dfsek.terra.config.loaders;
|
||||
|
||||
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
|
||||
|
||||
public class ExpressionParserOptionsTemplate implements ObjectTemplate<ParseOptions> {
|
||||
|
||||
private static final ParseOptions DEFAULT_PARSE_OPTIONS = new ParseOptions();
|
||||
|
||||
@Value("use-let-expressions")
|
||||
@Default
|
||||
private boolean useLetExpressions = DEFAULT_PARSE_OPTIONS.useLetExpressions();
|
||||
|
||||
@Override
|
||||
public ParseOptions get() {
|
||||
return new ParseOptions(useLetExpressions);
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.dfsek.terra.config.pack;
|
||||
|
||||
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
|
||||
import com.dfsek.tectonic.api.config.template.ConfigTemplate;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
|
||||
|
||||
public class ConfigPackExpressionOptionsTemplate implements ConfigTemplate {
|
||||
@Value("expressions.options")
|
||||
@Default
|
||||
private ParseOptions parseOptions = new ParseOptions();
|
||||
|
||||
public ParseOptions getParseOptions() {
|
||||
return parseOptions;
|
||||
}
|
||||
}
|
||||
+14
-1
@@ -19,6 +19,7 @@ package com.dfsek.terra.config.pack;
|
||||
|
||||
import ca.solostudios.strata.version.Version;
|
||||
import ca.solostudios.strata.version.VersionRange;
|
||||
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
|
||||
import com.dfsek.tectonic.api.TypeRegistry;
|
||||
import com.dfsek.tectonic.api.config.Configuration;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
@@ -121,6 +122,8 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
|
||||
private final RegistryKey key;
|
||||
|
||||
private final ParseOptions parseOptions;
|
||||
|
||||
public ConfigPackImpl(File folder, Platform platform) {
|
||||
this(new FolderLoader(folder.toPath()), Construct.construct(() -> {
|
||||
try {
|
||||
@@ -168,6 +171,11 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
selfLoader.load(addonsTemplate, packManifest);
|
||||
this.addons = addonsTemplate.getAddons();
|
||||
|
||||
ConfigPackExpressionOptionsTemplate expressionOptionsTemplate = new ConfigPackExpressionOptionsTemplate();
|
||||
selfLoader.load(expressionOptionsTemplate, packManifest);
|
||||
this.parseOptions = expressionOptionsTemplate.getParseOptions();
|
||||
|
||||
|
||||
Map<String, Configuration> configurations = discoverConfigurations();
|
||||
registerMeta(configurations);
|
||||
|
||||
@@ -261,7 +269,7 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
selfLoader.registerPreprocessor(Meta.class, valuePreprocessor);
|
||||
abstractConfigLoader.registerPreprocessor(Meta.class, valuePreprocessor);
|
||||
|
||||
MetaNumberPreprocessor numberPreprocessor = new MetaNumberPreprocessor(configurations);
|
||||
MetaNumberPreprocessor numberPreprocessor = new MetaNumberPreprocessor(configurations, parseOptions);
|
||||
selfLoader.registerPreprocessor(Meta.class, numberPreprocessor);
|
||||
abstractConfigLoader.registerPreprocessor(Meta.class, numberPreprocessor);
|
||||
}
|
||||
@@ -362,6 +370,11 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
return template.getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParseOptions getExpressionParseOptions() {
|
||||
return parseOptions;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked,rawtypes")
|
||||
@Override
|
||||
public <T> ConfigPack registerShortcut(TypeKey<T> clazz, String shortcut, ShortcutLoader<T> loader) {
|
||||
|
||||
+5
-2
@@ -18,6 +18,7 @@
|
||||
package com.dfsek.terra.config.preprocessor;
|
||||
|
||||
import com.dfsek.paralithic.eval.parser.Parser;
|
||||
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
|
||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||
import com.dfsek.tectonic.api.config.Configuration;
|
||||
import com.dfsek.tectonic.api.depth.DepthTracker;
|
||||
@@ -37,9 +38,11 @@ import java.util.Map;
|
||||
public class MetaNumberPreprocessor extends MetaPreprocessor<Meta> {
|
||||
public static final TypeKey<String> META_STRING_KEY = new TypeKey<@Meta String>() {
|
||||
};
|
||||
private final ParseOptions parseOptions;
|
||||
|
||||
public MetaNumberPreprocessor(Map<String, Configuration> configs) {
|
||||
public MetaNumberPreprocessor(Map<String, Configuration> configs, ParseOptions parseOptions) {
|
||||
super(configs);
|
||||
this.parseOptions = parseOptions;
|
||||
}
|
||||
|
||||
private static boolean isNumber(Class<?> clazz) {
|
||||
@@ -57,7 +60,7 @@ public class MetaNumberPreprocessor extends MetaPreprocessor<Meta> {
|
||||
if(t.getType() instanceof Class && isNumber((Class<?>) t.getType()) && c instanceof String) {
|
||||
String expression = (String) loader.loadType(META_STRING_KEY.getAnnotatedType(), c, depthTracker);
|
||||
try {
|
||||
return (Result<T>) Result.overwrite(new Parser().eval(expression), depthTracker);
|
||||
return (Result<T>) Result.overwrite(new Parser(parseOptions).eval(expression), depthTracker);
|
||||
} catch(ParseException e) {
|
||||
throw new LoadException("Invalid expression: ", e, depthTracker);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
|
||||
import com.dfsek.tectonic.api.config.Configuration;
|
||||
import com.dfsek.tectonic.api.config.template.ConfigTemplate;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
@@ -32,7 +33,7 @@ public class MetaTest {
|
||||
loader.registerPreprocessor(Meta.class, new MetaStringPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaListLikePreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaMapPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaNumberPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaNumberPreprocessor(configurationMap, new ParseOptions()));
|
||||
|
||||
loader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurationMap));
|
||||
|
||||
@@ -53,7 +54,7 @@ public class MetaTest {
|
||||
loader.registerPreprocessor(Meta.class, new MetaStringPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaListLikePreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaMapPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaNumberPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaNumberPreprocessor(configurationMap, new ParseOptions()));
|
||||
|
||||
loader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurationMap));
|
||||
|
||||
@@ -75,7 +76,7 @@ public class MetaTest {
|
||||
loader.registerPreprocessor(Meta.class, new MetaStringPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaListLikePreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaMapPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaNumberPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaNumberPreprocessor(configurationMap, new ParseOptions()));
|
||||
|
||||
loader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurationMap));
|
||||
|
||||
@@ -96,7 +97,7 @@ public class MetaTest {
|
||||
loader.registerPreprocessor(Meta.class, new MetaStringPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaListLikePreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaMapPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaNumberPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaNumberPreprocessor(configurationMap, new ParseOptions()));
|
||||
|
||||
loader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurationMap));
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# Allay platform
|
||||
|
||||
## Resource files
|
||||
|
||||
Current mapping version: je 1.21 to be 1.21.30
|
||||
|
||||
- `mapping/biomes.json` obtain from GeyserMC/mappings.
|
||||
- `mapping/items.json` obtain from GeyserMC/mappings.
|
||||
- `mapping/blocks.json` generated by using GeyserMC/mappings-generator, and it's origin name is `generator_blocks.json`.
|
||||
- `je_block_default_states.json` converted from https://zh.minecraft.wiki/w/Module:Block_state_values.
|
||||
@@ -0,0 +1,5 @@
|
||||
dependencies {
|
||||
shadedApi(project(":common:implementation:base"))
|
||||
|
||||
compileOnly("org.allaymc.allay", "api", Versions.Allay.api)
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.dfsek.terra.allay;
|
||||
|
||||
import com.dfsek.tectonic.api.TypeRegistry;
|
||||
import com.dfsek.tectonic.api.depth.DepthTracker;
|
||||
import com.dfsek.tectonic.api.exception.LoadException;
|
||||
import org.allaymc.api.server.Server;
|
||||
import org.allaymc.api.world.biome.BiomeId;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.dfsek.terra.AbstractPlatform;
|
||||
import com.dfsek.terra.allay.delegate.AllayBiome;
|
||||
import com.dfsek.terra.allay.generator.AllayGeneratorWrapper;
|
||||
import com.dfsek.terra.allay.handle.AllayItemHandle;
|
||||
import com.dfsek.terra.allay.handle.AllayWorldHandle;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.handle.ItemHandle;
|
||||
import com.dfsek.terra.api.handle.WorldHandle;
|
||||
import com.dfsek.terra.api.world.biome.PlatformBiome;
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public class AllayPlatform extends AbstractPlatform {
|
||||
|
||||
public static final Set<AllayGeneratorWrapper> GENERATOR_WRAPPERS = new HashSet<>();
|
||||
|
||||
protected static final AllayWorldHandle ALLAY_WORLD_HANDLE = new AllayWorldHandle();
|
||||
protected static final AllayItemHandle ALLAY_ITEM_HANDLE = new AllayItemHandle();
|
||||
|
||||
public AllayPlatform() {
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reload() {
|
||||
getTerraConfig().load(this);
|
||||
getRawConfigRegistry().clear();
|
||||
boolean succeed = getRawConfigRegistry().loadAll(this);
|
||||
|
||||
GENERATOR_WRAPPERS.forEach(wrapper -> {
|
||||
getConfigRegistry().get(wrapper.getConfigPack().getRegistryKey()).ifPresent(pack -> {
|
||||
wrapper.setConfigPack(pack);
|
||||
var dimension = wrapper.getAllayWorldGenerator().getDimension();
|
||||
TerraAllayPlugin.INSTANCE.getPluginLogger().info(
|
||||
"Replaced pack in chunk generator for world {}",
|
||||
dimension.getWorld().getWorldData().getName() + ":" + dimension.getDimensionInfo().dimensionId()
|
||||
);
|
||||
});
|
||||
});
|
||||
return succeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String platformName() {
|
||||
return "Allay";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull WorldHandle getWorldHandle() {
|
||||
return ALLAY_WORLD_HANDLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemHandle getItemHandle() {
|
||||
return ALLAY_ITEM_HANDLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull File getDataFolder() {
|
||||
return TerraAllayPlugin.INSTANCE.getPluginContainer().dataFolder().toFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runPossiblyUnsafeTask(@NotNull Runnable task) {
|
||||
Server.getInstance().getScheduler().runLater(Server.getInstance(), task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(TypeRegistry registry) {
|
||||
super.register(registry);
|
||||
registry.registerLoader(BlockState.class, (type, o, loader, depthTracker) -> ALLAY_WORLD_HANDLE.createBlockState((String) o))
|
||||
.registerLoader(PlatformBiome.class, (type, o, loader, depthTracker) -> parseBiome((String) o, depthTracker));
|
||||
}
|
||||
|
||||
protected AllayBiome parseBiome(String id, DepthTracker depthTracker) throws LoadException {
|
||||
if(!id.startsWith("minecraft:")) throw new LoadException("Invalid biome identifier " + id, depthTracker);
|
||||
return new AllayBiome(BiomeId.fromId(Mapping.biomeIdJeToBe(id)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.dfsek.terra.allay;
|
||||
|
||||
import org.allaymc.api.utils.HashUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public class JeBlockState {
|
||||
protected final String identifier;
|
||||
protected final TreeMap<String, String> properties;
|
||||
protected int hash = Integer.MAX_VALUE;
|
||||
|
||||
public static JeBlockState fromString(String data) {
|
||||
return new JeBlockState(data);
|
||||
}
|
||||
|
||||
public static JeBlockState create(String identifier, TreeMap<String, String> properties) {
|
||||
return new JeBlockState(identifier, properties);
|
||||
}
|
||||
|
||||
private JeBlockState(String data) {
|
||||
String[] strings = data.replace("[", ",").replace("]", ",").replace(" ", "").split(",");
|
||||
this.identifier = strings[0];
|
||||
this.properties = new TreeMap<>();
|
||||
if (strings.length > 1) {
|
||||
for (int i = 1; i < strings.length; i++) {
|
||||
final String tmp = strings[i];
|
||||
final int index = tmp.indexOf("=");
|
||||
properties.put(tmp.substring(0, index), tmp.substring(index + 1));
|
||||
}
|
||||
}
|
||||
completeMissingProperties();
|
||||
}
|
||||
|
||||
public String getPropertyValue(String key) {
|
||||
return properties.get(key);
|
||||
}
|
||||
|
||||
private void completeMissingProperties() {
|
||||
Map<String, String> defaultProperties = Mapping.getJeBlockDefaultProperties(identifier);
|
||||
if(properties.size() == defaultProperties.size()) {
|
||||
return;
|
||||
}
|
||||
defaultProperties.entrySet().stream().filter(entry -> !properties.containsKey(entry.getKey())).forEach(
|
||||
entry -> properties.put(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
|
||||
private JeBlockState(String identifier, TreeMap<String, String> properties) {
|
||||
this.identifier = identifier;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public String toString(boolean includeProperties) {
|
||||
if(!includeProperties) return identifier;
|
||||
StringBuilder builder = new StringBuilder(identifier).append(";");
|
||||
properties.forEach((k, v) -> builder.append(k).append("=").append(v).append(";"));
|
||||
String str = builder.toString();
|
||||
if (hash == Integer.MAX_VALUE) {
|
||||
hash = HashUtils.fnv1a_32(str.getBytes());
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
public int getHash() {
|
||||
if (hash == Integer.MAX_VALUE) {
|
||||
hash = HashUtils.fnv1a_32(toString(true).getBytes());
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
package com.dfsek.terra.allay;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import org.allaymc.api.block.type.BlockState;
|
||||
import org.allaymc.api.block.type.BlockStateSafeGetter;
|
||||
import org.allaymc.api.block.type.BlockStateSafeGetter.Getter;
|
||||
import org.allaymc.api.block.type.BlockTypes;
|
||||
import org.allaymc.api.item.type.ItemType;
|
||||
import org.allaymc.api.item.type.ItemTypeSafeGetter;
|
||||
import org.allaymc.api.utils.JSONUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public final class Mapping {
|
||||
|
||||
private static final Map<String, Map<String, String>> JE_BLOCK_DEFAULT_PROPERTIES = new Object2ObjectOpenHashMap<>();
|
||||
private static final Map<BlockState, JeBlockState> BLOCK_STATE_BE_TO_JE = new Object2ObjectOpenHashMap<>();
|
||||
private static final Map<Integer, BlockState> BLOCK_STATE_JE_HASH_TO_BE = new Int2ObjectOpenHashMap<>();
|
||||
private static final Map<String, ItemType<?>> ITEM_ID_JE_TO_BE = new Object2ObjectOpenHashMap<>();
|
||||
private static final Map<String, Integer> BIOME_ID_JE_TO_BE = new Object2IntOpenHashMap<>();
|
||||
private static final BlockState BE_AIR_STATE = BlockTypes.AIR.getDefaultState();
|
||||
|
||||
public static void init() {
|
||||
if(!initBlockStateMapping()) error();
|
||||
if(!initJeBlockDefaultProperties()) error();
|
||||
if(!initItemMapping()) error();
|
||||
if(!initBiomeMapping()) error();
|
||||
}
|
||||
|
||||
public static JeBlockState blockStateBeToJe(BlockState beBlockState) {
|
||||
return BLOCK_STATE_BE_TO_JE.get(beBlockState);
|
||||
}
|
||||
|
||||
public static BlockState blockStateJeToBe(JeBlockState jeBlockState) {
|
||||
BlockState result = BLOCK_STATE_JE_HASH_TO_BE.get(jeBlockState.getHash());
|
||||
if(result == null) {
|
||||
TerraAllayPlugin.INSTANCE.getPluginLogger().warn("Failed to find be block state for {}", jeBlockState);
|
||||
return BE_AIR_STATE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ItemType<?> itemIdJeToBe(String jeItemId) {
|
||||
return ITEM_ID_JE_TO_BE.get(jeItemId);
|
||||
}
|
||||
|
||||
// Enchantment identifiers are same in both versions
|
||||
|
||||
public static String enchantmentIdBeToJe(String beEnchantmentId) {
|
||||
return beEnchantmentId;
|
||||
}
|
||||
|
||||
public static String enchantmentIdJeToBe(String jeEnchantmentId) {
|
||||
return jeEnchantmentId;
|
||||
}
|
||||
|
||||
public static int biomeIdJeToBe(String jeBiomeId) {
|
||||
return BIOME_ID_JE_TO_BE.get(jeBiomeId);
|
||||
}
|
||||
|
||||
public static Map<String, String> getJeBlockDefaultProperties(String jeBlockIdentifier) {
|
||||
Map<String, String> defaultProperties = JE_BLOCK_DEFAULT_PROPERTIES.get(jeBlockIdentifier);
|
||||
if( defaultProperties == null) {
|
||||
TerraAllayPlugin.INSTANCE.getPluginLogger().warn("Failed to find default properties for {}", jeBlockIdentifier);
|
||||
return Map.of();
|
||||
}
|
||||
return defaultProperties;
|
||||
}
|
||||
|
||||
private static void error() {
|
||||
throw new RuntimeException("Mapping not initialized");
|
||||
}
|
||||
|
||||
private static boolean initBiomeMapping() {
|
||||
try (InputStream stream = Mapping.class.getClassLoader().getResourceAsStream("mapping/biomes.json")) {
|
||||
if (stream == null) {
|
||||
TerraAllayPlugin.INSTANCE.getPluginLogger().error("biomes mapping not found");
|
||||
return false;
|
||||
}
|
||||
Set<Entry<String, Map<String, Integer>>> mappings = JSONUtils.from(stream, new TypeToken<Map<String, Map<String, Integer>>>(){}).entrySet();
|
||||
mappings.forEach(mapping -> BIOME_ID_JE_TO_BE.put(mapping.getKey(), mapping.getValue().get("bedrock_id")));
|
||||
} catch(IOException e) {
|
||||
TerraAllayPlugin.INSTANCE.getPluginLogger().error("Failed to load biomes mapping", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean initItemMapping() {
|
||||
try (InputStream stream = Mapping.class.getClassLoader().getResourceAsStream("mapping/items.json")) {
|
||||
if (stream == null) {
|
||||
TerraAllayPlugin.INSTANCE.getPluginLogger().error("items mapping not found");
|
||||
return false;
|
||||
}
|
||||
Set<Entry<String, Map<String, Object>>> mappings = JSONUtils.from(stream, new TypeToken<Map<String, Map<String, Object>>>(){}).entrySet();
|
||||
mappings.forEach(mapping -> {
|
||||
ItemType<?> item = ItemTypeSafeGetter
|
||||
.name((String) mapping.getValue().get("bedrock_identifier"))
|
||||
// NOTICE: should be cast to double
|
||||
.meta(((Double) mapping.getValue().get("bedrock_data")).intValue())
|
||||
.itemType();
|
||||
ITEM_ID_JE_TO_BE.put(mapping.getKey(), item);
|
||||
});
|
||||
} catch(IOException e) {
|
||||
TerraAllayPlugin.INSTANCE.getPluginLogger().error("Failed to load items mapping", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean initBlockStateMapping() {
|
||||
try (InputStream stream = Mapping.class.getClassLoader().getResourceAsStream("mapping/blocks.json")) {
|
||||
if (stream == null) {
|
||||
TerraAllayPlugin.INSTANCE.getPluginLogger().error("blocks mapping not found");
|
||||
return false;
|
||||
}
|
||||
// noinspection unchecked
|
||||
List<Map<String, Map<String, Object>>> mappings = (List<Map<String, Map<String, Object>>>) JSONUtils.from(stream, new TypeToken<Map<String, Object>>(){}).get("mappings");
|
||||
mappings.forEach(mapping -> {
|
||||
JeBlockState jeState = createJeBlockState(mapping.get("java_state"));
|
||||
BlockState beState = createBeBlockState(mapping.get("bedrock_state"));
|
||||
BLOCK_STATE_BE_TO_JE.put(beState, jeState);
|
||||
BLOCK_STATE_JE_HASH_TO_BE.put(jeState.getHash(), beState);
|
||||
});
|
||||
} catch(IOException e) {
|
||||
TerraAllayPlugin.INSTANCE.getPluginLogger().error("Failed to load blocks mapping", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean initJeBlockDefaultProperties() {
|
||||
try (InputStream stream = Mapping.class.getClassLoader().getResourceAsStream("je_block_default_states.json")) {
|
||||
if (stream == null) {
|
||||
TerraAllayPlugin.INSTANCE.getPluginLogger().error("je_block_default_states.json not found");
|
||||
return false;
|
||||
}
|
||||
Map<String, Map<String, String>> states = JSONUtils.from(stream, new TypeToken<Map<String, Map<String, String>>>(){});
|
||||
for(Entry<String, Map<String, String>> entry : states.entrySet()) {
|
||||
String identifier = entry.getKey();
|
||||
Map<String, String> properties = entry.getValue();
|
||||
JE_BLOCK_DEFAULT_PROPERTIES.put(identifier, properties);
|
||||
}
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static BlockState createBeBlockState(Map<String, Object> data) {
|
||||
Getter getter = BlockStateSafeGetter
|
||||
.name("minecraft:" + data.get("bedrock_identifier"));
|
||||
if (data.containsKey("state")) {
|
||||
// noinspection unchecked
|
||||
convertValueType((Map<String, Object>) data.get("state")).forEach(getter::property);
|
||||
}
|
||||
return getter.blockState();
|
||||
}
|
||||
|
||||
private static Map<String, Object> convertValueType(Map<String, Object> data) {
|
||||
TreeMap<String, Object> result = new TreeMap<>();
|
||||
for (Entry<String, Object> entry : data.entrySet()) {
|
||||
if (entry.getValue() instanceof Number number) {
|
||||
// Convert double to int because the number in json is double
|
||||
result.put(entry.getKey(), number.intValue());
|
||||
} else {
|
||||
result.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static JeBlockState createJeBlockState(Map<String, Object> data) {
|
||||
// noinspection unchecked
|
||||
return JeBlockState.create((String) data.get("Name"), new TreeMap<>((Map<String, String>) data.getOrDefault("Properties", Map.of())));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.dfsek.terra.allay;
|
||||
|
||||
import org.allaymc.api.eventbus.EventHandler;
|
||||
import org.allaymc.api.eventbus.event.world.WorldUnloadEvent;
|
||||
import org.allaymc.api.plugin.Plugin;
|
||||
import org.allaymc.api.registry.Registries;
|
||||
import org.allaymc.api.server.Server;
|
||||
|
||||
import com.dfsek.terra.allay.generator.AllayGeneratorWrapper;
|
||||
import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent;
|
||||
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public class TerraAllayPlugin extends Plugin {
|
||||
|
||||
public static TerraAllayPlugin INSTANCE;
|
||||
public static AllayPlatform PLATFORM;
|
||||
|
||||
{
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
pluginLogger.info("Starting Terra...");
|
||||
|
||||
pluginLogger.info("Loading mapping...");
|
||||
Mapping.init();
|
||||
|
||||
pluginLogger.info("Initializing allay platform...");
|
||||
PLATFORM = new AllayPlatform();
|
||||
PLATFORM.getEventManager().callEvent(new PlatformInitializationEvent());
|
||||
// TODO: adapt command manager
|
||||
|
||||
pluginLogger.info("Registering generator...");
|
||||
Registries.WORLD_GENERATOR_FACTORIES.register("TERRA", preset -> {
|
||||
try {
|
||||
AllayGeneratorWrapper wrapper = new AllayGeneratorWrapper(preset);
|
||||
AllayPlatform.GENERATOR_WRAPPERS.add(wrapper);
|
||||
return wrapper.getAllayWorldGenerator();
|
||||
} catch (IllegalArgumentException e) {
|
||||
TerraAllayPlugin.INSTANCE.getPluginLogger().error("Fail to create world generator with preset: {}", preset);
|
||||
TerraAllayPlugin.INSTANCE.getPluginLogger().error("Reason: {}", e.getMessage());
|
||||
return Registries.WORLD_GENERATOR_FACTORIES.get("FLAT").apply("");
|
||||
}
|
||||
});
|
||||
|
||||
pluginLogger.info("Terra started");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
Server.getInstance().getEventBus().registerListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReloadable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
if(PLATFORM.reload()) {
|
||||
pluginLogger.info("Terra reloaded successfully.");
|
||||
} else {
|
||||
pluginLogger.error("Terra failed to reload.");
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
private void onWorldUnload(WorldUnloadEvent event) {
|
||||
AllayPlatform.GENERATOR_WRAPPERS.removeIf(wrapper -> wrapper.getAllayWorldGenerator().getDimension().getWorld() == event.getWorld());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.dfsek.terra.allay.delegate;
|
||||
|
||||
import org.allaymc.api.world.biome.BiomeType;
|
||||
|
||||
import com.dfsek.terra.api.world.biome.PlatformBiome;
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public record AllayBiome(BiomeType allayBiome) implements PlatformBiome {
|
||||
@Override
|
||||
public BiomeType getHandle() {
|
||||
return allayBiome;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.dfsek.terra.allay.delegate;
|
||||
|
||||
import org.allaymc.api.block.type.BlockState;
|
||||
import org.allaymc.api.block.type.BlockTypes;
|
||||
|
||||
import com.dfsek.terra.allay.JeBlockState;
|
||||
import com.dfsek.terra.api.block.BlockType;
|
||||
import com.dfsek.terra.api.block.state.properties.Property;
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public final class AllayBlockState implements com.dfsek.terra.api.block.state.BlockState {
|
||||
|
||||
public static final AllayBlockState AIR = new AllayBlockState(BlockTypes.AIR.getDefaultState(),
|
||||
JeBlockState.fromString("minecraft:air"));
|
||||
|
||||
private final BlockState allayBlockState;
|
||||
private final JeBlockState jeBlockState;
|
||||
private final boolean containsWater;
|
||||
|
||||
public AllayBlockState(BlockState allayBlockState, JeBlockState jeBlockState) {
|
||||
this.allayBlockState = allayBlockState;
|
||||
this.jeBlockState = jeBlockState;
|
||||
this.containsWater = "true".equals(jeBlockState.getPropertyValue("waterlogged"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(com.dfsek.terra.api.block.state.BlockState o) {
|
||||
AllayBlockState other = ((AllayBlockState) o);
|
||||
return other.allayBlockState == this.allayBlockState && other.containsWater == this.containsWater;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Comparable<T>> boolean has(Property<T> property) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Comparable<T>> T get(Property<T> property) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Comparable<T>> com.dfsek.terra.api.block.state.BlockState set(Property<T> property, T value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockType getBlockType() {
|
||||
return new AllayBlockType(allayBlockState.getBlockType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsString(boolean properties) {
|
||||
return jeBlockState.toString(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAir() {
|
||||
return allayBlockState.getBlockType() == BlockTypes.AIR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getHandle() {
|
||||
return allayBlockState;
|
||||
}
|
||||
|
||||
public BlockState allayBlockState() { return allayBlockState; }
|
||||
|
||||
public boolean containsWater() { return containsWater; }
|
||||
|
||||
public JeBlockState jeBlockState() { return jeBlockState; }
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.dfsek.terra.allay.delegate;
|
||||
|
||||
import org.allaymc.api.block.tag.BlockTags;
|
||||
import org.allaymc.api.block.type.BlockType;
|
||||
|
||||
import com.dfsek.terra.allay.Mapping;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public record AllayBlockType(BlockType<?> allayBlockType) implements com.dfsek.terra.api.block.BlockType {
|
||||
@Override
|
||||
public BlockState getDefaultState() {
|
||||
return new AllayBlockState(allayBlockType.getDefaultState(), Mapping.blockStateBeToJe(allayBlockType.getDefaultState()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSolid() {
|
||||
return allayBlockType.getMaterial().isSolid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWater() {
|
||||
return allayBlockType.hasBlockTag(BlockTags.WATER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockType<?> getHandle() {
|
||||
return allayBlockType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.dfsek.terra.allay.delegate;
|
||||
|
||||
import org.allaymc.api.block.property.type.BlockPropertyTypes;
|
||||
import org.allaymc.api.block.tag.BlockTags;
|
||||
import org.allaymc.api.block.type.BlockTypes;
|
||||
import org.allaymc.api.world.chunk.Chunk;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.dfsek.terra.allay.Mapping;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.world.ServerWorld;
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public record AllayChunk(ServerWorld world, Chunk allayChunk) implements com.dfsek.terra.api.world.chunk.Chunk {
|
||||
|
||||
private static final org.allaymc.api.block.type.BlockState WATER = BlockTypes.WATER.ofState(BlockPropertyTypes.LIQUID_DEPTH.createValue(0));
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, BlockState data, boolean physics) {
|
||||
AllayBlockState allayBlockState = (AllayBlockState) data;
|
||||
allayChunk.setBlockState(x, y, z, allayBlockState.allayBlockState());
|
||||
boolean containsWater = allayBlockState.containsWater() || allayChunk.getBlockState(x, y, z).getBlockType().hasBlockTag(BlockTags.WATER);
|
||||
if (containsWater) {
|
||||
allayChunk.setBlockState(x, y, z, WATER, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull BlockState getBlock(int x, int y, int z) {
|
||||
org.allaymc.api.block.type.BlockState blockState = allayChunk.getBlockState(x, y, z);
|
||||
return new AllayBlockState(blockState, Mapping.blockStateBeToJe(blockState));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return allayChunk.getX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getZ() {
|
||||
return allayChunk.getZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerWorld getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getHandle() {
|
||||
return allayChunk;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.dfsek.terra.allay.delegate;
|
||||
|
||||
import org.allaymc.api.item.enchantment.EnchantmentType;
|
||||
|
||||
import com.dfsek.terra.allay.Mapping;
|
||||
import com.dfsek.terra.api.inventory.ItemStack;
|
||||
import com.dfsek.terra.api.inventory.item.Enchantment;
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public record AllayEnchantment(EnchantmentType allayEnchantment) implements Enchantment {
|
||||
@Override
|
||||
public boolean canEnchantItem(ItemStack itemStack) {
|
||||
return ((AllayItemStack)itemStack).allayItemStack().checkEnchantmentCompatibility(allayEnchantment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean conflictsWith(Enchantment other) {
|
||||
return ((AllayEnchantment)other).allayEnchantment.isIncompatibleWith(allayEnchantment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return Mapping.enchantmentIdBeToJe(allayEnchantment.getIdentifier().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxLevel() {
|
||||
return allayEnchantment.getMaxLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnchantmentType getHandle() {
|
||||
return allayEnchantment;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.dfsek.terra.allay.delegate;
|
||||
|
||||
import com.dfsek.terra.api.entity.Entity;
|
||||
import com.dfsek.terra.api.util.vector.Vector3;
|
||||
import com.dfsek.terra.api.world.ServerWorld;
|
||||
|
||||
/**
|
||||
* NOTICE: Entity is not supported currently, and this is a fake implementation.
|
||||
*
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public final class AllayFakeEntity implements Entity {
|
||||
|
||||
private final Object fakeHandle = new Object();
|
||||
private Vector3 position;
|
||||
private ServerWorld world;
|
||||
|
||||
public AllayFakeEntity(Vector3 position, ServerWorld world) {
|
||||
this.position = position;
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3 position() {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void position(Vector3 position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void world(ServerWorld world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerWorld world() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return fakeHandle;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.dfsek.terra.allay.delegate;
|
||||
|
||||
import org.allaymc.api.item.ItemStack;
|
||||
import org.allaymc.api.item.enchantment.EnchantmentInstance;
|
||||
import org.allaymc.api.item.enchantment.EnchantmentType;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.inventory.item.Enchantment;
|
||||
import com.dfsek.terra.api.inventory.item.ItemMeta;
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public record AllayItemMeta(ItemStack allayItemStack) implements ItemMeta {
|
||||
@Override
|
||||
public void addEnchantment(Enchantment enchantment, int level) {
|
||||
EnchantmentType allayEnchantment = ((AllayEnchantment) enchantment).allayEnchantment();
|
||||
allayItemStack.addEnchantment(allayEnchantment, (short) level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Enchantment, Integer> getEnchantments() {
|
||||
Map<Enchantment, Integer> results = new HashMap<>();
|
||||
for (EnchantmentInstance allayEnchantmentInstance : allayItemStack.getEnchantments()) {
|
||||
results.put(new AllayEnchantment(allayEnchantmentInstance.getType()), allayEnchantmentInstance.getLevel());
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getHandle() {
|
||||
return allayItemStack;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.dfsek.terra.allay.delegate;
|
||||
|
||||
import org.allaymc.api.item.ItemStack;
|
||||
import org.allaymc.api.item.enchantment.EnchantmentInstance;
|
||||
|
||||
import com.dfsek.terra.api.inventory.Item;
|
||||
import com.dfsek.terra.api.inventory.item.ItemMeta;
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public record AllayItemStack(ItemStack allayItemStack) implements com.dfsek.terra.api.inventory.ItemStack{
|
||||
@Override
|
||||
public int getAmount() {
|
||||
return allayItemStack.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAmount(int i) {
|
||||
allayItemStack.setCount(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getType() {
|
||||
return new AllayItemType(allayItemStack.getItemType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemMeta getItemMeta() {
|
||||
return new AllayItemMeta(allayItemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemMeta(ItemMeta meta) {
|
||||
ItemStack targetItem = ((AllayItemMeta) meta).allayItemStack();
|
||||
allayItemStack.removeAllEnchantments();
|
||||
for (EnchantmentInstance enchantment : targetItem.getEnchantments()) {
|
||||
allayItemStack.addEnchantment(enchantment.getType(), enchantment.getLevel());
|
||||
}
|
||||
allayItemStack.setLore(targetItem.getLore());
|
||||
allayItemStack.setDurability(targetItem.getDurability());
|
||||
allayItemStack.setCustomName(targetItem.getCustomName());
|
||||
allayItemStack.setMeta(targetItem.getMeta());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getHandle() {
|
||||
return allayItemStack;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.dfsek.terra.allay.delegate;
|
||||
|
||||
import org.allaymc.api.item.data.ItemId;
|
||||
import org.allaymc.api.item.type.ItemType;
|
||||
import org.allaymc.api.registry.Registries;
|
||||
|
||||
import com.dfsek.terra.api.inventory.Item;
|
||||
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public final class AllayItemType implements Item {
|
||||
private final ItemType<?> allayItemType;
|
||||
private final double maxDurability;
|
||||
|
||||
public AllayItemType(ItemType<?> allayItemType) {
|
||||
this.allayItemType = allayItemType;
|
||||
this.maxDurability = Registries.ITEM_DATA.get(ItemId.fromIdentifier(allayItemType.getIdentifier())).maxDamage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.dfsek.terra.api.inventory.ItemStack newItemStack(int amount) {
|
||||
return new AllayItemStack(allayItemType.createItemStack(amount));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMaxDurability() {
|
||||
return maxDurability;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemType<?> getHandle() {
|
||||
return allayItemType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.dfsek.terra.allay.delegate;
|
||||
|
||||
import org.allaymc.api.block.property.type.BlockPropertyTypes;
|
||||
import org.allaymc.api.block.tag.BlockTags;
|
||||
import org.allaymc.api.block.type.BlockTypes;
|
||||
import org.allaymc.api.world.chunk.UnsafeChunk;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.dfsek.terra.allay.Mapping;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.world.chunk.generation.ProtoChunk;
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public record AllayProtoChunk(UnsafeChunk allayChunk) implements ProtoChunk {
|
||||
|
||||
private static final org.allaymc.api.block.type.BlockState WATER = BlockTypes.WATER.ofState(BlockPropertyTypes.LIQUID_DEPTH.createValue(0));
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return allayChunk.getDimensionInfo().maxHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, @NotNull BlockState blockState) {
|
||||
AllayBlockState allayBlockState = (AllayBlockState) blockState;
|
||||
allayChunk.setBlockState(x, y, z, allayBlockState.allayBlockState());
|
||||
boolean containsWater = allayBlockState.containsWater() || allayChunk.getBlockState(x, y, z).getBlockType().hasBlockTag(BlockTags.WATER);
|
||||
if (containsWater) {
|
||||
allayChunk.setBlockState(x, y, z, WATER, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull BlockState getBlock(int x, int y, int z) {
|
||||
org.allaymc.api.block.type.BlockState blockState = allayChunk.getBlockState(x, y, z);
|
||||
return new AllayBlockState(blockState, Mapping.blockStateBeToJe(blockState));
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnsafeChunk getHandle() {
|
||||
return allayChunk;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.dfsek.terra.allay.delegate;
|
||||
|
||||
import org.allaymc.api.block.property.type.BlockPropertyTypes;
|
||||
import org.allaymc.api.block.tag.BlockTags;
|
||||
import org.allaymc.api.block.type.BlockTypes;
|
||||
import org.allaymc.api.world.generator.context.OtherChunkAccessibleContext;
|
||||
|
||||
import com.dfsek.terra.allay.Mapping;
|
||||
import com.dfsek.terra.api.block.entity.BlockEntity;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.entity.Entity;
|
||||
import com.dfsek.terra.api.entity.EntityType;
|
||||
import com.dfsek.terra.api.util.vector.Vector3;
|
||||
import com.dfsek.terra.api.world.ServerWorld;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
|
||||
import com.dfsek.terra.api.world.chunk.generation.ProtoWorld;
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public record AllayProtoWorld(AllayServerWorld allayServerWorld, OtherChunkAccessibleContext context) implements ProtoWorld {
|
||||
|
||||
private static final org.allaymc.api.block.type.BlockState WATER = BlockTypes.WATER.ofState(BlockPropertyTypes.LIQUID_DEPTH.createValue(0));
|
||||
|
||||
@Override
|
||||
public int centerChunkX() {
|
||||
return context.getCurrentChunk().getX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int centerChunkZ() {
|
||||
return context.getCurrentChunk().getZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerWorld getWorld() {
|
||||
return allayServerWorld;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockState(int x, int y, int z, BlockState data, boolean physics) {
|
||||
AllayBlockState allayBlockState = (AllayBlockState)data;
|
||||
boolean containsWater = allayBlockState.containsWater() || context.getBlockState(x, y, z).getBlockType().hasBlockTag(BlockTags.WATER);
|
||||
context.setBlockState(x, y, z, allayBlockState.allayBlockState());
|
||||
if (containsWater) context.setBlockState(x, y, z, WATER, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(int x, int y, int z) {
|
||||
org.allaymc.api.block.type.BlockState blockState = context.getBlockState(x, y, z);
|
||||
return new AllayBlockState(blockState, Mapping.blockStateBeToJe(blockState));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity spawnEntity(double x, double y, double z, EntityType entityType) {
|
||||
return new AllayFakeEntity(Vector3.of(x, y, z), allayServerWorld);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity getBlockEntity(int x, int y, int z) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkGenerator getGenerator() {
|
||||
return allayServerWorld.getGenerator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider getBiomeProvider() {
|
||||
return allayServerWorld.getBiomeProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigPack getPack() {
|
||||
return allayServerWorld.getPack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return allayServerWorld.getSeed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return allayServerWorld.getMaxHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return allayServerWorld.getMinHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AllayServerWorld getHandle() {
|
||||
return allayServerWorld;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.dfsek.terra.allay.delegate;
|
||||
|
||||
import org.allaymc.api.block.property.type.BlockPropertyTypes;
|
||||
import org.allaymc.api.block.type.BlockTypes;
|
||||
import org.allaymc.api.world.Dimension;
|
||||
|
||||
import com.dfsek.terra.allay.Mapping;
|
||||
import com.dfsek.terra.allay.generator.AllayGeneratorWrapper;
|
||||
import com.dfsek.terra.api.block.entity.BlockEntity;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.entity.Entity;
|
||||
import com.dfsek.terra.api.entity.EntityType;
|
||||
import com.dfsek.terra.api.util.vector.Vector3;
|
||||
import com.dfsek.terra.api.world.ServerWorld;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.chunk.Chunk;
|
||||
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public record AllayServerWorld(AllayGeneratorWrapper allayGeneratorWrapper, Dimension allayDimension) implements ServerWorld {
|
||||
|
||||
private static final org.allaymc.api.block.type.BlockState WATER = BlockTypes.WATER.ofState(BlockPropertyTypes.LIQUID_DEPTH.createValue(0));
|
||||
|
||||
@Override
|
||||
public Chunk getChunkAt(int x, int z) {
|
||||
return new AllayChunk(this, allayDimension.getChunkService().getChunk(x ,z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockState(int x, int y, int z, BlockState data, boolean physics) {
|
||||
// In dimension#setBlockState() method, Water will be moved to layer 1 if it is placed at layer 0
|
||||
allayDimension.setBlockState(x, y, z, ((AllayBlockState) data).allayBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity spawnEntity(double x, double y, double z, EntityType entityType) {
|
||||
return new AllayFakeEntity(Vector3.of(x, y, z), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(int x, int y, int z) {
|
||||
org.allaymc.api.block.type.BlockState allayBlockState = allayDimension.getBlockState(x, y, z);
|
||||
return new AllayBlockState(allayBlockState, Mapping.blockStateBeToJe(allayBlockState));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity getBlockEntity(int x, int y, int z) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkGenerator getGenerator() {
|
||||
return allayGeneratorWrapper.getHandle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider getBiomeProvider() {
|
||||
return allayGeneratorWrapper.getBiomeProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigPack getPack() {
|
||||
return allayGeneratorWrapper.getConfigPack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return allayGeneratorWrapper.getSeed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return allayDimension.getDimensionInfo().maxHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return allayDimension.getDimensionInfo().minHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return allayDimension;
|
||||
}
|
||||
}
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
package com.dfsek.terra.allay.generator;
|
||||
|
||||
import org.allaymc.api.utils.AllayStringUtils;
|
||||
import org.allaymc.api.world.biome.BiomeType;
|
||||
import org.allaymc.api.world.chunk.UnsafeChunk;
|
||||
import org.allaymc.api.world.generator.WorldGenerator;
|
||||
import org.allaymc.api.world.generator.context.NoiseContext;
|
||||
import org.allaymc.api.world.generator.context.PopulateContext;
|
||||
import org.allaymc.api.world.generator.function.Noiser;
|
||||
import org.allaymc.api.world.generator.function.Populator;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.dfsek.terra.allay.TerraAllayPlugin;
|
||||
import com.dfsek.terra.allay.delegate.AllayProtoChunk;
|
||||
import com.dfsek.terra.allay.delegate.AllayProtoWorld;
|
||||
import com.dfsek.terra.allay.delegate.AllayServerWorld;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
|
||||
import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage;
|
||||
import com.dfsek.terra.api.world.chunk.generation.util.GeneratorWrapper;
|
||||
import com.dfsek.terra.api.world.info.WorldProperties;
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public class AllayGeneratorWrapper implements GeneratorWrapper {
|
||||
|
||||
protected static final String OPTION_PACK_NAME = "pack";
|
||||
protected static final String OPTION_SEED = "seed";
|
||||
|
||||
protected final BiomeProvider biomeProvider;
|
||||
protected final long seed;
|
||||
protected final WorldGenerator allayWorldGenerator;
|
||||
protected ChunkGenerator chunkGenerator;
|
||||
protected ConfigPack configPack;
|
||||
protected WorldProperties worldProperties;
|
||||
protected AllayServerWorld allayServerWorld;
|
||||
|
||||
public AllayGeneratorWrapper(String preset) {
|
||||
Map<String, String> options = AllayStringUtils.parseOptions(preset);
|
||||
String packName = options.get(OPTION_PACK_NAME);
|
||||
if(packName == null) {
|
||||
throw new IllegalArgumentException("Missing config pack name");
|
||||
}
|
||||
this.seed = Long.parseLong(options.getOrDefault(OPTION_SEED, "0"));
|
||||
this.configPack = getConfigPack(packName);
|
||||
this.chunkGenerator = createGenerator(this.configPack);
|
||||
this.biomeProvider = this.configPack.getBiomeProvider();
|
||||
this.allayWorldGenerator = WorldGenerator
|
||||
.builder()
|
||||
.name("TERRA")
|
||||
.preset(preset)
|
||||
.noisers(new AllayNoiser())
|
||||
.populators(new AllayPopulator())
|
||||
.onDimensionSet(dimension -> {
|
||||
this.allayServerWorld = new AllayServerWorld(this, dimension);
|
||||
this.worldProperties = new WorldProperties() {
|
||||
|
||||
private final Object fakeHandle = new Object();
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return dimension.getDimensionInfo().maxHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return dimension.getDimensionInfo().minHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return fakeHandle;
|
||||
}
|
||||
};
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkGenerator getHandle() {
|
||||
return chunkGenerator;
|
||||
}
|
||||
|
||||
public BiomeProvider getBiomeProvider() {
|
||||
return this.biomeProvider;
|
||||
}
|
||||
|
||||
public ConfigPack getConfigPack() {
|
||||
return this.configPack;
|
||||
}
|
||||
|
||||
public void setConfigPack(ConfigPack configPack) {
|
||||
this.configPack = configPack;
|
||||
this.chunkGenerator = createGenerator(this.configPack);
|
||||
}
|
||||
|
||||
public long getSeed() {
|
||||
return this.seed;
|
||||
}
|
||||
|
||||
public WorldGenerator getAllayWorldGenerator() {
|
||||
return this.allayWorldGenerator;
|
||||
}
|
||||
|
||||
protected class AllayNoiser implements Noiser {
|
||||
|
||||
@Override
|
||||
public boolean apply(NoiseContext context) {
|
||||
UnsafeChunk chunk = context.getCurrentChunk();
|
||||
int chunkX = chunk.getX();
|
||||
int chunkZ = chunk.getZ();
|
||||
chunkGenerator.generateChunkData(
|
||||
new AllayProtoChunk(chunk),
|
||||
worldProperties, biomeProvider,
|
||||
chunkX, chunkZ
|
||||
);
|
||||
int minHeight = context.getDimensionInfo().minHeight();
|
||||
int maxHeight = context.getDimensionInfo().maxHeight();
|
||||
for(int x = 0; x < 16; x++) {
|
||||
for(int y = minHeight; y < maxHeight; y++) {
|
||||
for(int z = 0; z < 16; z++) {
|
||||
chunk.setBiome(
|
||||
x, y, z,
|
||||
(BiomeType) biomeProvider.getBiome(chunkX * 16 + x, y, chunkZ * 16 + z, seed).getPlatformBiome().getHandle()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "TERRA_NOISER";
|
||||
}
|
||||
}
|
||||
|
||||
protected class AllayPopulator implements Populator {
|
||||
|
||||
@Override
|
||||
public boolean apply(PopulateContext context) {
|
||||
AllayProtoWorld tmp = new AllayProtoWorld(allayServerWorld, context);
|
||||
try {
|
||||
for(GenerationStage generationStage : configPack.getStages()) {
|
||||
generationStage.populate(tmp);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
TerraAllayPlugin.INSTANCE.getPluginLogger().error("Error while populating chunk", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "TERRA_POPULATOR";
|
||||
}
|
||||
}
|
||||
|
||||
protected static ConfigPack getConfigPack(String packName) {
|
||||
Optional<ConfigPack> byId = TerraAllayPlugin.PLATFORM.getConfigRegistry().getByID(packName);
|
||||
return byId.orElseGet(
|
||||
() -> TerraAllayPlugin.PLATFORM.getConfigRegistry().getByID(packName.toUpperCase(Locale.ENGLISH))
|
||||
.orElseThrow(() -> new IllegalArgumentException("Cant find terra config pack named " + packName))
|
||||
);
|
||||
}
|
||||
|
||||
protected static ChunkGenerator createGenerator(ConfigPack configPack) {
|
||||
return configPack.getGeneratorProvider().newInstance(configPack);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.dfsek.terra.allay.handle;
|
||||
|
||||
import org.allaymc.api.registry.Registries;
|
||||
import org.allaymc.api.utils.Identifier;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.dfsek.terra.allay.Mapping;
|
||||
import com.dfsek.terra.allay.delegate.AllayEnchantment;
|
||||
import com.dfsek.terra.allay.delegate.AllayItemType;
|
||||
import com.dfsek.terra.api.handle.ItemHandle;
|
||||
import com.dfsek.terra.api.inventory.Item;
|
||||
import com.dfsek.terra.api.inventory.item.Enchantment;
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public class AllayItemHandle implements ItemHandle {
|
||||
@Override
|
||||
public Item createItem(String data) {
|
||||
return new AllayItemType(Mapping.itemIdJeToBe(data));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enchantment getEnchantment(String id) {
|
||||
return new AllayEnchantment(Registries.ENCHANTMENTS.getByK2(new Identifier(Mapping.enchantmentIdJeToBe(id))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Enchantment> getEnchantments() {
|
||||
return Registries.ENCHANTMENTS.getContent().m1().values().stream()
|
||||
.map(AllayEnchantment::new)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.dfsek.terra.allay.handle;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.dfsek.terra.allay.JeBlockState;
|
||||
import com.dfsek.terra.allay.Mapping;
|
||||
import com.dfsek.terra.allay.delegate.AllayBlockState;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.entity.EntityType;
|
||||
import com.dfsek.terra.api.handle.WorldHandle;
|
||||
|
||||
/**
|
||||
* @author daoge_cmd
|
||||
*/
|
||||
public class AllayWorldHandle implements WorldHandle {
|
||||
|
||||
@Override
|
||||
public @NotNull BlockState createBlockState(@NotNull String data) {
|
||||
JeBlockState jeBlockState = JeBlockState.fromString(data);
|
||||
return new AllayBlockState(Mapping.blockStateJeToBe(jeBlockState), jeBlockState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull BlockState air() {
|
||||
return AllayBlockState.AIR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull EntityType getEntity(@NotNull String id) {
|
||||
return new EntityType() {
|
||||
private final Object fakeEntityType = new Object();
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return fakeEntityType;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
{ "minecraft:badlands": { "bedrock_id": 37 }, "minecraft:bamboo_jungle": { "bedrock_id": 48 }, "minecraft:basalt_deltas": { "bedrock_id": 181 }, "minecraft:beach": { "bedrock_id": 16 }, "minecraft:birch_forest": { "bedrock_id": 27 }, "minecraft:cherry_grove": { "bedrock_id": 192 }, "minecraft:cold_ocean": { "bedrock_id": 44 }, "minecraft:crimson_forest": { "bedrock_id": 179 }, "minecraft:dark_forest": { "bedrock_id": 29 }, "minecraft:deep_cold_ocean": { "bedrock_id": 45 }, "minecraft:deep_dark": { "bedrock_id": 190 }, "minecraft:deep_frozen_ocean": { "bedrock_id": 47 }, "minecraft:deep_lukewarm_ocean": { "bedrock_id": 43 }, "minecraft:deep_ocean": { "bedrock_id": 24 }, "minecraft:desert": { "bedrock_id": 2 }, "minecraft:dripstone_caves": { "bedrock_id": 188 }, "minecraft:end_barrens": { "bedrock_id": 9 }, "minecraft:end_highlands": { "bedrock_id": 9 }, "minecraft:end_midlands": { "bedrock_id": 9 }, "minecraft:eroded_badlands": { "bedrock_id": 165 }, "minecraft:flower_forest": { "bedrock_id": 132 }, "minecraft:forest": { "bedrock_id": 4 }, "minecraft:frozen_ocean": { "bedrock_id": 46 }, "minecraft:frozen_peaks": { "bedrock_id": 183 }, "minecraft:frozen_river": { "bedrock_id": 11 }, "minecraft:grove": { "bedrock_id": 185 }, "minecraft:ice_spikes": { "bedrock_id": 140 }, "minecraft:jagged_peaks": { "bedrock_id": 182 }, "minecraft:jungle": { "bedrock_id": 21 }, "minecraft:lukewarm_ocean": { "bedrock_id": 42 }, "minecraft:lush_caves": { "bedrock_id": 187 }, "minecraft:mangrove_swamp": { "bedrock_id": 191 }, "minecraft:meadow": { "bedrock_id": 186 }, "minecraft:mushroom_fields": { "bedrock_id": 14 }, "minecraft:nether_wastes": { "bedrock_id": 8 }, "minecraft:ocean": { "bedrock_id": 0 }, "minecraft:old_growth_birch_forest": { "bedrock_id": 155 }, "minecraft:old_growth_pine_taiga": { "bedrock_id": 32 }, "minecraft:old_growth_spruce_taiga": { "bedrock_id": 160 }, "minecraft:plains": { "bedrock_id": 1 }, "minecraft:river": { "bedrock_id": 7 }, "minecraft:savanna": { "bedrock_id": 35 }, "minecraft:savanna_plateau": { "bedrock_id": 36 }, "minecraft:small_end_islands": { "bedrock_id": 9 }, "minecraft:snowy_beach": { "bedrock_id": 26 }, "minecraft:snowy_plains": { "bedrock_id": 12 }, "minecraft:snowy_slopes": { "bedrock_id": 184 }, "minecraft:snowy_taiga": { "bedrock_id": 30 }, "minecraft:soul_sand_valley": { "bedrock_id": 178 }, "minecraft:sparse_jungle": { "bedrock_id": 23 }, "minecraft:stony_peaks": { "bedrock_id": 189 }, "minecraft:stony_shore": { "bedrock_id": 25 }, "minecraft:sunflower_plains": { "bedrock_id": 129 }, "minecraft:swamp": { "bedrock_id": 6 }, "minecraft:taiga": { "bedrock_id": 5 }, "minecraft:the_end": { "bedrock_id": 9 }, "minecraft:the_void": { "bedrock_id": 7 }, "minecraft:warm_ocean": { "bedrock_id": 40 }, "minecraft:warped_forest": { "bedrock_id": 180 }, "minecraft:windswept_forest": { "bedrock_id": 34 }, "minecraft:windswept_gravelly_hills": { "bedrock_id": 131 }, "minecraft:windswept_hills": { "bedrock_id": 3 }, "minecraft:windswept_savanna": { "bedrock_id": 163 }, "minecraft:wooded_badlands": { "bedrock_id": 38 } }
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"entrance": "com.dfsek.terra.allay.TerraAllayPlugin",
|
||||
"name": "Terra",
|
||||
"authors": ["daoge_cmd", "dfsek", "duplexsystem", "Astrash", "solonovamax", "Sancires", "Aureus", "RogueShade"],
|
||||
"version": "@VERSION@",
|
||||
"description": "@DESCRIPTION@",
|
||||
"website": "@WIKI@"
|
||||
}
|
||||
@@ -4,7 +4,7 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
shaded(project(":platforms:bukkit:common"))
|
||||
shaded(project(":platforms:bukkit:nms:v1_21", configuration = "reobf"))
|
||||
shaded(project(":platforms:bukkit:nms:v1_21_3", configuration = "reobf"))
|
||||
shaded("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper)
|
||||
}
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@ public class TerraBukkitPlugin extends JavaPlugin {
|
||||
@Override
|
||||
public @Nullable
|
||||
ChunkGenerator getDefaultWorldGenerator(@NotNull String worldName, String id) {
|
||||
if(id == null || id.trim().equals("")) { return null; }
|
||||
if(id == null || id.trim().isEmpty()) { return null; }
|
||||
return new BukkitChunkGeneratorWrapper(generatorMap.computeIfAbsent(worldName, name -> {
|
||||
ConfigPack pack = platform.getConfigRegistry().getByID(id).orElseThrow(
|
||||
() -> new IllegalArgumentException("No such config pack \"" + id + "\""));
|
||||
|
||||
@@ -54,9 +54,6 @@ public interface Initializer {
|
||||
private static Initializer constructInitializer() {
|
||||
try {
|
||||
String packageVersion = NMS;
|
||||
if(NMS.equals("v1_21_3")) {
|
||||
packageVersion = "v1_21"; // TODO: Refactor nms package to v1_21_3
|
||||
}
|
||||
|
||||
Class<?> initializerClass = Class.forName(TERRA_PACKAGE + "." + packageVersion + ".NMSInitializer");
|
||||
try {
|
||||
|
||||
+12
-8
@@ -1,11 +1,12 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
|
||||
import com.dfsek.terra.bukkit.nms.v1_21_3.config.VanillaBiomeProperties;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Holder.Reference;
|
||||
import net.minecraft.core.MappedRegistry;
|
||||
import net.minecraft.core.RegistrationInfo;
|
||||
import net.minecraft.core.WritableRegistry;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
@@ -32,9 +33,9 @@ public class AwfulBukkitHacks {
|
||||
public static void registerBiomes(ConfigRegistry configRegistry) {
|
||||
try {
|
||||
LOGGER.info("Hacking biome registry...");
|
||||
WritableRegistry<Biome> biomeRegistry = (WritableRegistry<Biome>) RegistryFetcher.biomeRegistry();
|
||||
MappedRegistry<Biome> biomeRegistry = (MappedRegistry<Biome>) RegistryFetcher.biomeRegistry();
|
||||
|
||||
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, false);
|
||||
Reflection.MAPPED_REGISTRY.setFrozen(biomeRegistry, false);
|
||||
|
||||
configRegistry.forEach(pack -> pack.getRegistry(com.dfsek.terra.api.world.biome.Biome.class).forEach((key, biome) -> {
|
||||
try {
|
||||
@@ -42,7 +43,10 @@ public class AwfulBukkitHacks {
|
||||
NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey();
|
||||
ResourceLocation vanillaMinecraftKey = ResourceLocation.fromNamespaceAndPath(vanillaBukkitKey.getNamespace(),
|
||||
vanillaBukkitKey.getKey());
|
||||
Biome platform = NMSBiomeInjector.createBiome(biome, biomeRegistry.get(vanillaMinecraftKey).orElseThrow().value());
|
||||
|
||||
VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
|
||||
|
||||
Biome platform = NMSBiomeInjector.createBiome(biomeRegistry.get(vanillaMinecraftKey).orElseThrow().value(), vanillaBiomeProperties);
|
||||
|
||||
ResourceKey<Biome> delegateKey = ResourceKey.create(
|
||||
Registries.BIOME,
|
||||
@@ -62,8 +66,6 @@ public class AwfulBukkitHacks {
|
||||
}
|
||||
}));
|
||||
|
||||
Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, true); // freeze registry again :)
|
||||
|
||||
LOGGER.info("Doing tag garbage....");
|
||||
Map<TagKey<Biome>, List<Holder<Biome>>> collect = biomeRegistry
|
||||
.getTags() // streamKeysAndEntries
|
||||
@@ -90,9 +92,11 @@ public class AwfulBukkitHacks {
|
||||
() -> LOGGER.error("No such biome: {}", tb))),
|
||||
() -> LOGGER.error("No vanilla biome: {}", vb)));
|
||||
|
||||
((MappedRegistry<Biome>) biomeRegistry).bindAllTagsToEmpty();
|
||||
biomeRegistry.bindAllTagsToEmpty();
|
||||
ImmutableMap.copyOf(collect).forEach(biomeRegistry::bindTag);
|
||||
|
||||
Reflection.MAPPED_REGISTRY.setFrozen(biomeRegistry, true); // freeze registry again :)
|
||||
|
||||
} catch(SecurityException | IllegalArgumentException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
|
||||
import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent;
|
||||
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.bukkit.BukkitAddon;
|
||||
import com.dfsek.terra.bukkit.PlatformImpl;
|
||||
import com.dfsek.terra.bukkit.nms.v1_21.config.VanillaBiomeProperties;
|
||||
import com.dfsek.terra.bukkit.nms.v1_21_3.config.VanillaBiomeProperties;
|
||||
|
||||
|
||||
public class NMSAddon extends BukkitAddon {
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
+3
-5
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
@@ -11,7 +11,7 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.bukkit.nms.v1_21.config.VanillaBiomeProperties;
|
||||
import com.dfsek.terra.bukkit.nms.v1_21_3.config.VanillaBiomeProperties;
|
||||
|
||||
|
||||
public class NMSBiomeInjector {
|
||||
@@ -22,14 +22,12 @@ public class NMSBiomeInjector {
|
||||
.flatMap(registry::get);
|
||||
}
|
||||
|
||||
public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla)
|
||||
public static Biome createBiome(Biome vanilla, VanillaBiomeProperties vanillaBiomeProperties)
|
||||
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
|
||||
Biome.BiomeBuilder builder = new Biome.BiomeBuilder();
|
||||
|
||||
BiomeSpecialEffects.Builder effects = new BiomeSpecialEffects.Builder();
|
||||
|
||||
VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
|
||||
|
||||
effects.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor()))
|
||||
.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
|
||||
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.core.Holder;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.core.BlockPos;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
|
||||
import com.dfsek.terra.bukkit.BukkitAddon;
|
||||
|
||||
+1
-2
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@@ -17,7 +17,6 @@ import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.util.reflection.ReflectionUtil;
|
||||
import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper;
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
|
||||
import net.minecraft.world.level.LevelHeightAccessor;
|
||||
|
||||
+6
-6
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Holder.Reference;
|
||||
@@ -27,7 +27,7 @@ public class Reflection {
|
||||
|
||||
|
||||
public static final ChunkMapProxy CHUNKMAP;
|
||||
public static final HolderSetProxy HOLDER_SET;
|
||||
public static final HolderSetNamedProxy HOLDER_SET;
|
||||
public static final BiomeProxy BIOME;
|
||||
|
||||
static {
|
||||
@@ -39,7 +39,7 @@ public class Reflection {
|
||||
STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class);
|
||||
REFERENCE = reflectionProxyFactory.reflectionProxy(ReferenceProxy.class);
|
||||
CHUNKMAP = reflectionProxyFactory.reflectionProxy(ChunkMapProxy.class);
|
||||
HOLDER_SET = reflectionProxyFactory.reflectionProxy(HolderSetProxy.class);
|
||||
HOLDER_SET = reflectionProxyFactory.reflectionProxy(HolderSetNamedProxy.class);
|
||||
BIOME = reflectionProxyFactory.reflectionProxy(BiomeProxy.class);
|
||||
}
|
||||
|
||||
@@ -73,10 +73,10 @@ public class Reflection {
|
||||
void setWorldGenContext(ChunkMap instance, WorldGenContext worldGenContext);
|
||||
}
|
||||
|
||||
@Proxies(HolderSet.class)
|
||||
public interface HolderSetProxy {
|
||||
@Proxies(HolderSet.Named.class)
|
||||
public interface HolderSetNamedProxy {
|
||||
@MethodName("contents")
|
||||
<T> List<Holder<T>> invokeContents(HolderSet<T> instance);
|
||||
<T> List<Holder<T>> invokeContents(HolderSet.Named<T> instance);
|
||||
}
|
||||
|
||||
@Proxies(Biome.class)
|
||||
+4
-10
@@ -1,24 +1,18 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
|
||||
|
||||
public class RegistryFetcher {
|
||||
private static <T> Registry<T> getRegistry(ResourceKey<Registry<T>> key) {
|
||||
CraftServer craftserver = (CraftServer) Bukkit.getServer();
|
||||
DedicatedServer dedicatedserver = craftserver.getServer();
|
||||
return dedicatedserver
|
||||
return MinecraftServer.getServer()
|
||||
.registryAccess()
|
||||
.get(key)
|
||||
.orElseThrow()
|
||||
.value();
|
||||
.lookupOrThrow(key);
|
||||
}
|
||||
|
||||
public static Registry<Biome> biomeRegistry() {
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.world.level.biome.AmbientAdditionsSettings;
|
||||
|
||||
|
||||
public class BiomeAdditionsSoundTemplate implements ObjectTemplate<AmbientAdditionsSettings> {
|
||||
@Value("sound")
|
||||
@Default
|
||||
private SoundEvent sound = null;
|
||||
|
||||
@Value("sound-chance")
|
||||
@Default
|
||||
private Double soundChance = null;
|
||||
|
||||
@Override
|
||||
public AmbientAdditionsSettings get() {
|
||||
if(sound == null || soundChance == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new AmbientAdditionsSettings(BuiltInRegistries.SOUND_EVENT.wrapAsHolder(sound), soundChance);
|
||||
}
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.world.level.biome.AmbientMoodSettings;
|
||||
|
||||
|
||||
public class BiomeMoodSoundTemplate implements ObjectTemplate<AmbientMoodSettings> {
|
||||
@Value("sound")
|
||||
@Default
|
||||
private SoundEvent sound = null;
|
||||
|
||||
@Value("cultivation-ticks")
|
||||
@Default
|
||||
private Integer soundCultivationTicks = null;
|
||||
|
||||
@Value("spawn-range")
|
||||
@Default
|
||||
private Integer soundSpawnRange = null;
|
||||
|
||||
@Value("extra-distance")
|
||||
@Default
|
||||
private Double soundExtraDistance = null;
|
||||
|
||||
@Override
|
||||
public AmbientMoodSettings get() {
|
||||
if(sound == null || soundCultivationTicks == null || soundSpawnRange == null || soundExtraDistance == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new AmbientMoodSettings(BuiltInRegistries.SOUND_EVENT.wrapAsHolder(sound), soundCultivationTicks, soundSpawnRange, soundExtraDistance);
|
||||
}
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import net.minecraft.commands.arguments.ParticleArgument;
|
||||
import net.minecraft.core.HolderLookup.Provider;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.world.level.biome.AmbientParticleSettings;
|
||||
|
||||
|
||||
public class BiomeParticleConfigTemplate implements ObjectTemplate<AmbientParticleSettings> {
|
||||
@Value("particle")
|
||||
@Default
|
||||
private String particle = null;
|
||||
|
||||
@Value("probability")
|
||||
@Default
|
||||
private Integer probability = null;
|
||||
|
||||
@Override
|
||||
public AmbientParticleSettings get() {
|
||||
if(particle == null || probability == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return new AmbientParticleSettings(ParticleArgument.readParticle(new StringReader(particle),
|
||||
(Provider) BuiltInRegistries.PARTICLE_TYPE.asHolderIdMap()), probability);
|
||||
} catch(CommandSyntaxException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
|
||||
|
||||
public class EntityTypeTemplate implements ObjectTemplate<EntityType<?>> {
|
||||
@Value("id")
|
||||
@Default
|
||||
private ResourceLocation id = null;
|
||||
|
||||
@Override
|
||||
public EntityType<?> get() {
|
||||
return BuiltInRegistries.ENTITY_TYPE.get(id).orElseThrow().value();
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.sounds.Music;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
|
||||
|
||||
public class MusicSoundTemplate implements ObjectTemplate<Music> {
|
||||
@Value("sound")
|
||||
@Default
|
||||
private SoundEvent sound = null;
|
||||
|
||||
@Value("min-delay")
|
||||
@Default
|
||||
private Integer minDelay = null;
|
||||
|
||||
@Value("max-delay")
|
||||
@Default
|
||||
private Integer maxDelay = null;
|
||||
|
||||
@Value("replace-current-music")
|
||||
@Default
|
||||
private Boolean replaceCurrentMusic = null;
|
||||
|
||||
@Override
|
||||
public Music get() {
|
||||
if(sound == null || minDelay == null || maxDelay == null || replaceCurrentMusic == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new Music(BuiltInRegistries.SOUND_EVENT.wrapAsHolder(sound), minDelay, maxDelay, replaceCurrentMusic);
|
||||
}
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
|
||||
|
||||
public class SoundEventTemplate implements ObjectTemplate<SoundEvent> {
|
||||
@Value("id")
|
||||
@Default
|
||||
private ResourceLocation id = null;
|
||||
|
||||
@Value("distance-to-travel")
|
||||
@Default
|
||||
private Float distanceToTravel = null;
|
||||
|
||||
@Override
|
||||
public SoundEvent get() {
|
||||
if(id == null) {
|
||||
return null;
|
||||
} else if(distanceToTravel == null) {
|
||||
return SoundEvent.createVariableRangeEvent(id);
|
||||
} else {
|
||||
return SoundEvent.createFixedRangeEvent(id, distanceToTravel);
|
||||
}
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
|
||||
|
||||
public class SpawnCostConfig implements ObjectTemplate<SpawnCostConfig> {
|
||||
@Value("type")
|
||||
@Default
|
||||
private EntityType<?> type = null;
|
||||
|
||||
@Value("mass")
|
||||
@Default
|
||||
private Double mass = null;
|
||||
|
||||
@Value("gravity")
|
||||
@Default
|
||||
private Double gravity = null;
|
||||
|
||||
public EntityType<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Double getMass() {
|
||||
return mass;
|
||||
}
|
||||
|
||||
public Double getGravity() {
|
||||
return gravity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpawnCostConfig get() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData;
|
||||
|
||||
|
||||
public class SpawnEntryTemplate implements ObjectTemplate<SpawnerData> {
|
||||
@Value("type")
|
||||
@Default
|
||||
private EntityType<?> type = null;
|
||||
|
||||
@Value("weight")
|
||||
@Default
|
||||
private Integer weight = null;
|
||||
|
||||
@Value("min-group-size")
|
||||
@Default
|
||||
private Integer minGroupSize = null;
|
||||
|
||||
@Value("max-group-size")
|
||||
@Default
|
||||
private Integer maxGroupSize = null;
|
||||
|
||||
@Override
|
||||
public SpawnerData get() {
|
||||
return new SpawnerData(type, weight, minGroupSize, maxGroupSize);
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import java.util.List;
|
||||
import net.minecraft.world.entity.MobCategory;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
public class SpawnSettingsTemplate implements ObjectTemplate<MobSpawnSettings> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SpawnTypeConfig.class);
|
||||
private static boolean used = false;
|
||||
|
||||
@Value("spawns")
|
||||
@Default
|
||||
private List<SpawnTypeConfig> spawns = null;
|
||||
|
||||
@Value("costs")
|
||||
@Default
|
||||
private List<SpawnCostConfig> costs = null;
|
||||
|
||||
@Value("probability")
|
||||
@Default
|
||||
private Float probability = null;
|
||||
|
||||
@Override
|
||||
public MobSpawnSettings get() {
|
||||
MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder();
|
||||
for(SpawnTypeConfig spawn : spawns) {
|
||||
MobCategory group = spawn.getGroup();
|
||||
for(SpawnerData entry : spawn.getEntries()) {
|
||||
builder.addSpawn(group, entry);
|
||||
}
|
||||
}
|
||||
for(SpawnCostConfig cost : costs) {
|
||||
builder.addMobCharge(cost.getType(), cost.getMass(), cost.getGravity());
|
||||
}
|
||||
if(probability != null) {
|
||||
builder.creatureGenerationProbability(probability);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import java.util.List;
|
||||
import net.minecraft.world.entity.MobCategory;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData;
|
||||
|
||||
|
||||
public class SpawnTypeConfig implements ObjectTemplate<SpawnTypeConfig> {
|
||||
@Value("group")
|
||||
@Default
|
||||
private MobCategory group = null;
|
||||
|
||||
@Value("entries")
|
||||
@Default
|
||||
private List<SpawnerData> entries = null;
|
||||
|
||||
public MobCategory getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public List<SpawnerData> getEntries() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpawnTypeConfig get() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21.config;
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.ConfigTemplate;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.dfsek.terra.bukkit.nms.v1_21_3.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.npc.VillagerType;
|
||||
|
||||
|
||||
public class VillagerTypeTemplate implements ObjectTemplate<VillagerType> {
|
||||
@Value("id")
|
||||
@Default
|
||||
private ResourceLocation id = null;
|
||||
|
||||
@Override
|
||||
public VillagerType get() {
|
||||
return BuiltInRegistries.VILLAGER_TYPE.get(id).orElseThrow().value();
|
||||
}
|
||||
}
|
||||
@@ -60,13 +60,13 @@ public final class BiomeUtil {
|
||||
} else {
|
||||
VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
|
||||
|
||||
net.minecraft.world.biome.Biome minecraftBiome = MinecraftUtil.createBiome(biome,
|
||||
net.minecraft.world.biome.Biome minecraftBiome = com.dfsek.terra.mod.util.BiomeUtil.createBiome(biome,
|
||||
ForgeRegistries.BIOMES.getDelegateOrThrow(
|
||||
vanilla.getKey().orElseThrow())
|
||||
.value(),
|
||||
vanillaBiomeProperties);
|
||||
|
||||
Identifier identifier = new Identifier("terra", MinecraftUtil.createBiomeID(pack, id));
|
||||
Identifier identifier = new Identifier("terra", com.dfsek.terra.mod.util.BiomeUtil.createBiomeID(pack, id));
|
||||
|
||||
if(ForgeRegistries.BIOMES.containsKey(identifier)) {
|
||||
((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(ForgeRegistries.BIOMES.getHolder(identifier)
|
||||
@@ -83,7 +83,7 @@ public final class BiomeUtil {
|
||||
Objects.requireNonNullElse(vanillaBiomeProperties.getVillagerType(),
|
||||
villagerMap.getOrDefault(vanilla.getKey().orElseThrow(), VillagerType.PLAINS)));
|
||||
|
||||
MinecraftUtil.TERRA_BIOME_MAP.computeIfAbsent(vanilla.getKey().orElseThrow().getValue(), i -> new ArrayList<>()).add(
|
||||
com.dfsek.terra.mod.util.BiomeUtil.TERRA_BIOME_MAP.computeIfAbsent(vanilla.getKey().orElseThrow().getValue(), i -> new ArrayList<>()).add(
|
||||
identifier);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
|
||||
|
||||
@Value("climate.precipitation")
|
||||
@Default
|
||||
private Boolean precipitation = true;
|
||||
private Boolean precipitation = null;
|
||||
|
||||
@Value("climate.temperature")
|
||||
@Default
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ import com.dfsek.terra.mod.util.MinecraftAdapter;
|
||||
@Implements(@Interface(iface = com.dfsek.terra.api.entity.Entity.class, prefix = "terra$"))
|
||||
public abstract class EntityMixin {
|
||||
@Shadow
|
||||
public net.minecraft.world.World world;
|
||||
private net.minecraft.world.World world;
|
||||
|
||||
@Shadow
|
||||
private BlockPos blockPos;
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.dfsek.terra.mod.mixin.invoke;
|
||||
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
|
||||
@Mixin(Biome.class)
|
||||
public interface BiomeInvoker {
|
||||
@Invoker("getDefaultGrassColor")
|
||||
int invokeGetDefaultGrassColor();
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.dfsek.terra.mod.util;
|
||||
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.Biome.Builder;
|
||||
import net.minecraft.world.biome.BiomeEffects;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.mod.config.VanillaBiomeProperties;
|
||||
import com.dfsek.terra.mod.mixin.access.BiomeAccessor;
|
||||
import com.dfsek.terra.mod.mixin.invoke.BiomeInvoker;
|
||||
|
||||
|
||||
public class BiomeUtil {
|
||||
public static final Map<Identifier, List<Identifier>>
|
||||
TERRA_BIOME_MAP = new HashMap<>();
|
||||
|
||||
public static Biome createBiome(Biome vanilla, VanillaBiomeProperties vanillaBiomeProperties) {
|
||||
BiomeEffects.Builder effects = new BiomeEffects.Builder();
|
||||
|
||||
net.minecraft.world.biome.Biome.Builder builder = new Builder();
|
||||
|
||||
effects.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
|
||||
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
|
||||
.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor()))
|
||||
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()))
|
||||
.grassColorModifier(
|
||||
Objects.requireNonNullElse(vanillaBiomeProperties.getGrassColorModifier(), vanilla.getEffects().getGrassColorModifier()))
|
||||
.grassColor(Objects.requireNonNullElse(vanillaBiomeProperties.getGrassColor(),
|
||||
vanilla.getEffects().getGrassColor().orElseGet(() -> ((BiomeInvoker) ((Object) vanilla)).invokeGetDefaultGrassColor())))
|
||||
.foliageColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFoliageColor(), vanilla.getFoliageColor()));
|
||||
|
||||
if(vanillaBiomeProperties.getParticleConfig() == null) {
|
||||
vanilla.getEffects().getParticleConfig().ifPresent(effects::particleConfig);
|
||||
} else {
|
||||
effects.particleConfig(vanillaBiomeProperties.getParticleConfig());
|
||||
}
|
||||
|
||||
if(vanillaBiomeProperties.getLoopSound() == null) {
|
||||
vanilla.getEffects().getLoopSound().ifPresent(effects::loopSound);
|
||||
} else {
|
||||
effects.loopSound(Registries.SOUND_EVENT.getEntry(vanillaBiomeProperties.getLoopSound()));
|
||||
}
|
||||
|
||||
if(vanillaBiomeProperties.getMoodSound() == null) {
|
||||
vanilla.getEffects().getMoodSound().ifPresent(effects::moodSound);
|
||||
} else {
|
||||
effects.moodSound(vanillaBiomeProperties.getMoodSound());
|
||||
}
|
||||
|
||||
if(vanillaBiomeProperties.getAdditionsSound() == null) {
|
||||
vanilla.getEffects().getAdditionsSound().ifPresent(effects::additionsSound);
|
||||
} else {
|
||||
effects.additionsSound(vanillaBiomeProperties.getAdditionsSound());
|
||||
}
|
||||
|
||||
if(vanillaBiomeProperties.getMusic() == null) {
|
||||
vanilla.getEffects().getMusic().ifPresent(effects::music);
|
||||
} else {
|
||||
effects.music(vanillaBiomeProperties.getMusic());
|
||||
}
|
||||
|
||||
builder.precipitation(Objects.requireNonNullElse(vanillaBiomeProperties.getPrecipitation(), vanilla.hasPrecipitation()));
|
||||
|
||||
builder.temperature(Objects.requireNonNullElse(vanillaBiomeProperties.getTemperature(), vanilla.getTemperature()));
|
||||
|
||||
builder.downfall(Objects.requireNonNullElse(vanillaBiomeProperties.getDownfall(),
|
||||
((BiomeAccessor) ((Object) vanilla)).getWeather().downfall()));
|
||||
|
||||
builder.temperatureModifier(Objects.requireNonNullElse(vanillaBiomeProperties.getTemperatureModifier(),
|
||||
((BiomeAccessor) ((Object) vanilla)).getWeather().temperatureModifier()));
|
||||
|
||||
builder.spawnSettings(Objects.requireNonNullElse(vanillaBiomeProperties.getSpawnSettings(), vanilla.getSpawnSettings()));
|
||||
|
||||
return builder
|
||||
.effects(effects.build())
|
||||
.generationSettings(vanilla.getGenerationSettings())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) {
|
||||
return pack.getID()
|
||||
.toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
public static Map<Identifier, List<Identifier>> getTerraBiomeMap() {
|
||||
return Map.copyOf(TERRA_BIOME_MAP);
|
||||
}
|
||||
}
|
||||
@@ -38,8 +38,6 @@ import com.dfsek.terra.mod.mixin_ifaces.FloraFeatureHolder;
|
||||
|
||||
public final class MinecraftUtil {
|
||||
public static final Logger logger = LoggerFactory.getLogger(MinecraftUtil.class);
|
||||
public static final Map<Identifier, List<Identifier>>
|
||||
TERRA_BIOME_MAP = new HashMap<>();
|
||||
|
||||
private MinecraftUtil() {
|
||||
|
||||
@@ -64,7 +62,7 @@ public final class MinecraftUtil {
|
||||
|
||||
public static void registerFlora(Registry<net.minecraft.world.biome.Biome> biomes) {
|
||||
logger.info("Injecting flora into Terra biomes...");
|
||||
TERRA_BIOME_MAP
|
||||
BiomeUtil.TERRA_BIOME_MAP
|
||||
.forEach((vb, terraBiomes) ->
|
||||
biomes.getOptionalValue(vb)
|
||||
.ifPresentOrElse(vanilla -> terraBiomes
|
||||
@@ -87,92 +85,7 @@ public final class MinecraftUtil {
|
||||
|
||||
}
|
||||
|
||||
public static Map<Identifier, List<Identifier>> getTerraBiomeMap() {
|
||||
return Map.copyOf(TERRA_BIOME_MAP);
|
||||
}
|
||||
|
||||
public static RegistryKey<Biome> registerKey(Identifier identifier) {
|
||||
return RegistryKey.of(RegistryKeys.BIOME, identifier);
|
||||
}
|
||||
|
||||
public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla,
|
||||
VanillaBiomeProperties vanillaBiomeProperties) {
|
||||
GenerationSettings.Builder generationSettings = new GenerationSettings.Builder();
|
||||
|
||||
BiomeEffects.Builder effects = new BiomeEffects.Builder();
|
||||
|
||||
net.minecraft.world.biome.Biome.Builder builder = new Builder();
|
||||
|
||||
effects.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))
|
||||
.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))
|
||||
.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor()))
|
||||
.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()))
|
||||
.grassColorModifier(Objects.requireNonNullElse(vanillaBiomeProperties.getGrassColorModifier(), vanilla.getEffects().getGrassColorModifier()))
|
||||
.grassColor(Objects.requireNonNullElse(vanillaBiomeProperties.getGrassColor(), vanilla.getEffects().getGrassColor().orElseGet(vanilla.getDefaultGrassColor())))
|
||||
.foliageColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFoliageColor(), vanilla.getFoliageColor()));
|
||||
|
||||
if(vanillaBiomeProperties.getFoliageColor() == null) {
|
||||
vanilla.getEffects().getFoliageColor().ifPresent(effects::foliageColor);
|
||||
} else {
|
||||
effects.foliageColor(vanillaBiomeProperties.getFoliageColor());
|
||||
}
|
||||
|
||||
if(vanillaBiomeProperties.getGrassColor() == null) {
|
||||
vanilla.getEffects().getGrassColor().ifPresent(effects::grassColor);
|
||||
} else {
|
||||
effects.grassColor(vanillaBiomeProperties.getGrassColor());
|
||||
}
|
||||
|
||||
if(vanillaBiomeProperties.getParticleConfig() == null) {
|
||||
vanilla.getEffects().getParticleConfig().ifPresent(effects::particleConfig);
|
||||
} else {
|
||||
effects.particleConfig(vanillaBiomeProperties.getParticleConfig());
|
||||
}
|
||||
|
||||
if(vanillaBiomeProperties.getLoopSound() == null) {
|
||||
vanilla.getEffects().getLoopSound().ifPresent(effects::loopSound);
|
||||
} else {
|
||||
effects.loopSound(Registries.SOUND_EVENT.getEntry(vanillaBiomeProperties.getLoopSound()));
|
||||
}
|
||||
|
||||
if(vanillaBiomeProperties.getMoodSound() == null) {
|
||||
vanilla.getEffects().getMoodSound().ifPresent(effects::moodSound);
|
||||
} else {
|
||||
effects.moodSound(vanillaBiomeProperties.getMoodSound());
|
||||
}
|
||||
|
||||
if(vanillaBiomeProperties.getAdditionsSound() == null) {
|
||||
vanilla.getEffects().getAdditionsSound().ifPresent(effects::additionsSound);
|
||||
} else {
|
||||
effects.additionsSound(vanillaBiomeProperties.getAdditionsSound());
|
||||
}
|
||||
|
||||
if(vanillaBiomeProperties.getMusic() == null) {
|
||||
vanilla.getEffects().getMusic().ifPresent(effects::music);
|
||||
} else {
|
||||
effects.music(vanillaBiomeProperties.getMusic());
|
||||
}
|
||||
|
||||
builder.precipitation(Objects.requireNonNullElse(vanillaBiomeProperties.getPrecipitation(), vanilla.hasPrecipitation()));
|
||||
|
||||
builder.temperature(Objects.requireNonNullElse(vanillaBiomeProperties.getTemperature(), vanilla.getTemperature()));
|
||||
|
||||
builder.downfall(Objects.requireNonNullElse(vanillaBiomeProperties.getDownfall(),
|
||||
((BiomeAccessor) ((Object) vanilla)).getWeather().downfall()));
|
||||
|
||||
builder.temperatureModifier(Objects.requireNonNullElse(vanillaBiomeProperties.getTemperatureModifier(),
|
||||
((BiomeAccessor) ((Object) vanilla)).getWeather().temperatureModifier()));
|
||||
|
||||
builder.spawnSettings(Objects.requireNonNullElse(vanillaBiomeProperties.getSpawnSettings(), vanilla.getSpawnSettings()));
|
||||
|
||||
return builder
|
||||
.effects(effects.build())
|
||||
.generationSettings(generationSettings.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) {
|
||||
return pack.getID()
|
||||
.toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public final class TagUtil {
|
||||
logger.info("Doing biome tag garbage....");
|
||||
Map<TagKey<Biome>, List<RegistryEntry<Biome>>> collect = tagsToMutableMap(registry);
|
||||
|
||||
MinecraftUtil
|
||||
BiomeUtil
|
||||
.getTerraBiomeMap()
|
||||
.forEach((vb, terraBiomes) ->
|
||||
MinecraftUtil
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"implementations.terra.inventory.meta.ItemStackMetaMixin",
|
||||
"implementations.terra.world.ChunkRegionMixin",
|
||||
"implementations.terra.world.ServerWorldMixin",
|
||||
"invoke.BiomeInvoker",
|
||||
"invoke.FluidBlockInvoker",
|
||||
"lifecycle.DataPackContentsMixin"
|
||||
],
|
||||
|
||||
+2
-2
@@ -26,7 +26,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import com.dfsek.terra.addon.EphemeralAddon;
|
||||
import com.dfsek.terra.api.addon.BaseAddon;
|
||||
import com.dfsek.terra.lifecycle.util.BiomeUtil;
|
||||
import com.dfsek.terra.lifecycle.util.LifecycleBiomeUtil;
|
||||
import com.dfsek.terra.mod.CommonPlatform;
|
||||
import com.dfsek.terra.mod.ModPlatform;
|
||||
import com.dfsek.terra.mod.generation.MinecraftChunkGeneratorWrapper;
|
||||
@@ -84,7 +84,7 @@ public abstract class LifecyclePlatform extends ModPlatform {
|
||||
|
||||
|
||||
if(server != null) {
|
||||
BiomeUtil.registerBiomes(server.getRegistryManager().getOrThrow(RegistryKeys.BIOME));
|
||||
LifecycleBiomeUtil.registerBiomes(server.getRegistryManager().getOrThrow(RegistryKeys.BIOME));
|
||||
server.reloadResources(server.getDataPackManager().getEnabledIds()).exceptionally(throwable -> {
|
||||
LOGGER.warn("Failed to execute reload", throwable);
|
||||
return null;
|
||||
|
||||
+8
-6
@@ -1,5 +1,7 @@
|
||||
package com.dfsek.terra.lifecycle.util;
|
||||
|
||||
import com.dfsek.terra.mod.util.BiomeUtil;
|
||||
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
@@ -22,10 +24,10 @@ import com.dfsek.terra.mod.mixin.access.VillagerTypeAccessor;
|
||||
import com.dfsek.terra.mod.util.MinecraftUtil;
|
||||
|
||||
|
||||
public final class BiomeUtil {
|
||||
private static final Logger logger = LoggerFactory.getLogger(BiomeUtil.class);
|
||||
public final class LifecycleBiomeUtil {
|
||||
private static final Logger logger = LoggerFactory.getLogger(LifecycleBiomeUtil.class);
|
||||
|
||||
private BiomeUtil() {
|
||||
private LifecycleBiomeUtil() {
|
||||
|
||||
}
|
||||
|
||||
@@ -55,10 +57,10 @@ public final class BiomeUtil {
|
||||
} else {
|
||||
VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
|
||||
|
||||
net.minecraft.world.biome.Biome minecraftBiome = MinecraftUtil.createBiome(biome, Objects.requireNonNull(registry.get(vanilla)),
|
||||
net.minecraft.world.biome.Biome minecraftBiome = BiomeUtil.createBiome(Objects.requireNonNull(registry.get(vanilla)),
|
||||
vanillaBiomeProperties);
|
||||
|
||||
Identifier identifier = Identifier.of("terra", MinecraftUtil.createBiomeID(pack, id));
|
||||
Identifier identifier = Identifier.of("terra", BiomeUtil.createBiomeID(pack, id));
|
||||
|
||||
if(registry.containsId(identifier)) {
|
||||
((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(MinecraftUtil.getEntry(registry, identifier)
|
||||
@@ -76,7 +78,7 @@ public final class BiomeUtil {
|
||||
Objects.requireNonNullElse(vanillaBiomeProperties.getVillagerType(),
|
||||
villagerMap.getOrDefault(vanilla, VillagerType.PLAINS)));
|
||||
|
||||
MinecraftUtil.TERRA_BIOME_MAP.computeIfAbsent(vanilla.getValue(), i -> new ArrayList<>()).add(identifier);
|
||||
BiomeUtil.TERRA_BIOME_MAP.computeIfAbsent(vanilla.getValue(), i -> new ArrayList<>()).add(identifier);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ public final class LifecycleUtil {
|
||||
|
||||
public static void initialize(MutableRegistry<Biome> biomeMutableRegistry, MutableRegistry<WorldPreset> worldPresetMutableRegistry) {
|
||||
CommonPlatform.get().getEventManager().callEvent(new PlatformInitializationEvent());
|
||||
BiomeUtil.registerBiomes(biomeMutableRegistry);
|
||||
LifecycleBiomeUtil.registerBiomes(biomeMutableRegistry);
|
||||
CommonPlatform.get().registerWorldTypes(
|
||||
(id, preset) -> Registry.register(worldPresetMutableRegistry, RegistryKey.of(RegistryKeys.WORLD_PRESET, id), preset));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user