mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-05-20 16:50:28 +00:00
Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| be3e50411e | |||
| c87d0446d3 | |||
| e08a105d27 | |||
| 03cecfb0fd | |||
| 502b84722e | |||
| 1abaace21b | |||
| 951270c147 | |||
| 29cc8e9ffb | |||
| c5bd7e7646 | |||
| 4cdcdc0fee | |||
| 9d4c4e35e7 | |||
| 3876cbc88e | |||
| 800b8bc3a7 | |||
| 73ca08cb3d | |||
| 664995e6eb | |||
| 130d9648ee | |||
| 869d95f5c8 | |||
| f396e0e5eb | |||
| 942a8c9c8b | |||
| 414dcdae3e | |||
| 1195a6676f | |||
| 5501f53056 | |||
| 41d6e1c648 | |||
| 5ac7257517 | |||
| 9f4f9702a6 | |||
| 01d169256e | |||
| 7a703ad091 | |||
| ce9273c7e8 | |||
| 653a414ac1 | |||
| 2080db21ca | |||
| 8a933609ee | |||
| ba4a50e234 | |||
| f8e8ce8bc2 | |||
| 0013d4e682 | |||
| 9a97f1178d | |||
| e6a551d84d | |||
| 92921430d8 | |||
| 20c905aae4 | |||
| ec0730ef73 | |||
| e4576b3405 | |||
| c5800970a8 | |||
| 8f88b1c156 | |||
| 1360994a67 | |||
| e00b28d27e | |||
| c5ff5c101d | |||
| b1a1001c49 | |||
| 77d5162e73 | |||
| 2e8cd54ac2 |
+2
-2
@@ -1,6 +1,6 @@
|
||||
import com.dfsek.terra.getGitHash
|
||||
|
||||
val versionObj = Version("5", "1", "0", true)
|
||||
val versionObj = Version("5", "1", "3", true)
|
||||
|
||||
allprojects {
|
||||
version = versionObj
|
||||
@@ -18,4 +18,4 @@ class Version(val major: String, val minor: String, val revision: String, val pr
|
||||
else //Only use git hash if it's a prerelease.
|
||||
"$major.$minor.$revision-BETA+${getGitHash()}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ fun Project.configureCommon() {
|
||||
}
|
||||
|
||||
fun Project.getGitHash(): String {
|
||||
val stdout = java.io.ByteArrayOutputStream()
|
||||
val stdout = ByteArrayOutputStream()
|
||||
exec {
|
||||
commandLine = mutableListOf("git", "rev-parse", "--short", "HEAD")
|
||||
standardOutput = stdout
|
||||
|
||||
@@ -18,9 +18,7 @@ fun Project.configureDependencies() {
|
||||
|
||||
dependencies {
|
||||
"testImplementation"("org.junit.jupiter:junit-jupiter-api:5.7.0")
|
||||
"testImplementation"("org.yaml:snakeyaml:1.27")
|
||||
"testImplementation"("com.googlecode.json-simple:json-simple:1.1.1")
|
||||
"testRuntimeOnly"("org.junit.jupiter:junit-jupiter-engine:5.7.0")
|
||||
"testImplementation"("org.junit.jupiter:junit-jupiter-engine:5.7.0")
|
||||
"compileOnly"("org.jetbrains:annotations:20.1.0")
|
||||
}
|
||||
}
|
||||
@@ -14,13 +14,9 @@ fun Project.configureDistribution() {
|
||||
apply(plugin = "java-library")
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
|
||||
|
||||
// configurations.create("shaded")
|
||||
|
||||
configurations {
|
||||
val shaded = create("shaded")
|
||||
getByName("compile").extendsFrom(shaded)
|
||||
// shaded.extendsFrom(getByName("compile"))
|
||||
val shadedApi = create("shadedApi")
|
||||
shaded.extendsFrom(shadedApi)
|
||||
getByName("api").extendsFrom(shadedApi)
|
||||
@@ -29,11 +25,8 @@ fun Project.configureDistribution() {
|
||||
getByName("implementation").extendsFrom(shadedImplementation)
|
||||
}
|
||||
|
||||
// tasks.withType<JavaCompile> {
|
||||
// classpath +=
|
||||
// }
|
||||
|
||||
val downloadDefaultPacks = tasks.create("downloadDefaultPacks") {
|
||||
group = "terra"
|
||||
doFirst {
|
||||
file("${buildDir}/resources/main/packs/").deleteRecursively()
|
||||
|
||||
@@ -69,8 +62,14 @@ fun Project.configureDistribution() {
|
||||
archiveClassifier.set("shaded")
|
||||
setVersion(project.version)
|
||||
relocate("org.apache.commons", "com.dfsek.terra.lib.commons")
|
||||
relocate("parsii", "com.dfsek.terra.lib.parsii")
|
||||
relocate("net.jafama", "com.dfsek.terra.lib.jafama")
|
||||
relocate("org.objectweb.asm", "com.dfsek.terra.lib.asm")
|
||||
relocate("com.google.errorprone", "com.dfsek.terra.lib.google.errorprone")
|
||||
relocate("com.google.j2objc", "com.dfsek.terra.lib.google.j2objc")
|
||||
relocate("org.checkerframework", "com.dfsek.terra.lib.checkerframework")
|
||||
relocate("org.javax.annotation", "com.dfsek.terra.lib.javax.annotation")
|
||||
relocate("org.json", "com.dfsek.terra.lib.json")
|
||||
relocate("org.yaml", "com.dfsek.terra.lib.yaml")
|
||||
minimize()
|
||||
}
|
||||
convention.getPlugin<BasePluginConvention>().archivesBaseName = project.name
|
||||
|
||||
+214
-1
@@ -1,10 +1,25 @@
|
||||
import com.dfsek.terra.configureCommon
|
||||
import com.github.javaparser.StaticJavaParser
|
||||
import com.github.javaparser.ast.CompilationUnit
|
||||
import com.github.javaparser.ast.body.FieldDeclaration
|
||||
import com.github.javaparser.ast.expr.StringLiteralExpr
|
||||
import com.github.javaparser.ast.type.PrimitiveType
|
||||
import com.github.javaparser.ast.type.PrimitiveType.Primitive
|
||||
import com.github.javaparser.ast.type.Type
|
||||
import com.github.javaparser.ast.Node
|
||||
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
buildscript {
|
||||
dependencies {
|
||||
classpath("com.github.javaparser:javaparser-symbol-solver-core:3.20.2")
|
||||
}
|
||||
}
|
||||
|
||||
configureCommon()
|
||||
|
||||
group = "com.dfsek.terra.common"
|
||||
@@ -20,7 +35,8 @@ dependencies {
|
||||
"shadedApi"("org.ow2.asm:asm:9.0")
|
||||
"shadedApi"("commons-io:commons-io:2.6")
|
||||
|
||||
"compileOnly"("com.googlecode.json-simple:json-simple:1.1")
|
||||
"shadedApi"("com.googlecode.json-simple:json-simple:1.1.1")
|
||||
"shadedApi"("org.yaml:snakeyaml:1.27")
|
||||
|
||||
"compileOnly"("com.google.guava:guava:30.0-jre")
|
||||
|
||||
@@ -50,4 +66,201 @@ publishing {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
create("tectonic") {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
tasks.create<SourceTask>("tectonicDocs") {
|
||||
group = "terra"
|
||||
println("Scanning sources...")
|
||||
|
||||
|
||||
val docs = HashMap<String, String>()
|
||||
|
||||
val refactor = HashMap<String, String>()
|
||||
|
||||
val sources = HashMap<String, CompilationUnit>()
|
||||
|
||||
sourceSets.main.get().java.forEach {
|
||||
sources[it.name.substring(0, it.name.length - 5)] = StaticJavaParser.parse(it)
|
||||
}
|
||||
|
||||
sources.forEach { (name, unit) ->
|
||||
unit.getClassByName(name).ifPresent { declaration ->
|
||||
if (declaration.isAnnotationPresent("AutoDocAlias")) {
|
||||
refactor[name] = (declaration.getAnnotationByName("AutoDocAlias").get().childNodes[1] as StringLiteralExpr).asString()
|
||||
println("Refactoring $name to ${refactor[name]}.")
|
||||
} else if (declaration.isAnnotationPresent("AutoDocShadow")) {
|
||||
refactor[name] = (declaration.getAnnotationByName("AutoDocShadow").get().childNodes[1] as StringLiteralExpr).asString()
|
||||
println("Shadowing $name to ${refactor[name]}.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val children = HashMap<String, MutableList<ClassOrInterfaceDeclaration>>()
|
||||
sources.forEach { (name, unit) ->
|
||||
unit.getClassByName(name).ifPresent { declaration ->
|
||||
if(!declaration.isAnnotationPresent("AutoDocShadow")) {
|
||||
declaration.extendedTypes.forEach { classOrInterfaceType ->
|
||||
val inherit = classOrInterfaceType.name.asString()
|
||||
if (!children.containsKey(inherit)) children[inherit] = ArrayList()
|
||||
children[inherit]!!.add(declaration)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val linksAll = HashMap<String, Set<String>>()
|
||||
|
||||
sources.forEach { (name, unit) ->
|
||||
val doc = StringBuilder()
|
||||
doc.append("# ${generify(name, refactor)}\n")
|
||||
|
||||
var applicable = false
|
||||
|
||||
val links = HashSet<String>()
|
||||
|
||||
unit.getClassByName(name).ifPresent { declaration ->
|
||||
applicable = scanForParent(sources, declaration, "ConfigTemplate", "ValidatedConfigTemplate", "ObjectTemplate")
|
||||
|
||||
declaration.javadoc.ifPresent {
|
||||
doc.append("${sanitizeJavadoc(it.toText())} \n")
|
||||
}
|
||||
declaration.extendedTypes.forEach {
|
||||
if (!it.name.asString().equals("AbstractableTemplate")) {
|
||||
doc.append("Inherits from ${parseTypeLink(it, refactor, links, false)} \n \n")
|
||||
}
|
||||
}
|
||||
if (children.containsKey(name)) {
|
||||
doc.append("Children:\n")
|
||||
children[name]!!.forEach {
|
||||
doc.append("* ${parseTypeLink(it.name, refactor, links)}\n")
|
||||
}
|
||||
doc.append(" \n\n")
|
||||
}
|
||||
doc.append("\n")
|
||||
}
|
||||
|
||||
|
||||
unit.findAll(FieldDeclaration::class.java).filter { it.isAnnotationPresent("Value") }.forEach { fieldDeclaration ->
|
||||
doc.append("## ${(fieldDeclaration.getAnnotationByName("Value").get().childNodes[1] as StringLiteralExpr).asString()}\n")
|
||||
|
||||
if (fieldDeclaration.isAnnotationPresent("Default")) {
|
||||
doc.append("* Default value: ${fieldDeclaration.variables[0]} \n")
|
||||
}
|
||||
val type = fieldDeclaration.commonType
|
||||
doc.append("* Type: ${parseTypeLink(type, refactor, links)} \n")
|
||||
doc.append("\n")
|
||||
|
||||
fieldDeclaration.javadoc.ifPresent {
|
||||
doc.append(sanitizeJavadoc(it.toText()))
|
||||
}
|
||||
doc.append("\n\n")
|
||||
applicable = true
|
||||
}
|
||||
val s = doc.toString()
|
||||
if (s.isNotEmpty() && applicable) {
|
||||
docs[generify(name, refactor)] = s
|
||||
linksAll[name] = links
|
||||
}
|
||||
}
|
||||
println("Done. Generated ${docs.size} files")
|
||||
|
||||
val docsDir = File(buildDir, "tectonic")
|
||||
docsDir.mkdirs()
|
||||
val files = HashSet<String>()
|
||||
|
||||
docs.forEach {
|
||||
val save = File(docsDir, "${it.key}.md")
|
||||
files.add(it.key)
|
||||
if (save.exists()) save.delete()
|
||||
save.createNewFile()
|
||||
save.writeText(it.value)
|
||||
}
|
||||
|
||||
sourceSets["tectonic"].resources.forEach {
|
||||
files.add(it.name.substringBefore('.'))
|
||||
it.copyTo(File(docsDir, it.name), true)
|
||||
}
|
||||
|
||||
linksAll.forEach { (file, links) ->
|
||||
links.forEach {
|
||||
if(!files.contains(it)) println("WARNING: Dead link to \"$it\" in file \"$file\"")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun scanForParent(map: HashMap<String, CompilationUnit>, current: ClassOrInterfaceDeclaration, vararg parent: String): Boolean {
|
||||
for (type in current.implementedTypes) {
|
||||
if(parent.contains(type.childNodes[0].toString())) return true
|
||||
}
|
||||
for(type in current.extendedTypes) {
|
||||
val name = type.childNodes[0].toString()
|
||||
if(map.containsKey(name)) {
|
||||
val op = map[name]!!.getClassByName(name)
|
||||
if(op.isPresent && scanForParent(map, op.get(), *parent)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun parseTypeLink(type: Node, refactor: Map<String, String>, links: MutableSet<String>, generic: Boolean = true): String {
|
||||
val st = parseType(type, refactor)
|
||||
|
||||
if (type is Type && type.childNodes.size > 1 && generic) {
|
||||
val outer = generify(type.childNodes[0].toString(), refactor)
|
||||
|
||||
val builder = StringBuilder()
|
||||
builder.append("[$outer](./$outer)\\<")
|
||||
links.add(outer)
|
||||
|
||||
for (i in 1 until type.childNodes.size) {
|
||||
builder.append(parseTypeLink(type.childNodes[i], refactor, links, generic))
|
||||
if (i != type.childNodes.size - 1) builder.append(", ")
|
||||
}
|
||||
|
||||
builder.append("\\>")
|
||||
|
||||
return builder.toString()
|
||||
}
|
||||
links.add(st)
|
||||
return "[$st](./$st)"
|
||||
}
|
||||
|
||||
fun parseType(type: Node, refactor: Map<String, String>): String {
|
||||
if (type is PrimitiveType) {
|
||||
return when (type.type) {
|
||||
Primitive.BOOLEAN -> "Boolean"
|
||||
Primitive.BYTE -> "Byte"
|
||||
Primitive.DOUBLE -> "Double"
|
||||
Primitive.INT -> "Integer"
|
||||
Primitive.CHAR -> "Char"
|
||||
Primitive.FLOAT -> "Float"
|
||||
Primitive.SHORT -> "Short"
|
||||
Primitive.LONG -> "Long"
|
||||
else -> type.asString()
|
||||
}
|
||||
}
|
||||
if(type is Type && type.childNodes.size > 1) return generify(type.childNodes[0].toString(), refactor)
|
||||
return generify(type.toString(), refactor)
|
||||
}
|
||||
|
||||
fun generify(type: String, refactor: Map<String, String>): String {
|
||||
return when (type) {
|
||||
"HashMap", "LinkedHashMap" -> "Map"
|
||||
"ArrayList", "LinkedList", "GlueList" -> "List"
|
||||
"HashSet" -> "Set"
|
||||
else -> refactor.getOrDefault(type, type)
|
||||
}
|
||||
}
|
||||
|
||||
fun sanitizeJavadoc(doc: String): String {
|
||||
return doc
|
||||
.replace("<p>", "")
|
||||
}
|
||||
@@ -160,7 +160,6 @@ public class TerraCommandManager implements CommandManager {
|
||||
if(field.isAnnotationPresent(SwitchTarget.class)) {
|
||||
SwitchTarget switchTarget = field.getAnnotation(SwitchTarget.class);
|
||||
if(!holder.switches.containsValue(switchTarget.value())) {
|
||||
System.out.println(holder.switches);
|
||||
throw new MalformedCommandException("Switch Target specifies nonexistent switch \"" + switchTarget.value() + "\"");
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.dfsek.terra.api.docs;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* For use in Terra AutoDoc, to specify
|
||||
* that references to the annotated class
|
||||
* should be refactored in the documentation.
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface AutoDocAlias {
|
||||
String value();
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.dfsek.terra.api.docs;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* For use in Terra AutoDoc, to specify
|
||||
* that references to the annotated class
|
||||
* should be shadowed to the target class.
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface AutoDocShadow {
|
||||
String value();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.dfsek.terra.api.event.events;
|
||||
|
||||
import com.dfsek.terra.api.util.mutable.MutableBoolean;
|
||||
|
||||
/**
|
||||
* Abstract class containing basic {@link Cancellable} implementation.
|
||||
*/
|
||||
public abstract class AbstractCancellable implements Cancellable {
|
||||
private final MutableBoolean cancelled = new MutableBoolean(false);
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled.set(cancelled);
|
||||
}
|
||||
}
|
||||
+9
-4
@@ -1,6 +1,5 @@
|
||||
package com.dfsek.terra.api.event.events.world;
|
||||
|
||||
import com.dfsek.terra.api.event.events.Event;
|
||||
import com.dfsek.terra.api.event.events.PackEvent;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import com.dfsek.terra.config.pack.WorldConfig;
|
||||
@@ -9,18 +8,24 @@ import com.dfsek.terra.world.TerraWorld;
|
||||
/**
|
||||
* Called upon initialization of a TerraWorld.
|
||||
*/
|
||||
public class TerraWorldLoadEvent implements Event {
|
||||
public class TerraWorldLoadEvent implements PackEvent {
|
||||
private final TerraWorld world;
|
||||
private final ConfigPack pack;
|
||||
|
||||
public TerraWorldLoadEvent(TerraWorld world) {
|
||||
public TerraWorldLoadEvent(TerraWorld world, ConfigPack pack) {
|
||||
this.world = world;
|
||||
this.pack = pack;
|
||||
}
|
||||
|
||||
public TerraWorld getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public WorldConfig getPack() {
|
||||
public ConfigPack getPack() {
|
||||
return pack;
|
||||
}
|
||||
|
||||
public WorldConfig getWorldConfig() {
|
||||
return world.getConfig();
|
||||
}
|
||||
}
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.dfsek.terra.api.event.events.world.generation;
|
||||
|
||||
import com.dfsek.terra.api.event.events.PackEvent;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.entity.Entity;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedEntity;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
|
||||
/**
|
||||
* Called when an entity is spawned via {@link BufferedEntity}.
|
||||
*/
|
||||
public class EntitySpawnEvent implements PackEvent {
|
||||
private final ConfigPack pack;
|
||||
private final Entity entity;
|
||||
private final Location location;
|
||||
|
||||
public EntitySpawnEvent(ConfigPack pack, Entity entity, Location location) {
|
||||
this.pack = pack;
|
||||
this.entity = entity;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigPack getPack() {
|
||||
return pack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity that triggered the event.
|
||||
*
|
||||
* @return The entity.
|
||||
*/
|
||||
public Entity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the location of the entity.
|
||||
*
|
||||
* @return Location of the entity.
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
package com.dfsek.terra.api.event.events.world.generation;
|
||||
|
||||
import com.dfsek.terra.api.event.events.AbstractCancellable;
|
||||
import com.dfsek.terra.api.event.events.Cancellable;
|
||||
import com.dfsek.terra.api.event.events.PackEvent;
|
||||
import com.dfsek.terra.api.platform.block.Block;
|
||||
import com.dfsek.terra.api.platform.block.state.Container;
|
||||
import com.dfsek.terra.api.structures.loot.LootTable;
|
||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedLootApplication;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when loot is populated via {@link BufferedLootApplication}.
|
||||
*/
|
||||
public class LootPopulateEvent extends AbstractCancellable implements PackEvent, Cancellable {
|
||||
private final Block block;
|
||||
private final Container container;
|
||||
private LootTable table;
|
||||
private final ConfigPack pack;
|
||||
private final StructureScript script;
|
||||
|
||||
public LootPopulateEvent(Block block, Container container, LootTable table, ConfigPack pack, StructureScript script) {
|
||||
this.block = block;
|
||||
this.container = container;
|
||||
this.table = table;
|
||||
this.pack = pack;
|
||||
this.script = script;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigPack getPack() {
|
||||
return pack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block containing the tile entity loot is applied to.
|
||||
*
|
||||
* @return Block at which loot is applied.
|
||||
*/
|
||||
public Block getBlock() {
|
||||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Container} representing the inventory.
|
||||
*
|
||||
* @return Inventory recieving loot.
|
||||
*/
|
||||
public Container getContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the loot table to be populated.
|
||||
* @return Loot table.
|
||||
*/
|
||||
public LootTable getTable() {
|
||||
return table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the loot table to be populated.
|
||||
*
|
||||
* @param table New loot table.
|
||||
*/
|
||||
public void setTable(@NotNull LootTable table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the script used to generate the structure.
|
||||
*
|
||||
* @return Structure script.
|
||||
*/
|
||||
public StructureScript getStructureScript() {
|
||||
return script;
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,7 @@ public class StructureScript {
|
||||
.registerFunction("setMark", new SetMarkFunctionBuilder())
|
||||
.registerFunction("getMark", new GetMarkFunctionBuilder())
|
||||
.registerFunction("pull", new PullFunctionBuilder(main))
|
||||
.registerFunction("loot", new LootFunctionBuilder(main, lootRegistry))
|
||||
.registerFunction("loot", new LootFunctionBuilder(main, lootRegistry, this))
|
||||
.registerFunction("entity", new EntityFunctionBuilder(main))
|
||||
.registerFunction("getBiome", new BiomeFunctionBuilder(main))
|
||||
.registerFunction("getBlock", new CheckBlockFunctionBuilder())
|
||||
|
||||
+5
-2
@@ -3,6 +3,7 @@ package com.dfsek.terra.api.structures.script.builders;
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.structures.parser.lang.Returnable;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||
import com.dfsek.terra.api.structures.script.functions.LootFunction;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
import com.dfsek.terra.registry.config.LootRegistry;
|
||||
@@ -12,16 +13,18 @@ import java.util.List;
|
||||
public class LootFunctionBuilder implements FunctionBuilder<LootFunction> {
|
||||
private final TerraPlugin main;
|
||||
private final LootRegistry registry;
|
||||
private final StructureScript script;
|
||||
|
||||
public LootFunctionBuilder(TerraPlugin main, LootRegistry registry) {
|
||||
public LootFunctionBuilder(TerraPlugin main, LootRegistry registry, StructureScript script) {
|
||||
this.main = main;
|
||||
this.registry = registry;
|
||||
this.script = script;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public LootFunction build(List<Returnable<?>> argumentList, Position position) {
|
||||
return new LootFunction(registry, (Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), main, position);
|
||||
return new LootFunction(registry, (Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), main, position, script);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-1
@@ -21,9 +21,11 @@ public class EntityFunction implements Function<Void> {
|
||||
private final EntityType data;
|
||||
private final Returnable<Number> x, y, z;
|
||||
private final Position position;
|
||||
private final TerraPlugin main;
|
||||
|
||||
public EntityFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, TerraPlugin main, Position position) throws ParseException {
|
||||
this.position = position;
|
||||
this.main = main;
|
||||
if(!(data instanceof ConstantExpression)) throw new ParseException("Entity data must be constant", data.getPosition());
|
||||
|
||||
this.data = main.getWorldHandle().getEntity(((ConstantExpression<String>) data).getConstant());
|
||||
@@ -39,7 +41,7 @@ public class EntityFunction implements Function<Void> {
|
||||
|
||||
RotationUtil.rotateVector(xz, arguments.getRotation());
|
||||
|
||||
arguments.getBuffer().addItem(new BufferedEntity(data), new Vector3(xz.getX(), y.apply(implementationArguments, variableMap).doubleValue(), xz.getZ()).toLocation(arguments.getBuffer().getOrigin().getWorld()));
|
||||
arguments.getBuffer().addItem(new BufferedEntity(data, main), new Vector3(xz.getX(), y.apply(implementationArguments, variableMap).doubleValue(), xz.getZ()).toLocation(arguments.getBuffer().getOrigin().getWorld()));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -8,6 +8,7 @@ import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
|
||||
import com.dfsek.terra.api.structures.parser.lang.Returnable;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.Function;
|
||||
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
|
||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||
import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
|
||||
import com.dfsek.terra.api.structures.structure.RotationUtil;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedLootApplication;
|
||||
@@ -23,8 +24,9 @@ public class LootFunction implements Function<Void> {
|
||||
private final Returnable<Number> x, y, z;
|
||||
private final Position position;
|
||||
private final TerraPlugin main;
|
||||
private final StructureScript script;
|
||||
|
||||
public LootFunction(LootRegistry registry, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, TerraPlugin main, Position position) {
|
||||
public LootFunction(LootRegistry registry, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, TerraPlugin main, Position position, StructureScript script) {
|
||||
this.registry = registry;
|
||||
this.position = position;
|
||||
this.data = data;
|
||||
@@ -32,6 +34,7 @@ public class LootFunction implements Function<Void> {
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.main = main;
|
||||
this.script = script;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,7 +52,7 @@ public class LootFunction implements Function<Void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
arguments.getBuffer().addItem(new BufferedLootApplication(table, main), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld()));
|
||||
arguments.getBuffer().addItem(new BufferedLootApplication(table, main, script), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld()));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+8
-2
@@ -1,18 +1,24 @@
|
||||
package com.dfsek.terra.api.structures.structure.buffer.items;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.event.events.world.generation.EntitySpawnEvent;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.entity.Entity;
|
||||
import com.dfsek.terra.api.platform.entity.EntityType;
|
||||
|
||||
public class BufferedEntity implements BufferedItem {
|
||||
|
||||
private final EntityType type;
|
||||
private final TerraPlugin main;
|
||||
|
||||
public BufferedEntity(EntityType type) {
|
||||
public BufferedEntity(EntityType type, TerraPlugin main) {
|
||||
this.type = type;
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paste(Location origin) {
|
||||
origin.clone().add(0.5, 0, 0.5).getWorld().spawnEntity(origin, type);
|
||||
Entity entity = origin.clone().add(0.5, 0, 0.5).getWorld().spawnEntity(origin, type);
|
||||
main.getEventManager().callEvent(new EntitySpawnEvent(main.getWorld(entity.getWorld()).getGenerator().getConfigPack(), entity, entity.getLocation()));
|
||||
}
|
||||
}
|
||||
|
||||
+14
-3
@@ -1,31 +1,42 @@
|
||||
package com.dfsek.terra.api.structures.structure.buffer.items;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.event.events.world.generation.LootPopulateEvent;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.block.Block;
|
||||
import com.dfsek.terra.api.platform.block.state.BlockState;
|
||||
import com.dfsek.terra.api.platform.block.state.Container;
|
||||
import com.dfsek.terra.api.structures.loot.LootTable;
|
||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||
import com.dfsek.terra.api.util.FastRandom;
|
||||
|
||||
public class BufferedLootApplication implements BufferedItem {
|
||||
private final LootTable table;
|
||||
private final TerraPlugin main;
|
||||
private final StructureScript structure;
|
||||
|
||||
public BufferedLootApplication(LootTable table, TerraPlugin main) {
|
||||
public BufferedLootApplication(LootTable table, TerraPlugin main, StructureScript structure) {
|
||||
this.table = table;
|
||||
this.main = main;
|
||||
this.structure = structure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paste(Location origin) {
|
||||
try {
|
||||
BlockState data = origin.getBlock().getState();
|
||||
Block block = origin.getBlock();
|
||||
BlockState data = block.getState();
|
||||
if(!(data instanceof Container)) {
|
||||
main.logger().severe("Failed to place loot at " + origin + "; block " + data + " is not container.");
|
||||
return;
|
||||
}
|
||||
Container container = (Container) data;
|
||||
table.fillInventory(container.getInventory(), new FastRandom(origin.hashCode()));
|
||||
|
||||
LootPopulateEvent event = new LootPopulateEvent(block, container, table, main.getWorld(block.getLocation().getWorld()).getGenerator().getConfigPack(), structure);
|
||||
main.getEventManager().callEvent(event);
|
||||
if(event.isCancelled()) return;
|
||||
|
||||
event.getTable().fillInventory(container.getInventory(), new FastRandom(origin.hashCode()));
|
||||
data.update(false);
|
||||
} catch(Exception e) {
|
||||
main.logger().warning("Could not apply loot at " + origin + ": " + e.getMessage());
|
||||
|
||||
@@ -5,6 +5,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class MutableBoolean implements MutablePrimitive<Boolean> {
|
||||
private boolean value;
|
||||
|
||||
public MutableBoolean() {
|
||||
this.value = false;
|
||||
}
|
||||
|
||||
public MutableBoolean(boolean value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean get() {
|
||||
return value;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.dfsek.terra.api.world.generation;
|
||||
|
||||
/**
|
||||
* Marker interface that marks a feature as "chunkified" (only modifying one chunk at a time)
|
||||
*/
|
||||
public interface Chunkified {
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.dfsek.terra.api.world.generation;
|
||||
|
||||
/**
|
||||
* The phase of terrain generation. Used for modifying values based on the phase of generation.
|
||||
*/
|
||||
public enum GenerationPhase {
|
||||
BASE, POPULATE, GENERATION_POPULATE, PALETTE_APPLY, POST_GEN
|
||||
}
|
||||
@@ -6,10 +6,10 @@ import com.dfsek.terra.api.platform.world.World;
|
||||
import com.dfsek.terra.api.platform.world.generator.ChunkData;
|
||||
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import com.dfsek.terra.world.generation.math.SamplerCache;
|
||||
import com.dfsek.terra.world.generation.math.samplers.Sampler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public interface TerraChunkGenerator {
|
||||
@@ -32,4 +32,6 @@ public interface TerraChunkGenerator {
|
||||
TerraPlugin getMain();
|
||||
|
||||
Sampler createSampler(int chunkX, int chunkZ, BiomeProvider provider, World world, int elevationSmooth);
|
||||
|
||||
List<TerraBlockPopulator> getPopulators();
|
||||
}
|
||||
|
||||
@@ -63,8 +63,6 @@ public class StructureLoadCommand implements CommandTemplate {
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
System.out.println(rotation);
|
||||
|
||||
Player player = (Player) sender;
|
||||
|
||||
long t = System.nanoTime();
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
package com.dfsek.terra.config.builder;
|
||||
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.platform.world.Biome;
|
||||
import com.dfsek.terra.api.util.collections.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.util.seeded.SeededBuilder;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
|
||||
@AutoDocAlias("TerraBiome")
|
||||
public interface BiomeBuilder extends SeededBuilder<TerraBiome> {
|
||||
ProbabilityCollection<Biome> getVanillaBiomes();
|
||||
|
||||
BiomeTemplate getTemplate();
|
||||
}
|
||||
|
||||
@@ -66,4 +66,9 @@ public class UserDefinedBiomeBuilder implements BiomeBuilder {
|
||||
public ProbabilityCollection<Biome> getVanillaBiomes() {
|
||||
return template.getVanilla();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeTemplate getTemplate() {
|
||||
return template;
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -11,16 +11,28 @@ import com.dfsek.terra.api.world.biome.provider.StandardBiomeProvider;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Configures a biome pipeline.
|
||||
*/
|
||||
@SuppressWarnings({"FieldMayBeFinal", "unused"})
|
||||
public class BiomePipelineTemplate extends BiomeProviderTemplate {
|
||||
private final TerraPlugin main;
|
||||
/**
|
||||
* Initial size of biome pipeline chunks.
|
||||
*/
|
||||
@Value("pipeline.initial-size")
|
||||
@Default
|
||||
private int initialSize = 2;
|
||||
|
||||
/**
|
||||
* Mutator stages to be used in this biome pipeline.
|
||||
*/
|
||||
@Value("pipeline.stages")
|
||||
private List<StageSeeded> stages;
|
||||
|
||||
/**
|
||||
* Biome source to initialize the pipeline.
|
||||
*/
|
||||
@Value("pipeline.source")
|
||||
private SourceSeeded source;
|
||||
|
||||
|
||||
+15
-2
@@ -8,10 +8,21 @@ import com.dfsek.terra.api.math.noise.samplers.noise.ConstantSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
|
||||
|
||||
/**
|
||||
* Configures a biome provider.
|
||||
*/
|
||||
public abstract class BiomeProviderTemplate implements ObjectTemplate<BiomeProvider.BiomeProviderBuilder>, BiomeProvider.BiomeProviderBuilder {
|
||||
/**
|
||||
* Resolution of this provider.
|
||||
* A resolution of 1 means that 1 block = 1 sample.
|
||||
*/
|
||||
@Value("resolution")
|
||||
@Default
|
||||
protected int resolution = 1;
|
||||
|
||||
/**
|
||||
* Noise function to use for blending biomes at edges.
|
||||
*/
|
||||
@Value("blend.noise")
|
||||
@Default
|
||||
protected NoiseSeeded blend = new NoiseSeeded() {
|
||||
@@ -25,11 +36,13 @@ public abstract class BiomeProviderTemplate implements ObjectTemplate<BiomeProvi
|
||||
return 2;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Amplitude of edge blending, in blocks.
|
||||
*/
|
||||
@Value("blend.amplitude")
|
||||
@Default
|
||||
protected double blendAmp = 0d;
|
||||
@Value("type")
|
||||
BiomeProvider.Type type;
|
||||
|
||||
@Override
|
||||
public BiomeProvider.BiomeProviderBuilder get() {
|
||||
|
||||
+10
@@ -9,11 +9,21 @@ import com.dfsek.terra.config.builder.BiomeBuilder;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Configures an image biome provider.
|
||||
*/
|
||||
public class ImageProviderTemplate extends BiomeProviderTemplate {
|
||||
private final Registry<BiomeBuilder> biomes;
|
||||
|
||||
/**
|
||||
* Image to use for biome selection.
|
||||
*/
|
||||
@Value("image.name")
|
||||
private BufferedImage image;
|
||||
|
||||
/**
|
||||
* How the image should be aligned.
|
||||
*/
|
||||
@Value("image.align")
|
||||
private ImageBiomeProvider.Align align;
|
||||
|
||||
|
||||
+6
@@ -5,7 +5,13 @@ import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.biome.provider.SingleBiomeProvider;
|
||||
import com.dfsek.terra.config.builder.BiomeBuilder;
|
||||
|
||||
/**
|
||||
* Configures a single-biome provider.
|
||||
*/
|
||||
public class SingleBiomeProviderTemplate extends BiomeProviderTemplate {
|
||||
/**
|
||||
* The biome.
|
||||
*/
|
||||
@Value("biome")
|
||||
private BiomeBuilder biome;
|
||||
|
||||
|
||||
+11
@@ -1,16 +1,27 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome.templates.source;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.util.collections.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.api.world.biome.pipeline.source.BiomeSource;
|
||||
import com.dfsek.terra.api.world.biome.pipeline.source.RandomSource;
|
||||
import com.dfsek.terra.config.builder.BiomeBuilder;
|
||||
|
||||
/**
|
||||
* Configures a noise-based biome source.
|
||||
*/
|
||||
@AutoDocAlias("NoiseSource")
|
||||
public class NoiseSourceTemplate extends SourceTemplate {
|
||||
/**
|
||||
* Noise function to use for selecting biomes.
|
||||
*/
|
||||
@Value("noise")
|
||||
private NoiseSeeded noise;
|
||||
|
||||
/**
|
||||
* ProbabilityCollection of biomes to use.
|
||||
*/
|
||||
@Value("biomes")
|
||||
private ProbabilityCollection<BiomeBuilder> biomes;
|
||||
|
||||
|
||||
+2
@@ -1,9 +1,11 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome.templates.source;
|
||||
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.util.seeded.SourceSeeded;
|
||||
import com.dfsek.terra.api.world.biome.pipeline.source.BiomeSource;
|
||||
|
||||
@AutoDocAlias("SourceSeeded")
|
||||
public abstract class SourceTemplate implements ObjectTemplate<SourceSeeded>, SourceSeeded {
|
||||
@Override
|
||||
public SourceSeeded get() {
|
||||
|
||||
+5
@@ -2,12 +2,17 @@ package com.dfsek.terra.config.loaders.config.biome.templates.stage;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.api.util.seeded.SeededBuilder;
|
||||
import com.dfsek.terra.api.util.seeded.StageSeeded;
|
||||
import com.dfsek.terra.api.world.biome.pipeline.stages.Stage;
|
||||
|
||||
@AutoDocAlias("StageSeeded")
|
||||
public abstract class StageTemplate implements ObjectTemplate<SeededBuilder<Stage>>, StageSeeded {
|
||||
/**
|
||||
* Noise function to use for mutating biomes in this stage.
|
||||
*/
|
||||
@Value("noise")
|
||||
protected NoiseSeeded noise;
|
||||
|
||||
|
||||
+15
@@ -1,6 +1,7 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.util.collections.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
import com.dfsek.terra.api.world.biome.pipeline.mutator.BiomeMutator;
|
||||
@@ -11,16 +12,30 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@AutoDocAlias("BorderListMutator")
|
||||
public class BorderListMutatorTemplate extends MutatorStageTemplate {
|
||||
/**
|
||||
* Tag of the biome on the external side of the border.
|
||||
*/
|
||||
@Value("from")
|
||||
private String from;
|
||||
|
||||
/**
|
||||
* Tag of biomes to replace when bordering biomes with
|
||||
* tag "from".
|
||||
*/
|
||||
@Value("default-replace")
|
||||
private String defaultReplace;
|
||||
|
||||
/**
|
||||
* Default replacement biomes.
|
||||
*/
|
||||
@Value("default-to")
|
||||
private ProbabilityCollection<BiomeBuilder> defaultTo;
|
||||
|
||||
/**
|
||||
* Map of single biomes to their replacements.
|
||||
*/
|
||||
@Value("replace")
|
||||
private Map<BiomeBuilder, ProbabilityCollection<BiomeBuilder>> replace;
|
||||
|
||||
|
||||
+13
@@ -1,19 +1,32 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.util.collections.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.biome.pipeline.mutator.BiomeMutator;
|
||||
import com.dfsek.terra.api.world.biome.pipeline.mutator.BorderMutator;
|
||||
import com.dfsek.terra.config.builder.BiomeBuilder;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@AutoDocAlias("BorderMutator")
|
||||
public class BorderMutatorTemplate extends MutatorStageTemplate {
|
||||
/**
|
||||
* Tag of the biome on the external side of the border.
|
||||
*/
|
||||
@Value("from")
|
||||
private String from;
|
||||
|
||||
/**
|
||||
* Tag of biomes to replace when bordering biomes
|
||||
* with tag "from"
|
||||
*/
|
||||
@Value("replace")
|
||||
private String replace;
|
||||
|
||||
/**
|
||||
* Collection of biomes to place at borders
|
||||
* of "from" and "to"
|
||||
*/
|
||||
@Value("to")
|
||||
private ProbabilityCollection<BiomeBuilder> to;
|
||||
|
||||
|
||||
+2
@@ -1,10 +1,12 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator;
|
||||
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.world.biome.pipeline.mutator.BiomeMutator;
|
||||
import com.dfsek.terra.api.world.biome.pipeline.stages.MutatorStage;
|
||||
import com.dfsek.terra.api.world.biome.pipeline.stages.Stage;
|
||||
import com.dfsek.terra.config.loaders.config.biome.templates.stage.StageTemplate;
|
||||
|
||||
@AutoDocAlias("MutatorStage")
|
||||
public abstract class MutatorStageTemplate extends StageTemplate {
|
||||
public abstract BiomeMutator build(long seed);
|
||||
|
||||
|
||||
+5
@@ -1,6 +1,7 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.util.collections.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
import com.dfsek.terra.api.world.biome.pipeline.mutator.BiomeMutator;
|
||||
@@ -11,7 +12,11 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@AutoDocAlias("ReplaceListMutator")
|
||||
public class ReplaceListMutatorTemplate extends MutatorStageTemplate {
|
||||
/**
|
||||
* Default tag to replace from
|
||||
*/
|
||||
@Value("default-from")
|
||||
private String defaultFrom;
|
||||
|
||||
|
||||
+8
@@ -1,16 +1,24 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.util.collections.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.biome.pipeline.mutator.BiomeMutator;
|
||||
import com.dfsek.terra.api.world.biome.pipeline.mutator.ReplaceMutator;
|
||||
import com.dfsek.terra.config.builder.BiomeBuilder;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@AutoDocAlias("ReplaceMutator")
|
||||
public class ReplaceMutatorTemplate extends MutatorStageTemplate {
|
||||
/**
|
||||
* Tag of biomes to replace.
|
||||
*/
|
||||
@Value("from")
|
||||
private String from;
|
||||
|
||||
/**
|
||||
* Biomes to replace with.
|
||||
*/
|
||||
@Value("to")
|
||||
private ProbabilityCollection<BiomeBuilder> to;
|
||||
|
||||
|
||||
+2
@@ -1,8 +1,10 @@
|
||||
package com.dfsek.terra.config.loaders.config.biome.templates.stage.mutator;
|
||||
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.world.biome.pipeline.mutator.BiomeMutator;
|
||||
import com.dfsek.terra.api.world.biome.pipeline.mutator.SmoothMutator;
|
||||
|
||||
@AutoDocAlias("SmoothMutator")
|
||||
public class SmoothMutatorTemplate extends MutatorStageTemplate {
|
||||
@Override
|
||||
public BiomeMutator build(long seed) {
|
||||
|
||||
+2
@@ -6,6 +6,7 @@ import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.registry.config.NoiseRegistry;
|
||||
|
||||
@@ -14,6 +15,7 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@AutoDocAlias("NoiseSeeded")
|
||||
public class NoiseSamplerBuilderLoader implements TypeLoader<NoiseSeeded> {
|
||||
private final NoiseRegistry noiseRegistry;
|
||||
|
||||
|
||||
+20
-2
@@ -2,28 +2,46 @@ package com.dfsek.terra.config.loaders.config.sampler.templates;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.samplers.DomainWarpedSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
|
||||
/**
|
||||
* Defines a domain-warped noise function.
|
||||
*/
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
@AutoDocAlias("DomainWarpedSampler")
|
||||
public class DomainWarpTemplate extends SamplerTemplate<DomainWarpedSampler> {
|
||||
/**
|
||||
* Noise function used to warp input function.
|
||||
*/
|
||||
@Value("warp")
|
||||
private NoiseSeeded warp;
|
||||
|
||||
/**
|
||||
* Input function (function to be warped)
|
||||
*/
|
||||
@Value("function")
|
||||
private NoiseSeeded function;
|
||||
|
||||
/**
|
||||
* Salt for both warp function and
|
||||
* input function.
|
||||
*/
|
||||
@Value("salt")
|
||||
@Default
|
||||
private int salt = 0;
|
||||
|
||||
/**
|
||||
* Amplitude of warping. Values provided by
|
||||
* the warp function are multiplied by this constant.
|
||||
*/
|
||||
@Value("amplitude")
|
||||
@Default
|
||||
private double amplitude = 1;
|
||||
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
public DomainWarpedSampler apply(Long seed) {
|
||||
return new DomainWarpedSampler(function.apply(seed), warp.apply(seed), (int) (seed + salt), amplitude);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,12 +1,13 @@
|
||||
package com.dfsek.terra.config.loaders.config.sampler.templates;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.samplers.ImageSampler;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
@AutoDocAlias("ImageSampler")
|
||||
public class ImageSamplerTemplate extends SamplerTemplate<ImageSampler> {
|
||||
|
||||
@Value("image")
|
||||
@@ -19,7 +20,7 @@ public class ImageSamplerTemplate extends SamplerTemplate<ImageSampler> {
|
||||
private ImageSampler.Channel channel;
|
||||
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
public ImageSampler apply(Long seed) {
|
||||
return new ImageSampler(image, channel, frequency);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -4,13 +4,14 @@ import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
|
||||
import com.dfsek.tectonic.exception.ValidationException;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.samplers.KernelSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
@AutoDocAlias("KernelSampler")
|
||||
public class KernelTemplate extends SamplerTemplate<KernelSampler> implements ValidatedConfigTemplate {
|
||||
|
||||
@Value("kernel")
|
||||
@@ -28,7 +29,7 @@ public class KernelTemplate extends SamplerTemplate<KernelSampler> implements Va
|
||||
private double frequency = 1;
|
||||
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
public KernelSampler apply(Long seed) {
|
||||
double[][] k = new double[kernel.size()][kernel.get(0).size()];
|
||||
|
||||
for(int x = 0; x < kernel.size(); x++) {
|
||||
|
||||
+8
@@ -5,11 +5,16 @@ import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
|
||||
import com.dfsek.tectonic.exception.ValidationException;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
@AutoDocAlias("NoiseSeeded")
|
||||
public abstract class SamplerTemplate<T extends NoiseSampler> implements ValidatedConfigTemplate, ObjectTemplate<NoiseSeeded>, NoiseSeeded {
|
||||
/**
|
||||
* Number of dimensions for this sampler.
|
||||
*/
|
||||
@Value("dimensions")
|
||||
@Default
|
||||
private int dimensions = 2;
|
||||
@@ -28,4 +33,7 @@ public abstract class SamplerTemplate<T extends NoiseSampler> implements Validat
|
||||
public NoiseSeeded get() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract T apply(Long seed);
|
||||
}
|
||||
|
||||
+3
-1
@@ -2,12 +2,14 @@ package com.dfsek.terra.config.loaders.config.sampler.templates.noise;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.CellularSampler;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.simplex.OpenSimplex2Sampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
@AutoDocAlias("CellularSampler")
|
||||
public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> {
|
||||
@Value("distance")
|
||||
@Default
|
||||
@@ -38,7 +40,7 @@ public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> {
|
||||
};
|
||||
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
public CellularSampler apply(Long seed) {
|
||||
CellularSampler sampler = new CellularSampler((int) (long) seed + salt);
|
||||
sampler.setNoiseLookup(lookup.apply(seed));
|
||||
sampler.setFrequency(frequency);
|
||||
|
||||
+3
-2
@@ -2,18 +2,19 @@ package com.dfsek.terra.config.loaders.config.sampler.templates.noise;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.ConstantSampler;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.SamplerTemplate;
|
||||
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
@AutoDocAlias("ConstantSampler")
|
||||
public class ConstantNoiseTemplate extends SamplerTemplate<ConstantSampler> {
|
||||
@Value("value")
|
||||
@Default
|
||||
private double value = 0d;
|
||||
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
public ConstantSampler apply(Long seed) {
|
||||
return new ConstantSampler(value);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -8,9 +8,8 @@ import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
|
||||
import com.dfsek.tectonic.exception.ValidationException;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.ExpressionFunction;
|
||||
import com.dfsek.terra.api.math.paralithic.BlankFunction;
|
||||
import com.dfsek.terra.api.math.paralithic.defined.UserDefinedFunction;
|
||||
import com.dfsek.terra.api.math.paralithic.noise.NoiseFunction2;
|
||||
import com.dfsek.terra.api.math.paralithic.noise.NoiseFunction3;
|
||||
@@ -24,6 +23,7 @@ import java.util.Map;
|
||||
|
||||
|
||||
@SuppressWarnings({"FieldMayBeFinal", "unused"})
|
||||
@AutoDocAlias("ExpressionFunction")
|
||||
public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFunction> implements ValidatedConfigTemplate {
|
||||
@Value("variables")
|
||||
@Default
|
||||
@@ -41,7 +41,7 @@ public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFuncti
|
||||
private LinkedHashMap<String, FunctionTemplate> expressions = new LinkedHashMap<>();
|
||||
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
public ExpressionFunction apply(Long seed) {
|
||||
try {
|
||||
Map<String, Function> noiseFunctionMap = generateFunctions(seed);
|
||||
return new ExpressionFunction(noiseFunctionMap, equation, vars);
|
||||
@@ -65,7 +65,6 @@ public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFuncti
|
||||
Map<String, Function> noiseFunctionMap = new HashMap<>();
|
||||
|
||||
for(Map.Entry<String, FunctionTemplate> entry : expressions.entrySet()) {
|
||||
System.out.println(entry);
|
||||
noiseFunctionMap.put(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue(), new Parser(), new Scope()));
|
||||
}
|
||||
|
||||
|
||||
+15
-2
@@ -2,18 +2,31 @@ package com.dfsek.terra.config.loaders.config.sampler.templates.noise;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.GaborNoiseSampler;
|
||||
|
||||
/**
|
||||
* Defines a Gabor noise function.
|
||||
*/
|
||||
@AutoDocAlias("GaborNoiseSampler")
|
||||
public class GaborNoiseTemplate extends NoiseTemplate<GaborNoiseSampler> {
|
||||
/**
|
||||
* Rotation to apply to noise. Only has noticeable effects in anisotropic mode.
|
||||
*/
|
||||
@Value("rotation")
|
||||
@Default
|
||||
private double rotation = 0.25;
|
||||
|
||||
/**
|
||||
* Whether to use anisotropic or isotropic algorithm.
|
||||
*/
|
||||
@Value("isotropic")
|
||||
@Default
|
||||
private boolean isotropic = true;
|
||||
|
||||
/**
|
||||
* Standard deviation of result values.
|
||||
*/
|
||||
@Value("deviation")
|
||||
@Default
|
||||
private double deviation = 1.0;
|
||||
@@ -27,7 +40,7 @@ public class GaborNoiseTemplate extends NoiseTemplate<GaborNoiseSampler> {
|
||||
private double f0 = 0.625;
|
||||
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
public GaborNoiseSampler apply(Long seed) {
|
||||
GaborNoiseSampler gaborNoiseSampler = new GaborNoiseSampler((int) (long) seed + salt);
|
||||
gaborNoiseSampler.setFrequency(frequency);
|
||||
gaborNoiseSampler.setRotation(rotation);
|
||||
|
||||
+2
@@ -2,10 +2,12 @@ package com.dfsek.terra.config.loaders.config.sampler.templates.noise;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.NoiseFunction;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.SamplerTemplate;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
@AutoDocAlias("NoiseFunction")
|
||||
public abstract class NoiseTemplate<T extends NoiseFunction> extends SamplerTemplate<T> {
|
||||
@Value("frequency")
|
||||
@Default
|
||||
|
||||
+3
-2
@@ -1,10 +1,11 @@
|
||||
package com.dfsek.terra.config.loaders.config.sampler.templates.noise;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.docs.AutoDocShadow;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.NoiseFunction;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
@AutoDocShadow("NoiseFunction")
|
||||
public class SimpleNoiseTemplate extends NoiseTemplate<NoiseFunction> {
|
||||
private final Function<Integer, NoiseFunction> samplerSupplier;
|
||||
|
||||
@@ -13,7 +14,7 @@ public class SimpleNoiseTemplate extends NoiseTemplate<NoiseFunction> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
public NoiseFunction apply(Long seed) {
|
||||
NoiseFunction sampler = samplerSupplier.apply((int) (long) seed + salt);
|
||||
sampler.setFrequency(frequency);
|
||||
return sampler;
|
||||
|
||||
+3
-2
@@ -1,11 +1,12 @@
|
||||
package com.dfsek.terra.config.loaders.config.sampler.templates.noise.fractal;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.fractal.BrownianMotionSampler;
|
||||
|
||||
@AutoDocAlias("BrownianMotionSampler")
|
||||
public class BrownianMotionTemplate extends FractalTemplate<BrownianMotionSampler> {
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
public BrownianMotionSampler apply(Long seed) {
|
||||
BrownianMotionSampler sampler = new BrownianMotionSampler((int) (long) seed, function.apply(seed));
|
||||
sampler.setGain(fractalGain);
|
||||
sampler.setLacunarity(fractalLacunarity);
|
||||
|
||||
+2
@@ -2,10 +2,12 @@ package com.dfsek.terra.config.loaders.config.sampler.templates.noise.fractal;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.fractal.FractalNoiseFunction;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.SamplerTemplate;
|
||||
|
||||
@AutoDocAlias("FractalNoiseFunction")
|
||||
public abstract class FractalTemplate<T extends FractalNoiseFunction> extends SamplerTemplate<T> {
|
||||
@Value("octaves")
|
||||
@Default
|
||||
|
||||
+3
-2
@@ -2,16 +2,17 @@ package com.dfsek.terra.config.loaders.config.sampler.templates.noise.fractal;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.fractal.PingPongSampler;
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
@AutoDocAlias("PingPongSampler")
|
||||
public class PingPongTemplate extends FractalTemplate<PingPongSampler> {
|
||||
@Value("ping-pong")
|
||||
@Default
|
||||
private double pingPong = 2.0D;
|
||||
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
public PingPongSampler apply(Long seed) {
|
||||
PingPongSampler sampler = new PingPongSampler((int) (long) seed, function.apply(seed));
|
||||
sampler.setGain(fractalGain);
|
||||
sampler.setLacunarity(fractalLacunarity);
|
||||
|
||||
+3
-2
@@ -1,11 +1,12 @@
|
||||
package com.dfsek.terra.config.loaders.config.sampler.templates.noise.fractal;
|
||||
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.fractal.RidgedFractalSampler;
|
||||
|
||||
@AutoDocAlias("RidgedFractalSampler")
|
||||
public class RidgedFractalTemplate extends FractalTemplate<RidgedFractalSampler> {
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
public RidgedFractalSampler apply(Long seed) {
|
||||
RidgedFractalSampler sampler = new RidgedFractalSampler((int) (long) seed, function.apply(seed));
|
||||
sampler.setGain(fractalGain);
|
||||
sampler.setLacunarity(fractalLacunarity);
|
||||
|
||||
+4
-4
@@ -1,12 +1,12 @@
|
||||
package com.dfsek.terra.config.loaders.config.sampler.templates.normalizer;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.normalizer.ClampNormalizer;
|
||||
import com.dfsek.terra.api.math.noise.normalizer.LinearNormalizer;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
public class ClampNormalizerTemplate extends NormalizerTemplate<LinearNormalizer> {
|
||||
@AutoDocAlias("ClampNormalizer")
|
||||
public class ClampNormalizerTemplate extends NormalizerTemplate<ClampNormalizer> {
|
||||
@Value("max")
|
||||
private double max;
|
||||
|
||||
@@ -14,7 +14,7 @@ public class ClampNormalizerTemplate extends NormalizerTemplate<LinearNormalizer
|
||||
private double min;
|
||||
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
public ClampNormalizer apply(Long seed) {
|
||||
return new ClampNormalizer(function.apply(seed), min, max);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,10 +1,11 @@
|
||||
package com.dfsek.terra.config.loaders.config.sampler.templates.normalizer;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.normalizer.LinearNormalizer;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
@AutoDocAlias("LinearNormalizer")
|
||||
public class LinearNormalizerTemplate extends NormalizerTemplate<LinearNormalizer> {
|
||||
@Value("max")
|
||||
private double max;
|
||||
@@ -13,7 +14,7 @@ public class LinearNormalizerTemplate extends NormalizerTemplate<LinearNormalize
|
||||
private double min;
|
||||
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
public LinearNormalizer apply(Long seed) {
|
||||
return new LinearNormalizer(function.apply(seed), min, max);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -2,10 +2,11 @@ package com.dfsek.terra.config.loaders.config.sampler.templates.normalizer;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.normalizer.NormalNormalizer;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
@AutoDocAlias("NormalNormalizer")
|
||||
public class NormalNormalizerTemplate extends NormalizerTemplate<NormalNormalizer> {
|
||||
@Value("mean")
|
||||
private double mean;
|
||||
@@ -18,7 +19,7 @@ public class NormalNormalizerTemplate extends NormalizerTemplate<NormalNormalize
|
||||
private int groups = 16384;
|
||||
|
||||
@Override
|
||||
public NoiseSampler apply(Long seed) {
|
||||
public NormalNormalizer apply(Long seed) {
|
||||
return new NormalNormalizer(function.apply(seed), groups, mean, stdDev);
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -1,10 +1,12 @@
|
||||
package com.dfsek.terra.config.loaders.config.sampler.templates.normalizer;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.normalizer.Normalizer;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.config.loaders.config.sampler.templates.SamplerTemplate;
|
||||
|
||||
@AutoDocAlias("Normalizer")
|
||||
public abstract class NormalizerTemplate<T extends Normalizer> extends SamplerTemplate<T> {
|
||||
@Value("function")
|
||||
protected NoiseSeeded function;
|
||||
|
||||
@@ -139,6 +139,7 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
selfLoader.load(packPostTemplate, new FileInputStream(pack));
|
||||
biomeProviderBuilder = packPostTemplate.getProviderBuilder();
|
||||
biomeProviderBuilder.build(0); // Build dummy provider to catch errors at load time.
|
||||
checkDeadEntries(main);
|
||||
} catch(FileNotFoundException e) {
|
||||
throw new LoadException("No pack.yml file found in " + folder.getAbsolutePath(), e);
|
||||
}
|
||||
@@ -183,6 +184,7 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
selfLoader.load(packPostTemplate, file.getInputStream(pack));
|
||||
biomeProviderBuilder = packPostTemplate.getProviderBuilder();
|
||||
biomeProviderBuilder.build(0); // Build dummy provider to catch errors at load time.
|
||||
checkDeadEntries(main);
|
||||
} catch(IOException e) {
|
||||
throw new LoadException("Unable to load pack.yml from ZIP file", e);
|
||||
}
|
||||
@@ -198,6 +200,16 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
for(C template : configTemplates) registry.add(template.getID(), factory.build(template, main));
|
||||
}
|
||||
|
||||
private void checkDeadEntries(TerraPlugin main) {
|
||||
biomeRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in biome registry: '" + id + "'"));
|
||||
paletteRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in palette registry: '" + id + "'"));
|
||||
floraRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in flora registry: '" + id + "'"));
|
||||
carverRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in carver registry: '" + id + "'"));
|
||||
treeRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in tree registry: '" + id + "'"));
|
||||
oreRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in ore registry: '" + id + "'"));
|
||||
}
|
||||
|
||||
|
||||
private void load(long start, TerraPlugin main) throws ConfigException {
|
||||
main.getEventManager().callEvent(new ConfigPackPreLoadEvent(this));
|
||||
|
||||
|
||||
@@ -15,24 +15,52 @@ import java.util.Set;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
public class ConfigPackTemplate implements ConfigTemplate {
|
||||
|
||||
/**
|
||||
* The ID of the config pack.
|
||||
*/
|
||||
@Value("id")
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Noise functions to be made available
|
||||
* to noise equations in the config pack.
|
||||
* <p>
|
||||
* Keys are Paralithic function IDs,
|
||||
* values are noise functions.
|
||||
*/
|
||||
@Value("noise")
|
||||
private Map<String, NoiseSeeded> noiseBuilderMap;
|
||||
|
||||
/**
|
||||
* Addons this pack depends on.
|
||||
*/
|
||||
@Value("addons")
|
||||
@Default
|
||||
private Set<TerraAddon> addons = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Variables to be made available
|
||||
* to noise equations in the config pack.
|
||||
* <p>
|
||||
* Keys are variable IDs,
|
||||
* values are variable values.
|
||||
*/
|
||||
@Value("variables")
|
||||
@Default
|
||||
private Map<String, Double> variables = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Whether to enable beta noise
|
||||
* carvers.
|
||||
*/
|
||||
@Value("beta.carving")
|
||||
@Default
|
||||
private boolean betaCarvers = false;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Value("functions")
|
||||
@Default
|
||||
private LinkedHashMap<String, FunctionTemplate> functions = new LinkedHashMap<>();
|
||||
@@ -73,6 +101,46 @@ public class ConfigPackTemplate implements ConfigTemplate {
|
||||
@Default
|
||||
private String version = "0.1.0";
|
||||
|
||||
@Value("disable.carvers")
|
||||
@Default
|
||||
private boolean disableCarvers = false;
|
||||
|
||||
@Value("disable.structures")
|
||||
@Default
|
||||
private boolean disableStructures = false;
|
||||
|
||||
@Value("disable.ores")
|
||||
@Default
|
||||
private boolean disableOres = false;
|
||||
|
||||
@Value("disable.trees")
|
||||
@Default
|
||||
private boolean disableTrees = false;
|
||||
|
||||
@Value("disable.flora")
|
||||
@Default
|
||||
private boolean disableFlora = false;
|
||||
|
||||
public boolean disableCarvers() {
|
||||
return disableCarvers;
|
||||
}
|
||||
|
||||
public boolean disableFlora() {
|
||||
return disableFlora;
|
||||
}
|
||||
|
||||
public boolean disableOres() {
|
||||
return disableOres;
|
||||
}
|
||||
|
||||
public boolean disableStructures() {
|
||||
return disableStructures;
|
||||
}
|
||||
|
||||
public boolean disableTrees() {
|
||||
return disableTrees;
|
||||
}
|
||||
|
||||
public LinkedHashMap<String, FunctionTemplate> getFunctions() {
|
||||
return functions;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
|
||||
import com.dfsek.tectonic.exception.ValidationException;
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.ConstantSampler;
|
||||
import com.dfsek.terra.api.math.paralithic.BlankFunction;
|
||||
@@ -38,6 +39,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@SuppressWarnings({"FieldMayBeFinal", "unused"})
|
||||
@AutoDocAlias("TerraBiome")
|
||||
public class BiomeTemplate extends AbstractableTemplate implements ValidatedConfigTemplate {
|
||||
|
||||
private final ConfigPack pack;
|
||||
@@ -190,10 +192,19 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
|
||||
@Default
|
||||
private Map<UserDefinedCarver, Integer> carvers = new HashMap<>();
|
||||
|
||||
@Value("colors")
|
||||
@Abstractable
|
||||
@Default
|
||||
private Map<String, Integer> colors = new HashMap<>(); // Plain ol' map, so platforms can decide what to do with colors (if anything).
|
||||
|
||||
public Set<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public Map<String, Integer> getColors() {
|
||||
return colors;
|
||||
}
|
||||
|
||||
public Map<UserDefinedCarver, Integer> getCarvers() {
|
||||
return carvers;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.dfsek.terra.config.templates;
|
||||
import com.dfsek.tectonic.annotations.Abstractable;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.Range;
|
||||
import com.dfsek.terra.api.platform.block.BlockType;
|
||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
||||
@@ -12,6 +13,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
@AutoDocAlias("UserDefinedCarver")
|
||||
public class CarverTemplate extends AbstractableTemplate {
|
||||
@Value("id")
|
||||
private String id;
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.dfsek.terra.config.templates;
|
||||
import com.dfsek.tectonic.annotations.Abstractable;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
||||
import com.dfsek.terra.api.world.palette.holder.PaletteLayerHolder;
|
||||
import com.dfsek.terra.world.population.items.flora.TerraFlora;
|
||||
@@ -10,6 +11,7 @@ import com.dfsek.terra.world.population.items.flora.TerraFlora;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings({"FieldMayBeFinal", "unused"})
|
||||
@AutoDocAlias("Flora")
|
||||
public class FloraTemplate extends AbstractableTemplate {
|
||||
@Value("id")
|
||||
private String id;
|
||||
@@ -32,7 +34,7 @@ public class FloraTemplate extends AbstractableTemplate {
|
||||
@Value("irrigable")
|
||||
@Abstractable
|
||||
@Default
|
||||
private MaterialSet irrigable = null;
|
||||
private MaterialSet irrigable = new MaterialSet();
|
||||
|
||||
@Value("rotatable")
|
||||
@Abstractable
|
||||
|
||||
@@ -3,12 +3,14 @@ package com.dfsek.terra.config.templates;
|
||||
import com.dfsek.tectonic.annotations.Abstractable;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.Range;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
||||
import com.dfsek.terra.world.population.items.ores.Ore;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
@AutoDocAlias("Ore")
|
||||
public class OreTemplate extends AbstractableTemplate {
|
||||
@Value("id")
|
||||
private String id;
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.dfsek.terra.config.templates;
|
||||
import com.dfsek.tectonic.annotations.Abstractable;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.random.WhiteNoiseSampler;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
@@ -11,6 +12,7 @@ import com.dfsek.terra.api.world.palette.holder.PaletteLayerHolder;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings({"FieldMayBeFinal", "unused"})
|
||||
@AutoDocAlias("Palette")
|
||||
public class PaletteTemplate extends AbstractableTemplate {
|
||||
@Value("noise")
|
||||
@Abstractable
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.dfsek.tectonic.annotations.Abstractable;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.math.GridSpawn;
|
||||
import com.dfsek.terra.api.math.Range;
|
||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||
@@ -13,6 +14,7 @@ import com.dfsek.terra.api.util.collections.ProbabilityCollection;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
@AutoDocAlias("TerraStructure")
|
||||
public class StructureTemplate extends AbstractableTemplate implements ConfigTemplate {
|
||||
@Value("id")
|
||||
private String id;
|
||||
|
||||
@@ -3,11 +3,13 @@ package com.dfsek.terra.config.templates;
|
||||
import com.dfsek.tectonic.annotations.Abstractable;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.terra.api.docs.AutoDocAlias;
|
||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
||||
import com.dfsek.terra.api.util.collections.ProbabilityCollection;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
@AutoDocAlias("Tree")
|
||||
public class TreeTemplate extends AbstractableTemplate {
|
||||
@Value("scripts")
|
||||
@Abstractable
|
||||
|
||||
@@ -7,18 +7,19 @@ import com.dfsek.terra.registry.exception.DuplicateEntryException;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Registry implementation with read/write access. For internal use only.
|
||||
* @param <T>
|
||||
*/
|
||||
public class OpenRegistry<T> implements Registry<T> {
|
||||
private final Map<String, T> objects = new HashMap<>();
|
||||
private final Map<String, Entry<T>> objects = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public T load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
@@ -35,6 +36,10 @@ public class OpenRegistry<T> implements Registry<T> {
|
||||
* @param value Value to add.
|
||||
*/
|
||||
public boolean add(String identifier, T value) {
|
||||
return add(identifier, new Entry<>(value));
|
||||
}
|
||||
|
||||
protected boolean add(String identifier, Entry<T> value) {
|
||||
boolean exists = objects.containsKey(identifier);
|
||||
objects.put(identifier, value);
|
||||
return exists;
|
||||
@@ -60,22 +65,22 @@ public class OpenRegistry<T> implements Registry<T> {
|
||||
|
||||
@Override
|
||||
public T get(String identifier) {
|
||||
return objects.get(identifier);
|
||||
return objects.get(identifier).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<T> consumer) {
|
||||
objects.forEach((id, obj) -> consumer.accept(obj));
|
||||
objects.forEach((id, obj) -> consumer.accept(obj.getRaw()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(BiConsumer<String, T> consumer) {
|
||||
objects.forEach(consumer);
|
||||
objects.forEach((id, entry) -> consumer.accept(id, entry.getRaw()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<T> entries() {
|
||||
return new HashSet<>(objects.values());
|
||||
return objects.values().stream().map(Entry::getRaw).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,10 +88,41 @@ public class OpenRegistry<T> implements Registry<T> {
|
||||
return objects.keySet();
|
||||
}
|
||||
|
||||
public Map<String, T> getDeadEntries() {
|
||||
Map<String, T> dead = new HashMap<>();
|
||||
objects.forEach((id, entry) -> {
|
||||
if(entry.dead()) dead.put(id, entry.value); // dont increment value here.
|
||||
});
|
||||
return dead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all entries from the registry.
|
||||
*/
|
||||
public void clear() {
|
||||
objects.clear();
|
||||
}
|
||||
|
||||
|
||||
protected static final class Entry<T> {
|
||||
private final T value;
|
||||
private final AtomicInteger access = new AtomicInteger(0);
|
||||
|
||||
public Entry(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
access.incrementAndGet();
|
||||
return value;
|
||||
}
|
||||
|
||||
private T getRaw() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean dead() {
|
||||
return access.get() == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,9 @@ public class FloraRegistry extends OpenRegistry<Flora> {
|
||||
|
||||
private void addItem(String id, Callable<ConstantFlora> flora) {
|
||||
try {
|
||||
add(id, flora.call());
|
||||
Entry<Flora> entry = new Entry<>(flora.call());
|
||||
entry.getValue(); // Mark as not dead.
|
||||
add(id, entry);
|
||||
} catch(Exception e) {
|
||||
main.logger().warning("Failed to load Flora item: " + id + ": " + e.getMessage());
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class TerraWorld {
|
||||
this.provider = config.getProvider();
|
||||
profiler = new WorldProfiler(w);
|
||||
air = main.getWorldHandle().createBlockData("minecraft:air");
|
||||
main.getEventManager().callEvent(new TerraWorldLoadEvent(this));
|
||||
main.getEventManager().callEvent(new TerraWorldLoadEvent(this, c));
|
||||
safe = true;
|
||||
}
|
||||
|
||||
|
||||
+18
@@ -10,6 +10,7 @@ import com.dfsek.terra.api.util.world.PaletteUtil;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
||||
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
|
||||
import com.dfsek.terra.api.world.palette.Palette;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
@@ -21,9 +22,15 @@ import com.dfsek.terra.world.carving.NoiseCarver;
|
||||
import com.dfsek.terra.world.generation.math.SamplerCache;
|
||||
import com.dfsek.terra.world.generation.math.samplers.Sampler;
|
||||
import com.dfsek.terra.world.generation.math.samplers.Sampler2D;
|
||||
import com.dfsek.terra.world.population.CavePopulator;
|
||||
import com.dfsek.terra.world.population.OrePopulator;
|
||||
import com.dfsek.terra.world.population.StructurePopulator;
|
||||
import com.dfsek.terra.world.population.TreePopulator;
|
||||
import net.jafama.FastMath;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class DefaultChunkGenerator2D implements TerraChunkGenerator {
|
||||
@@ -31,12 +38,18 @@ public class DefaultChunkGenerator2D implements TerraChunkGenerator {
|
||||
private final TerraPlugin main;
|
||||
|
||||
private final Carver carver;
|
||||
private final List<TerraBlockPopulator> blockPopulators = new ArrayList<>();
|
||||
|
||||
private final SamplerCache cache;
|
||||
|
||||
public DefaultChunkGenerator2D(ConfigPack c, TerraPlugin main, SamplerCache cache) {
|
||||
this.configPack = c;
|
||||
this.main = main;
|
||||
blockPopulators.add(new CavePopulator(main));
|
||||
blockPopulators.add(new StructurePopulator(main));
|
||||
blockPopulators.add(new OrePopulator(main));
|
||||
blockPopulators.add(new TreePopulator(main));
|
||||
blockPopulators.add(new TreePopulator(main));
|
||||
carver = new NoiseCarver(new Range(0, 255), main.getWorldHandle().createBlockData("minecraft:air"), main);
|
||||
this.cache = cache;
|
||||
}
|
||||
@@ -125,4 +138,9 @@ public class DefaultChunkGenerator2D implements TerraChunkGenerator {
|
||||
public Sampler createSampler(int chunkX, int chunkZ, BiomeProvider provider, World world, int elevationSmooth) {
|
||||
return new Sampler2D(chunkX, chunkZ, provider, world, elevationSmooth);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TerraBlockPopulator> getPopulators() {
|
||||
return blockPopulators;
|
||||
}
|
||||
}
|
||||
|
||||
+21
-1
@@ -17,6 +17,7 @@ import com.dfsek.terra.api.util.world.PaletteUtil;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
||||
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
|
||||
import com.dfsek.terra.api.world.palette.Palette;
|
||||
import com.dfsek.terra.api.world.palette.SinglePalette;
|
||||
@@ -28,8 +29,15 @@ import com.dfsek.terra.world.TerraWorld;
|
||||
import com.dfsek.terra.world.carving.NoiseCarver;
|
||||
import com.dfsek.terra.world.generation.math.samplers.Sampler;
|
||||
import com.dfsek.terra.world.generation.math.samplers.Sampler3D;
|
||||
import com.dfsek.terra.world.population.CavePopulator;
|
||||
import com.dfsek.terra.world.population.FloraPopulator;
|
||||
import com.dfsek.terra.world.population.OrePopulator;
|
||||
import com.dfsek.terra.world.population.StructurePopulator;
|
||||
import com.dfsek.terra.world.population.TreePopulator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
@@ -38,14 +46,21 @@ public class DefaultChunkGenerator3D implements TerraChunkGenerator {
|
||||
private final TerraPlugin main;
|
||||
private final BlockType water;
|
||||
private final SinglePalette<BlockData> blank;
|
||||
private final List<TerraBlockPopulator> blockPopulators = new ArrayList<>();
|
||||
|
||||
private final Carver carver;
|
||||
|
||||
|
||||
|
||||
public DefaultChunkGenerator3D(ConfigPack c, TerraPlugin main) {
|
||||
this.configPack = c;
|
||||
this.main = main;
|
||||
|
||||
blockPopulators.add(new CavePopulator(main));
|
||||
blockPopulators.add(new StructurePopulator(main));
|
||||
blockPopulators.add(new OrePopulator(main));
|
||||
blockPopulators.add(new TreePopulator(main));
|
||||
blockPopulators.add(new FloraPopulator(main));
|
||||
|
||||
carver = new NoiseCarver(new Range(0, 255), main.getWorldHandle().createBlockData("minecraft:air"), main);
|
||||
water = main.getWorldHandle().createBlockData("minecraft:water").getBlockType();
|
||||
blank = new SinglePalette<>(main.getWorldHandle().createBlockData("minecraft:air"));
|
||||
@@ -236,4 +251,9 @@ public class DefaultChunkGenerator3D implements TerraChunkGenerator {
|
||||
public Sampler createSampler(int chunkX, int chunkZ, BiomeProvider provider, World world, int elevationSmooth) {
|
||||
return new Sampler3D(chunkX, chunkZ, provider, world, elevationSmooth);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TerraBlockPopulator> getPopulators() {
|
||||
return blockPopulators;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.dfsek.terra.api.platform.handle.WorldHandle;
|
||||
import com.dfsek.terra.api.platform.world.Chunk;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
import com.dfsek.terra.api.util.world.PopulationUtil;
|
||||
import com.dfsek.terra.api.world.generation.Chunkified;
|
||||
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
||||
import com.dfsek.terra.carving.UserDefinedCarver;
|
||||
import com.dfsek.terra.config.pack.WorldConfig;
|
||||
@@ -23,7 +24,7 @@ import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
public class CavePopulator implements TerraBlockPopulator {
|
||||
public class CavePopulator implements TerraBlockPopulator, Chunkified {
|
||||
private static final Map<BlockType, BlockData> shiftStorage = new HashMap<>(); // Persist BlockData created for shifts, to avoid re-calculating each time.
|
||||
private final TerraPlugin main;
|
||||
|
||||
@@ -41,6 +42,7 @@ public class CavePopulator implements TerraBlockPopulator {
|
||||
Random random = PopulationUtil.getRandom(chunk);
|
||||
if(!tw.isSafe()) return;
|
||||
WorldConfig config = tw.getConfig();
|
||||
if(config.getTemplate().disableCarvers()) return;
|
||||
|
||||
for(UserDefinedCarver c : config.getCarvers()) {
|
||||
CarverTemplate template = c.getConfig();
|
||||
|
||||
@@ -33,6 +33,8 @@ public class FloraPopulator implements TerraBlockPopulator {
|
||||
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
||||
TerraWorld tw = main.getWorld(world);
|
||||
try(ProfileFuture ignored = tw.getProfiler().measure("FloraTime")) {
|
||||
if(tw.getConfig().getTemplate().disableFlora()) return;
|
||||
|
||||
if(!tw.isSafe()) return;
|
||||
BiomeProvider provider = tw.getBiomeProvider();
|
||||
Map<Vector2, List<FloraLayer>> layers = new HashMap<>();
|
||||
|
||||
@@ -28,6 +28,8 @@ public class OrePopulator implements TerraBlockPopulator {
|
||||
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
||||
TerraWorld tw = main.getWorld(world);
|
||||
try(ProfileFuture ignored = tw.getProfiler().measure("OreTime")) {
|
||||
if(tw.getConfig().getTemplate().disableOres()) return;
|
||||
|
||||
if(!tw.isSafe()) return;
|
||||
for(int cx = -1; cx <= 1; cx++) {
|
||||
for(int cz = -1; cz <= 1; cz++) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.dfsek.terra.api.structures.structure.Rotation;
|
||||
import com.dfsek.terra.api.util.FastRandom;
|
||||
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.generation.Chunkified;
|
||||
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import com.dfsek.terra.config.pack.WorldConfig;
|
||||
@@ -20,7 +21,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class StructurePopulator implements TerraBlockPopulator {
|
||||
public class StructurePopulator implements TerraBlockPopulator, Chunkified {
|
||||
private final TerraPlugin main;
|
||||
|
||||
public StructurePopulator(TerraPlugin main) {
|
||||
@@ -32,6 +33,8 @@ public class StructurePopulator implements TerraBlockPopulator {
|
||||
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
||||
TerraWorld tw = main.getWorld(world);
|
||||
try(ProfileFuture ignored = tw.getProfiler().measure("StructureTime")) {
|
||||
if(tw.getConfig().getTemplate().disableStructures()) return;
|
||||
|
||||
int cx = (chunk.getX() << 4);
|
||||
int cz = (chunk.getZ() << 4);
|
||||
if(!tw.isSafe()) return;
|
||||
|
||||
@@ -33,6 +33,8 @@ public class TreePopulator implements TerraBlockPopulator {
|
||||
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
||||
TerraWorld tw = main.getWorld(world);
|
||||
try(ProfileFuture ignored = tw.getProfiler().measure("TreeTime")) {
|
||||
if(tw.getConfig().getTemplate().disableTrees()) return;
|
||||
|
||||
if(!tw.isSafe()) return;
|
||||
BiomeProvider provider = tw.getBiomeProvider();
|
||||
Random random = PopulationUtil.getRandom(chunk);
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# Boolean
|
||||
|
||||
A Boolean data type represents a logical boolean value, a value which can
|
||||
be either `true` or `false`.
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# Double
|
||||
|
||||
A Double type represents a double-precision floating point value.
|
||||
Essentially, a Double is a decimal number.
|
||||
|
||||
Examples:
|
||||
* `5`
|
||||
* `0.3`
|
||||
* `-12.5`
|
||||
* `100.3`
|
||||
@@ -0,0 +1,10 @@
|
||||
# Integer
|
||||
|
||||
An Integer data type represents a Java integer, a whole number with
|
||||
a minimum value of -2^31, and a maximum value of 2^31-1.
|
||||
|
||||
Examples:
|
||||
* `0`
|
||||
* `5`
|
||||
* `-20`
|
||||
* `123456`
|
||||
@@ -0,0 +1,17 @@
|
||||
# List
|
||||
|
||||
A List is an ordered collection of objects of a specific type.
|
||||
|
||||
Examples:
|
||||
* A List of [Strings](./String)s
|
||||
```yml
|
||||
- "thing"
|
||||
- "thing 2"
|
||||
- "thing 3"
|
||||
```
|
||||
* A List of [Integers](./Integer)
|
||||
```yml
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
```
|
||||
@@ -0,0 +1,17 @@
|
||||
# Map
|
||||
|
||||
A map is a data structure that "maps" one type (keys) to another (values).
|
||||
|
||||
Examples:
|
||||
* Mapping [Strings](./String) to [Strings](./String)
|
||||
```yml
|
||||
a: "thing"
|
||||
b: "thing 2"
|
||||
c: "thing 3"
|
||||
```
|
||||
* Mapping [Strings](./String) to [Integers](./Integer)
|
||||
```yml
|
||||
a: 1
|
||||
b: 2
|
||||
c: 3
|
||||
```
|
||||
@@ -0,0 +1,50 @@
|
||||
# ProbabilityCollection
|
||||
|
||||
A Probability Collection is a representation of a weighted pool.
|
||||
|
||||
Example:
|
||||
* `a` has a 1/5 (20%) chance, `b` and `c` both have a 2/5 (40%) chance.
|
||||
```yml
|
||||
- a: 1
|
||||
- b: 2
|
||||
- c: 2
|
||||
```
|
||||
|
||||
# Weighted Pool
|
||||
|
||||
A weighted pool is a way to randomly select one of many objects from a "pool" based on "weight".
|
||||
|
||||
## Pools
|
||||
A pool is a list of objects from which selections will be pulled.
|
||||
|
||||
## Weight
|
||||
Weight is the *relative* probability that any object will be selected from the pool. Each object in the pool has a
|
||||
weight, meaning the chance of object O being selected from pool P is `weight(O)/sum(weight(P_n))`.
|
||||
|
||||
## Example
|
||||
Here's an example pool:
|
||||
```yaml
|
||||
OPTION_A: 2
|
||||
OPTION_B: 1
|
||||
OPTION_C: 1
|
||||
```
|
||||
In this YAML-based pool, the keys are the objects, and the values are the weights. If we want the probability that
|
||||
`OPTION_A` will be selected, we sum all weights, and divide the weight of `OPTION_A` by that sum.
|
||||
`2 + 1 + 1 = 4`
|
||||
Therefore the probability that OPTION_A will be selected is `2/4`, or 50%.
|
||||
|
||||
## Manipulating weights to get a desired probability
|
||||
What if we want Option A to have a 60% chance of being selected? This requires manipulating the weights of all objects
|
||||
in the pool, since with B and C having a weight of 1, there is no integer weight that can be assigned to A that will
|
||||
give it a probability of 60%. What is usually done is that the weights are given a set sum that is easy to work with.
|
||||
Usually this is 100, since with a sum of 100, every object's weight is equal to the percent chance it will be selected.
|
||||
By applying this to the above example, we can produce this pool that has a 60% chance of A being selected:
|
||||
```yaml
|
||||
OPTION_A: 60
|
||||
OPTION_B: 20
|
||||
OPTION_C: 20
|
||||
```
|
||||
|
||||
## Use Cases
|
||||
Sometimes, it is undesirable to have an equal probability of all objects being selected, so you may want to "weight"
|
||||
some objects higher, so they are selected more often.
|
||||
@@ -0,0 +1,17 @@
|
||||
# Set
|
||||
|
||||
A Set is very similar to a [List](./List), except it is *unordered*.
|
||||
|
||||
Examples:
|
||||
* A Set of [Strings](./String).
|
||||
```yml
|
||||
- "thing"
|
||||
- "thing 2"
|
||||
- "thing 3"
|
||||
```
|
||||
* A Set of [Integers](./Integer).
|
||||
```yml
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
# String
|
||||
|
||||
A String data type represents a string of characters.
|
||||
|
||||
Examples:
|
||||
* `"Hello, World!"`
|
||||
* ```
|
||||
A
|
||||
Multi
|
||||
Line
|
||||
String
|
||||
```
|
||||
* `"Something"`
|
||||
@@ -39,6 +39,7 @@ import com.dfsek.terra.config.loaders.config.biome.templates.provider.SingleBiom
|
||||
import com.dfsek.terra.config.loaders.config.sampler.NoiseSamplerBuilderLoader;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import com.dfsek.terra.config.templates.AbstractableTemplate;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
import com.dfsek.terra.registry.config.BiomeRegistry;
|
||||
import com.dfsek.terra.registry.config.NoiseRegistry;
|
||||
import com.dfsek.terra.world.TerraWorld;
|
||||
@@ -306,6 +307,11 @@ public class DistributionTest {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeTemplate getTemplate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Generator getGenerator(World w) {
|
||||
return null;
|
||||
|
||||
@@ -15,12 +15,12 @@ configureCommon()
|
||||
|
||||
group = "com.dfsek.terra.bukkit"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url = uri("http://maven.enginehub.org/repo/") }
|
||||
maven { url = uri("https://repo.codemc.org/repository/maven-public") }
|
||||
maven { url = uri("https://papermc.io/repo/repository/maven-public/") }
|
||||
}
|
||||
val mcVersion = "1.16.5"
|
||||
val testDir = "target/server"
|
||||
val testMem = "3G"
|
||||
|
||||
val paperURL = "https://papermc.io/api/v1/paper/%version%/latest/download/"
|
||||
val purpurURL = "https://ci.pl3x.net/job/Purpur/lastSuccessfulBuild/artifact/final/purpurclip.jar"
|
||||
|
||||
dependencies {
|
||||
"shadedApi"(project(":common"))
|
||||
@@ -32,76 +32,159 @@ dependencies {
|
||||
|
||||
"compileOnly"("com.sk89q.worldedit:worldedit-bukkit:7.2.0-SNAPSHOT")
|
||||
|
||||
"shadedImplementation"("com.google.guava:guava:30.0-jre")
|
||||
"shadedApi"("com.google.guava:guava:30.0-jre")
|
||||
}
|
||||
|
||||
val testDir = "target/server/"
|
||||
val jvmFlags = listOf("-XX:+UseG1GC", "-XX:+ParallelRefProcEnabled", "-XX:MaxGCPauseMillis=200",
|
||||
"-XX:+UnlockExperimentalVMOptions", "-XX:+DisableExplicitGC", "-XX:+AlwaysPreTouch",
|
||||
"-XX:G1NewSizePercent=30", "-XX:G1MaxNewSizePercent=40", "-XX:G1HeapRegionSize=8M",
|
||||
"-XX:G1ReservePercent=20", "-XX:G1HeapWastePercent=5", "-XX:G1MixedGCCountTarget=4",
|
||||
"-XX:InitiatingHeapOccupancyPercent=15", "-XX:G1MixedGCLiveThresholdPercent=90",
|
||||
"-XX:G1RSetUpdatingPauseTimePercent=5", "-XX:SurvivorRatio=32", "-XX:+PerfDisableSharedMem",
|
||||
"-XX:MaxTenuringThreshold=1", "-Dusing.aikars.flags=https://mcflags.emc.gs",
|
||||
"-Daikars.new.flags=true", "-DIReallyKnowWhatIAmDoingISwear", "-javaagent:paperclip.jar")
|
||||
|
||||
val setupServer = tasks.create("setupServer") {
|
||||
dependsOn("shadowJar")
|
||||
doFirst {
|
||||
// clean
|
||||
file("${testDir}/").deleteRecursively()
|
||||
file("${testDir}/plugins").mkdirs()
|
||||
fun downloadPaperclip(url: String, dir: String) {
|
||||
val clip = URL(url.replace("%version%", mcVersion))
|
||||
val clipReadableByteChannel = Channels.newChannel(clip.openStream())
|
||||
val clipFile = file("$testDir/$dir/paperclip.jar")
|
||||
val clipOutputStream = clipFile.outputStream()
|
||||
val clipFileChannel = clipOutputStream.channel
|
||||
clipFileChannel.transferFrom(clipReadableByteChannel, 0, Long.MAX_VALUE)
|
||||
}
|
||||
|
||||
// Downloading latest paper jar.
|
||||
val paperUrl = URL("https://papermc.io/api/v1/paper/1.16.4/latest/download")
|
||||
val paperReadableByteChannel = Channels.newChannel(paperUrl.openStream())
|
||||
val paperFile = file("${testDir}/paper.jar")
|
||||
val paperFileOutputStream = paperFile.outputStream()
|
||||
val paperFileChannel = paperFileOutputStream.channel
|
||||
paperFileChannel.transferFrom(paperReadableByteChannel, 0, Long.MAX_VALUE)
|
||||
|
||||
// Cloning test setup.
|
||||
gitClone("https://github.com/PolyhedralDev/WorldGenTestServer")
|
||||
// Copying plugins
|
||||
Files.move(Paths.get("WorldGenTestServer/plugins"),
|
||||
Paths.get("$testDir/plugins"),
|
||||
StandardCopyOption.REPLACE_EXISTING)
|
||||
// Copying config
|
||||
val serverText = URL("https://raw.githubusercontent.com/PolyhedralDev/WorldGenTestServer/master/server.properties").readText()
|
||||
file("${testDir}/server.properties").writeText(serverText)
|
||||
val bukkitText = URL("https://raw.githubusercontent.com/PolyhedralDev/WorldGenTestServer/master/bukkit.yml").readText()
|
||||
file("${testDir}/bukkit.yml").writeText(bukkitText.replace("\${world}", "world").replace("\${gen}", "Terra:DEFAULT"))
|
||||
|
||||
File("${testDir}/eula.txt").writeText("eula=true")
|
||||
|
||||
// clean up
|
||||
file("WorldGenTestServer").deleteRecursively()
|
||||
fun copyTerra(dir: String) {
|
||||
file("$testDir/$dir").walk().forEach {
|
||||
if(it.name.startsWith("Terra-") && it.name.endsWith(".jar")) it.delete() // Delete old Terra jar(s)
|
||||
}
|
||||
copy {
|
||||
from("$buildDir/libs/Terra-bukkit-$version-shaded.jar")
|
||||
into("$testDir/$dir/plugins/")
|
||||
}
|
||||
}
|
||||
|
||||
val testWithPaper = task<JavaExec>(name = "testWithPaper") {
|
||||
fun installServer(dir: String) {
|
||||
// clean
|
||||
file("$testDir/$dir").deleteRecursively()
|
||||
file("$testDir/$dir/plugins").mkdirs()
|
||||
// Cloning test setup.
|
||||
gitClone("https://github.com/PolyhedralDev/WorldGenTestServer")
|
||||
// Copying plugins
|
||||
Files.move(Paths.get("WorldGenTestServer/plugins"),
|
||||
Paths.get("$testDir/$dir/plugins"),
|
||||
StandardCopyOption.REPLACE_EXISTING)
|
||||
// Copying config
|
||||
val serverText = URL("https://raw.githubusercontent.com/PolyhedralDev/WorldGenTestServer/master/server.properties").readText()
|
||||
file("$testDir/$dir/server.properties").writeText(serverText)
|
||||
val bukkitText = URL("https://raw.githubusercontent.com/PolyhedralDev/WorldGenTestServer/master/bukkit.yml").readText()
|
||||
file("$testDir/$dir/bukkit.yml").writeText(bukkitText.replace("\${world}", "world").replace("\${gen}", "Terra:DEFAULT"))
|
||||
|
||||
println("By proceeding, you are agreeing to the Minecraft EULA: https://account.mojang.com/documents/minecraft_eula")
|
||||
file("$testDir/$dir/eula.txt").writeText("eula=true")
|
||||
|
||||
// clean up
|
||||
file("WorldGenTestServer").deleteRecursively()
|
||||
}
|
||||
|
||||
fun deleteFolder(folder: File) {
|
||||
if(folder.exists()) folder.deleteRecursively()
|
||||
}
|
||||
|
||||
fun deleteFile(file: File) {
|
||||
if(file.exists()) file.delete()
|
||||
}
|
||||
|
||||
tasks.create("cleanWorlds") {
|
||||
group = "bukkit"
|
||||
doFirst {
|
||||
deleteFolder(file("$testDir/paper/world"))
|
||||
deleteFolder(file("$testDir/paper/world_nether"))
|
||||
deleteFolder(file("$testDir/paper/world_the_end"))
|
||||
|
||||
deleteFolder(file("$testDir/purpur/world"))
|
||||
deleteFolder(file("$testDir/purpur/world_nether"))
|
||||
deleteFolder(file("$testDir/purpur/world_the_end"))
|
||||
}
|
||||
}
|
||||
|
||||
tasks.create("updatePaper") {
|
||||
group = "bukkit"
|
||||
doFirst {
|
||||
deleteFile(file("$testDir/paper/paperclip.jar"))
|
||||
downloadPaperclip(paperURL, "paper")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.create("updatePurpur") {
|
||||
group = "bukkit"
|
||||
doFirst {
|
||||
deleteFile(file("$testDir/paper/paperclip.jar"))
|
||||
downloadPaperclip(purpurURL, "purpur")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.create("installPaper") {
|
||||
group = "bukkit"
|
||||
dependsOn("shadowJar")
|
||||
doFirst {
|
||||
installServer("paper")
|
||||
// Downloading latest paper jar.
|
||||
downloadPaperclip(paperURL, "paper")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.create("installPurpur") {
|
||||
group = "bukkit"
|
||||
dependsOn("shadowJar")
|
||||
doFirst {
|
||||
installServer("purpur")
|
||||
// Downloading latest paper jar.
|
||||
downloadPaperclip(purpurURL, "purpur")
|
||||
}
|
||||
}
|
||||
|
||||
task<JavaExec>(name = "runPaper") {
|
||||
group = "bukkit"
|
||||
standardInput = System.`in`
|
||||
dependsOn("shadowJar")
|
||||
// Copy Terra into dir
|
||||
doFirst {
|
||||
copy {
|
||||
from("${buildDir}/libs/Terra-bukkit-${version}-shaded.jar")
|
||||
into("${testDir}/plugins/")
|
||||
}
|
||||
copyTerra("paper")
|
||||
}
|
||||
|
||||
main = "io.papermc.paperclip.Paperclip"
|
||||
jvmArgs = listOf("-XX:+UseG1GC", "-XX:+ParallelRefProcEnabled", "-XX:MaxGCPauseMillis=200",
|
||||
"-XX:+UnlockExperimentalVMOptions", "-XX:+DisableExplicitGC", "-XX:+AlwaysPreTouch",
|
||||
"-XX:G1NewSizePercent=30", "-XX:G1MaxNewSizePercent=40", "-XX:G1HeapRegionSize=8M",
|
||||
"-XX:G1ReservePercent=20", "-XX:G1HeapWastePercent=5", "-XX:G1MixedGCCountTarget=4",
|
||||
"-XX:InitiatingHeapOccupancyPercent=15", "-XX:G1MixedGCLiveThresholdPercent=90",
|
||||
"-XX:G1RSetUpdatingPauseTimePercent=5", "-XX:SurvivorRatio=32", "-XX:+PerfDisableSharedMem",
|
||||
"-XX:MaxTenuringThreshold=1", "-Dusing.aikars.flags=https://mcflags.emc.gs",
|
||||
"-Daikars.new.flags=true", "-DIReallyKnowWhatIAmDoingISwear")
|
||||
maxHeapSize = "4G"
|
||||
minHeapSize = "4G"
|
||||
jvmArgs = jvmFlags
|
||||
maxHeapSize = testMem
|
||||
minHeapSize = testMem
|
||||
//args = listOf("nogui")
|
||||
workingDir = file("${testDir}/")
|
||||
classpath = files("${testDir}/paper.jar")
|
||||
workingDir = file("$testDir/paper")
|
||||
classpath = files("$testDir/paper/paperclip.jar")
|
||||
}
|
||||
|
||||
task<JavaExec>(name = "runPurpur") {
|
||||
group = "bukkit"
|
||||
standardInput = System.`in`
|
||||
dependsOn("shadowJar")
|
||||
// Copy Terra into dir
|
||||
doFirst {
|
||||
copyTerra("purpur")
|
||||
}
|
||||
|
||||
main = "io.papermc.paperclip.Paperclip"
|
||||
jvmArgs = jvmFlags
|
||||
maxHeapSize = testMem
|
||||
minHeapSize = testMem
|
||||
//args = listOf("nogui")
|
||||
workingDir = file("$testDir/purpur")
|
||||
classpath = files("$testDir/purpur/paperclip.jar")
|
||||
}
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
relocate("org.bstats.bukkit", "com.dfsek.terra.lib.bstats")
|
||||
relocate("io.papermc.lib", "com.dfsek.terra.lib.paperlib")
|
||||
relocate("com.google.common", "com.dfsek.terra.lib.google.common")
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create<MavenPublication>("mavenJava") {
|
||||
@@ -112,7 +195,6 @@ publishing {
|
||||
|
||||
repositories {
|
||||
val mavenUrl = "https://repo.codemc.io/repository/maven-releases/"
|
||||
val mavenSnapshotUrl = "https://repo.codemc.io/repository/maven-snapshots/"
|
||||
|
||||
maven(mavenUrl) {
|
||||
val mavenUsername: String? by project
|
||||
|
||||
+5
-10
@@ -23,6 +23,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@@ -40,20 +42,13 @@ public class BukkitChunkGeneratorWrapper extends ChunkGenerator implements Gener
|
||||
|
||||
private final TerraPlugin main;
|
||||
|
||||
private final List<TerraBlockPopulator> populators = new LinkedList<>();
|
||||
|
||||
private boolean needsLoad = true;
|
||||
|
||||
public BukkitChunkGeneratorWrapper(TerraChunkGenerator delegate) {
|
||||
this.delegate = delegate;
|
||||
this.main = delegate.getMain();
|
||||
popMan = new PopulationManager(main);
|
||||
popMan.attach(new OrePopulator(main));
|
||||
popMan.attach(new TreePopulator(main));
|
||||
popMan.attach(new FloraPopulator(main));
|
||||
populators.add(new CavePopulator(main));
|
||||
populators.add(new StructurePopulator(main));
|
||||
populators.add(popMan);
|
||||
this.popMan = new PopulationManager(delegate, main);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +91,7 @@ public class BukkitChunkGeneratorWrapper extends ChunkGenerator implements Gener
|
||||
|
||||
@Override
|
||||
public @NotNull List<BlockPopulator> getDefaultPopulators(@NotNull World world) {
|
||||
return populators.stream().map(BukkitPopulatorWrapper::new).collect(Collectors.toList());
|
||||
return Arrays.asList(popMan, new BukkitPopulatorWrapper(delegate));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package com.dfsek.terra.bukkit.generator;
|
||||
|
||||
import com.dfsek.terra.api.platform.world.Chunk;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
import com.dfsek.terra.api.platform.world.generator.BlockPopulator;
|
||||
import com.dfsek.terra.bukkit.world.BukkitChunk;
|
||||
import com.dfsek.terra.bukkit.world.BukkitWorld;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class BukkitPopulator implements BlockPopulator {
|
||||
private final org.bukkit.generator.BlockPopulator handle;
|
||||
|
||||
public BukkitPopulator(org.bukkit.generator.BlockPopulator handle) {
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populate(World world, Random random, Chunk chunk) {
|
||||
handle.populate(((BukkitWorld) world).getHandle(), random, ((BukkitChunk) chunk).getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.generator.BlockPopulator getHandle() {
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
+9
-3
@@ -1,6 +1,8 @@
|
||||
package com.dfsek.terra.bukkit.generator;
|
||||
|
||||
import com.dfsek.terra.api.world.generation.Chunkified;
|
||||
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
||||
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
|
||||
import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
@@ -10,14 +12,18 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.Random;
|
||||
|
||||
public class BukkitPopulatorWrapper extends BlockPopulator {
|
||||
private final TerraBlockPopulator delegate;
|
||||
private final TerraChunkGenerator delegate;
|
||||
|
||||
public BukkitPopulatorWrapper(TerraBlockPopulator delegate) {
|
||||
public BukkitPopulatorWrapper(TerraChunkGenerator delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk source) {
|
||||
delegate.populate(BukkitAdapter.adapt(world), BukkitAdapter.adapt(source));
|
||||
delegate.getPopulators().forEach(populator -> {
|
||||
if(populator instanceof Chunkified) {
|
||||
populator.populate(BukkitAdapter.adapt(world), BukkitAdapter.adapt(source));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,9 @@ public class TerraListener implements EventListener {
|
||||
public void injectTrees(ConfigPackPreLoadEvent event) {
|
||||
for(TreeType value : TreeType.values()) {
|
||||
try {
|
||||
event.getPack().getTreeRegistry().add(BukkitAdapter.TREE_TRANSFORMER.translate(value), new BukkitTree(value, main));
|
||||
String id = BukkitAdapter.TREE_TRANSFORMER.translate(value);
|
||||
event.getPack().getTreeRegistry().add(id, new BukkitTree(value, main));
|
||||
event.getPack().getTreeRegistry().get(id); // Platform trees should never be marked "dead"
|
||||
} catch(DuplicateEntryException ignore) { // If another addon has already registered trees, do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
+31
-30
@@ -4,54 +4,35 @@ import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.platform.world.Chunk;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
import com.dfsek.terra.api.util.FastRandom;
|
||||
import com.dfsek.terra.api.util.GlueList;
|
||||
import com.dfsek.terra.api.world.generation.Chunkified;
|
||||
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
||||
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
|
||||
import com.dfsek.terra.bukkit.TerraBukkitPlugin;
|
||||
import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
||||
import com.dfsek.terra.profiler.ProfileFuture;
|
||||
import com.dfsek.terra.profiler.WorldProfiler;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Cursed management class for the horrors of Bukkit population
|
||||
*/
|
||||
public class PopulationManager implements TerraBlockPopulator {
|
||||
private final List<TerraBlockPopulator> attachedPopulators = new GlueList<>();
|
||||
public class PopulationManager extends BlockPopulator {
|
||||
private final TerraChunkGenerator generator;
|
||||
private final HashSet<ChunkCoordinate> needsPop = new HashSet<>();
|
||||
private final TerraPlugin main;
|
||||
private WorldProfiler profiler;
|
||||
|
||||
public PopulationManager(TerraPlugin main) {
|
||||
public PopulationManager(TerraChunkGenerator generator, TerraPlugin main) {
|
||||
this.generator = generator;
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
public void attach(TerraBlockPopulator populator) {
|
||||
this.attachedPopulators.add(populator);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("try")
|
||||
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
||||
try(ProfileFuture ignored = measure()) {
|
||||
needsPop.add(new ChunkCoordinate(chunk));
|
||||
int x = chunk.getX();
|
||||
int z = chunk.getZ();
|
||||
if(((TerraBukkitPlugin) main).isEnabled()) {
|
||||
for(int xi = -1; xi <= 1; xi++) {
|
||||
for(int zi = -1; zi <= 1; zi++) {
|
||||
if(xi == 0 && zi == 0) continue;
|
||||
if(world.isChunkGenerated(xi + x, zi + z)) checkNeighbors(xi + x, zi + z, world);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ProfileFuture measure() {
|
||||
if(profiler != null) return profiler.measure("PopulationManagerTime");
|
||||
return null;
|
||||
@@ -87,10 +68,30 @@ public class PopulationManager implements TerraBlockPopulator {
|
||||
long zRand = (random.nextLong() / 2L << 1L) + 1L;
|
||||
random.setSeed((long) x * xRand + (long) z * zRand ^ w.getSeed());
|
||||
Chunk currentChunk = w.getChunkAt(x, z);
|
||||
for(TerraBlockPopulator r : attachedPopulators) {
|
||||
r.populate(w, currentChunk);
|
||||
}
|
||||
generator.getPopulators().forEach(populator -> {
|
||||
if(!(populator instanceof Chunkified)) {
|
||||
populator.populate(w, currentChunk);
|
||||
}
|
||||
});
|
||||
needsPop.remove(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populate(org.bukkit.@NotNull World world, @NotNull Random random, org.bukkit.@NotNull Chunk source) {
|
||||
try(ProfileFuture ignored = measure()) {
|
||||
Chunk chunk = BukkitAdapter.adapt(source);
|
||||
needsPop.add(new ChunkCoordinate(chunk));
|
||||
int x = chunk.getX();
|
||||
int z = chunk.getZ();
|
||||
if(((TerraBukkitPlugin) main).isEnabled()) {
|
||||
for(int xi = -1; xi <= 1; xi++) {
|
||||
for(int zi = -1; zi <= 1; zi++) {
|
||||
if(xi == 0 && zi == 0) continue;
|
||||
if(world.isChunkGenerated(xi + x, zi + z)) checkNeighbors(xi + x, zi + z, BukkitAdapter.adapt(world));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
import com.dfsek.terra.configureCommon
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import com.modrinth.minotaur.TaskModrinthUpload
|
||||
import net.fabricmc.loom.LoomGradleExtension
|
||||
import net.fabricmc.loom.task.RemapJarTask
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
id("fabric-loom").version("0.6-SNAPSHOT")
|
||||
id("com.modrinth.minotaur").version("1.1.0")
|
||||
}
|
||||
|
||||
configureCommon()
|
||||
@@ -19,8 +22,6 @@ group = "com.dfsek.terra.fabric"
|
||||
|
||||
dependencies {
|
||||
"shadedApi"(project(":common"))
|
||||
"shadedImplementation"("org.yaml:snakeyaml:1.27")
|
||||
"shadedImplementation"("com.googlecode.json-simple:json-simple:1.1.1")
|
||||
|
||||
"minecraft"("com.mojang:minecraft:1.16.5")
|
||||
"mappings"("net.fabricmc:yarn:1.16.5+build.5:v2")
|
||||
@@ -29,17 +30,13 @@ dependencies {
|
||||
"modImplementation"("net.fabricmc.fabric-api:fabric-api:0.31.0+1.16")
|
||||
}
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
relocate("org.json", "com.dfsek.terra.lib.json")
|
||||
relocate("org.yaml", "com.dfsek.terra.lib.yaml")
|
||||
}
|
||||
|
||||
|
||||
configure<LoomGradleExtension> {
|
||||
accessWidener("src/main/resources/terra.accesswidener")
|
||||
}
|
||||
|
||||
tasks.register<RemapJarTask>("remapShadedJar") {
|
||||
val remapped = tasks.register<RemapJarTask>("remapShadedJar") {
|
||||
group = "fabric"
|
||||
val shadowJar = tasks.getByName<ShadowJar>("shadowJar")
|
||||
dependsOn(shadowJar)
|
||||
input.set(shadowJar.archiveFile)
|
||||
@@ -47,3 +44,41 @@ tasks.register<RemapJarTask>("remapShadedJar") {
|
||||
addNestedDependencies.set(true)
|
||||
remapAccessWidener.set(true)
|
||||
}
|
||||
|
||||
|
||||
tasks.register<TaskModrinthUpload>("publishModrinth") {
|
||||
dependsOn("remapShadedJar")
|
||||
group = "fabric"
|
||||
token = System.getenv("MODRINTH_SECRET")
|
||||
projectId = "FIlZB9L0"
|
||||
versionNumber = project.version.toString()
|
||||
uploadFile = remapped.get().archiveFile.get().asFile
|
||||
releaseType = "beta"
|
||||
addGameVersion("1.16.4")
|
||||
addGameVersion("1.16.5")
|
||||
addLoader("fabric")
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create<MavenPublication>("mavenJava") {
|
||||
artifact(tasks["sourcesJar"])
|
||||
artifact(tasks["jar"])
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
val mavenUrl = "https://repo.codemc.io/repository/maven-releases/"
|
||||
|
||||
maven(mavenUrl) {
|
||||
val mavenUsername: String? by project
|
||||
val mavenPassword: String? by project
|
||||
if (mavenUsername != null && mavenPassword != null) {
|
||||
credentials {
|
||||
username = mavenUsername
|
||||
password = mavenPassword
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import com.dfsek.terra.config.builder.BiomeBuilder;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.config.lang.Language;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
import com.dfsek.terra.fabric.inventory.FabricItemHandle;
|
||||
import com.dfsek.terra.fabric.mixin.GeneratorTypeAccessor;
|
||||
import com.dfsek.terra.fabric.world.FabricAdapter;
|
||||
@@ -150,13 +151,18 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
||||
|
||||
@Override
|
||||
public TerraWorld getWorld(World world) {
|
||||
if(worldMap.size() > 1) System.out.println(worldMap.size());
|
||||
return worldMap.computeIfAbsent(world.getSeed(), w -> {
|
||||
logger.info("Loading world " + w);
|
||||
return new TerraWorld(world, ((FabricChunkGeneratorWrapper) ((FabricChunkGenerator) world.getGenerator()).getHandle()).getPack(), this);
|
||||
});
|
||||
}
|
||||
|
||||
public TerraWorld getWorld(long seed) {
|
||||
TerraWorld world = worldMap.get(seed);
|
||||
if(world == null) throw new IllegalArgumentException("No world exists with seed " + seed);
|
||||
return world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger logger() {
|
||||
return logger;
|
||||
@@ -242,9 +248,8 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
||||
}
|
||||
|
||||
private Biome createBiome(BiomeBuilder biome) {
|
||||
SpawnSettings.Builder spawnSettings = new SpawnSettings.Builder();
|
||||
DefaultBiomeFeatures.addFarmAnimals(spawnSettings);
|
||||
DefaultBiomeFeatures.addMonsters(spawnSettings, 95, 5, 100);
|
||||
BiomeTemplate template = biome.getTemplate();
|
||||
Map<String, Integer> colors = template.getColors();
|
||||
|
||||
Biome vanilla = ((FabricBiome) new ArrayList<>(biome.getVanillaBiomes().getContents()).get(0)).getHandle();
|
||||
|
||||
@@ -254,28 +259,37 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
||||
|
||||
|
||||
BiomeEffects.Builder effects = new BiomeEffects.Builder()
|
||||
.waterColor(vanilla.getEffects().waterColor)
|
||||
.waterFogColor(vanilla.getEffects().waterFogColor)
|
||||
.fogColor(vanilla.getEffects().fogColor)
|
||||
.skyColor(vanilla.getEffects().skyColor)
|
||||
.waterColor(colors.getOrDefault("water", vanilla.getEffects().waterColor))
|
||||
.waterFogColor(colors.getOrDefault("water-fog", vanilla.getEffects().waterFogColor))
|
||||
.fogColor(colors.getOrDefault("fog", vanilla.getEffects().fogColor))
|
||||
.skyColor(colors.getOrDefault("sky", vanilla.getEffects().skyColor))
|
||||
.grassColorModifier(vanilla.getEffects().grassColorModifier);
|
||||
vanilla.getEffects().grassColor.ifPresent(effects::grassColor);
|
||||
vanilla.getEffects().foliageColor.ifPresent(effects::foliageColor);
|
||||
|
||||
return (new Biome.Builder())
|
||||
if(colors.containsKey("grass")) {
|
||||
effects.grassColor(colors.get("grass"));
|
||||
} else {
|
||||
vanilla.getEffects().grassColor.ifPresent(effects::grassColor);
|
||||
}
|
||||
vanilla.getEffects().foliageColor.ifPresent(effects::foliageColor);
|
||||
if(colors.containsKey("foliage")) {
|
||||
effects.foliageColor(colors.get("foliage"));
|
||||
} else {
|
||||
vanilla.getEffects().foliageColor.ifPresent(effects::foliageColor);
|
||||
}
|
||||
|
||||
return new Biome.Builder()
|
||||
.precipitation(vanilla.getPrecipitation())
|
||||
.category(vanilla.getCategory())
|
||||
.depth(vanilla.getDepth())
|
||||
.scale(vanilla.getScale())
|
||||
.temperature(vanilla.getTemperature())
|
||||
.downfall(vanilla.getDownfall())
|
||||
.effects(vanilla.getEffects()) // TODO: configurable
|
||||
.spawnSettings(spawnSettings.build())
|
||||
.effects(effects.build())
|
||||
.spawnSettings(vanilla.getSpawnSettings())
|
||||
.generationSettings(generationSettings.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
instance = this;
|
||||
@@ -327,10 +341,8 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
||||
|
||||
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> {
|
||||
int max = manager.getMaxArgumentDepth();
|
||||
System.out.println("MAX:" + max);
|
||||
RequiredArgumentBuilder<ServerCommandSource, String> arg = argument("arg" + (max - 1), StringArgumentType.word());
|
||||
for(int i = 0; i < max; i++) {
|
||||
System.out.println("arg " + i);
|
||||
RequiredArgumentBuilder<ServerCommandSource, String> next = argument("arg" + (max - i - 1), StringArgumentType.word());
|
||||
|
||||
arg = next.then(assemble(arg, manager));
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.dfsek.terra.api.platform.block.state.BlockState;
|
||||
import com.dfsek.terra.fabric.world.FabricAdapter;
|
||||
import com.dfsek.terra.fabric.world.block.state.FabricBlockState;
|
||||
import com.dfsek.terra.fabric.world.handles.world.FabricWorldAccess;
|
||||
import net.minecraft.block.FluidBlock;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
|
||||
@@ -21,7 +22,10 @@ public class FabricBlock implements Block {
|
||||
|
||||
@Override
|
||||
public void setBlockData(BlockData data, boolean physics) {
|
||||
delegate.worldAccess.setBlockState(delegate.position, ((FabricBlockData) data).getHandle(), physics ? 3 : 1042, 0);
|
||||
delegate.worldAccess.setBlockState(delegate.position, ((FabricBlockData) data).getHandle(), physics ? 3 : 1042);
|
||||
if(physics && ((FabricBlockData) data).getHandle().getBlock() instanceof FluidBlock) {
|
||||
delegate.worldAccess.getFluidTickScheduler().schedule(delegate.position, ((FluidBlock) ((FabricBlockData) data).getHandle().getBlock()).getFluidState(((FabricBlockData) data).getHandle()).getFluid(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-5
@@ -27,11 +27,7 @@ public class PopulatorFeature extends Feature<DefaultFeatureConfig> {
|
||||
FabricChunkGeneratorWrapper gen = (FabricChunkGeneratorWrapper) chunkGenerator;
|
||||
FabricChunkWorldAccess chunk = new FabricChunkWorldAccess(world, pos.getX() >> 4, pos.getZ() >> 4);
|
||||
FabricWorld world1 = new FabricWorld(world.toServerWorld(), new FabricChunkGenerator(chunkGenerator));
|
||||
gen.getCavePopulator().populate(new FabricWorldAccess(world), chunk);
|
||||
gen.getStructurePopulator().populate(new FabricWorldAccess(world), chunk);
|
||||
gen.getOrePopulator().populate(world1, chunk);
|
||||
gen.getTreePopulator().populate(world1, chunk);
|
||||
gen.getFloraPopulator().populate(world1, chunk);
|
||||
gen.getHandle().getPopulators().forEach(populator -> populator.populate(world1, chunk));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+17
-27
@@ -7,7 +7,9 @@ import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import com.dfsek.terra.fabric.TerraFabricPlugin;
|
||||
import com.dfsek.terra.fabric.world.TerraBiomeSource;
|
||||
import com.dfsek.terra.fabric.world.handles.world.FabricSeededWorldAccess;
|
||||
import com.dfsek.terra.world.TerraWorld;
|
||||
import com.dfsek.terra.world.generation.generators.DefaultChunkGenerator3D;
|
||||
import com.dfsek.terra.world.generation.math.samplers.Sampler;
|
||||
import com.dfsek.terra.world.population.CavePopulator;
|
||||
import com.dfsek.terra.world.population.FloraPopulator;
|
||||
import com.dfsek.terra.world.population.OrePopulator;
|
||||
@@ -15,6 +17,7 @@ import com.dfsek.terra.world.population.StructurePopulator;
|
||||
import com.dfsek.terra.world.population.TreePopulator;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.jafama.FastMath;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.structure.StructureManager;
|
||||
@@ -50,32 +53,6 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
|
||||
return pack;
|
||||
}
|
||||
|
||||
private final FloraPopulator floraPopulator = new FloraPopulator(TerraFabricPlugin.getInstance());
|
||||
private final OrePopulator orePopulator = new OrePopulator(TerraFabricPlugin.getInstance());
|
||||
private final TreePopulator treePopulator = new TreePopulator(TerraFabricPlugin.getInstance());
|
||||
private final StructurePopulator structurePopulator = new StructurePopulator(TerraFabricPlugin.getInstance());
|
||||
private final CavePopulator cavePopulator = new CavePopulator(TerraFabricPlugin.getInstance());
|
||||
|
||||
public TreePopulator getTreePopulator() {
|
||||
return treePopulator;
|
||||
}
|
||||
|
||||
public OrePopulator getOrePopulator() {
|
||||
return orePopulator;
|
||||
}
|
||||
|
||||
public FloraPopulator getFloraPopulator() {
|
||||
return floraPopulator;
|
||||
}
|
||||
|
||||
public StructurePopulator getStructurePopulator() {
|
||||
return structurePopulator;
|
||||
}
|
||||
|
||||
public CavePopulator getCavePopulator() {
|
||||
return cavePopulator;
|
||||
}
|
||||
|
||||
public FabricChunkGeneratorWrapper(TerraBiomeSource biomeSource, long seed, ConfigPack configPack) {
|
||||
super(biomeSource, new StructuresConfig(false));
|
||||
this.pack = configPack;
|
||||
@@ -124,6 +101,8 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isStrongholdStartingChunk(ChunkPos chunkPos) {
|
||||
return false;
|
||||
@@ -131,7 +110,18 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
|
||||
|
||||
@Override
|
||||
public int getHeight(int x, int z, Heightmap.Type heightmapType) {
|
||||
return 0;
|
||||
TerraWorld world = TerraFabricPlugin.getInstance().getWorld(seed);
|
||||
Sampler sampler = world.getConfig().getSamplerCache().getChunk(FastMath.floorDiv(x, 16), FastMath.floorDiv(z, 16));
|
||||
int cx = FastMath.floorMod(x, 16);
|
||||
int cz = FastMath.floorMod(z, 16);
|
||||
|
||||
int height = world.getWorld().getMaxHeight();
|
||||
|
||||
while (height >= 0 && sampler.sample(cx, height - 1, cz) < 0) {
|
||||
height--;
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user