mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-05-20 16:50:28 +00:00
Compare commits
54 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 | |||
| 28222c074e | |||
| 1b70766a17 | |||
| cda2d4688c | |||
| 5028582198 | |||
| 5458564cfa | |||
| 7f11373f75 |
+2
-2
@@ -1,6 +1,6 @@
|
||||
import com.dfsek.terra.getGitHash
|
||||
|
||||
val versionObj = Version("5", "0", "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;
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,6 @@ public interface BlockType extends Handle {
|
||||
BlockData getDefaultData();
|
||||
|
||||
boolean isSolid();
|
||||
|
||||
boolean isWater();
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.api.world.tree;
|
||||
package com.dfsek.terra.api.platform.world;
|
||||
|
||||
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
@@ -21,6 +21,7 @@ import com.dfsek.terra.api.structures.script.builders.RecursionsFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.builders.SetMarkFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.builders.StateFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.builders.StructureFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.builders.UnaryBooleanFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.builders.UnaryNumberFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.builders.UnaryStringFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.builders.ZeroArgFunctionBuilder;
|
||||
@@ -58,7 +59,8 @@ public class StructureScript {
|
||||
|
||||
functionRegistry.forEach(parser::registerFunction); // Register registry functions.
|
||||
|
||||
parser.registerFunction("block", new BlockFunctionBuilder(main))
|
||||
parser.registerFunction("block", new BlockFunctionBuilder(main, false))
|
||||
.registerFunction("dynamicBlock", new BlockFunctionBuilder(main, true))
|
||||
.registerFunction("check", new CheckFunctionBuilder(main))
|
||||
.registerFunction("structure", new StructureFunctionBuilder(registry, main))
|
||||
.registerFunction("randomInt", new RandomFunctionBuilder())
|
||||
@@ -66,11 +68,12 @@ 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())
|
||||
.registerFunction("state", new StateFunctionBuilder(main))
|
||||
.registerFunction("setWaterlog", new UnaryBooleanFunctionBuilder((waterlog, args) -> args.setWaterlog(waterlog)))
|
||||
.registerFunction("originX", new ZeroArgFunctionBuilder<Number>(arguments -> arguments.getBuffer().getOrigin().getX(), Returnable.ReturnType.NUMBER))
|
||||
.registerFunction("originY", new ZeroArgFunctionBuilder<Number>(arguments -> arguments.getBuffer().getOrigin().getY(), Returnable.ReturnType.NUMBER))
|
||||
.registerFunction("originZ", new ZeroArgFunctionBuilder<Number>(arguments -> arguments.getBuffer().getOrigin().getZ(), Returnable.ReturnType.NUMBER))
|
||||
@@ -146,7 +149,7 @@ public class StructureScript {
|
||||
|
||||
private boolean applyBlock(TerraImplementationArguments arguments) {
|
||||
try {
|
||||
return !block.apply(arguments).getLevel().equals(Block.ReturnLevel.FAIL);
|
||||
return block.apply(arguments).getLevel() != Block.ReturnLevel.FAIL;
|
||||
} catch(RuntimeException e) {
|
||||
main.logger().severe("Failed to generate structure at " + arguments.getBuffer().getOrigin() + ": " + e.getMessage());
|
||||
main.getDebugLogger().stack(e);
|
||||
|
||||
+9
@@ -11,6 +11,7 @@ public class TerraImplementationArguments implements ImplementationArguments {
|
||||
private final Rotation rotation;
|
||||
private final Random random;
|
||||
private final int recursions;
|
||||
private boolean waterlog = false;
|
||||
|
||||
public TerraImplementationArguments(Buffer buffer, Rotation rotation, Random random, int recursions) {
|
||||
this.buffer = buffer;
|
||||
@@ -34,4 +35,12 @@ public class TerraImplementationArguments implements ImplementationArguments {
|
||||
public Rotation getRotation() {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
public boolean isWaterlog() {
|
||||
return waterlog;
|
||||
}
|
||||
|
||||
public void setWaterlog(boolean waterlog) {
|
||||
this.waterlog = waterlog;
|
||||
}
|
||||
}
|
||||
|
||||
+9
-3
@@ -5,24 +5,30 @@ import com.dfsek.terra.api.structures.parser.exceptions.ParseException;
|
||||
import com.dfsek.terra.api.structures.parser.lang.Returnable;
|
||||
import com.dfsek.terra.api.structures.parser.lang.constants.BooleanConstant;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.functions.AbstractBlockFunction;
|
||||
import com.dfsek.terra.api.structures.script.functions.BlockFunction;
|
||||
import com.dfsek.terra.api.structures.script.functions.DynamicBlockFunction;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BlockFunctionBuilder implements FunctionBuilder<BlockFunction> {
|
||||
public class BlockFunctionBuilder implements FunctionBuilder<AbstractBlockFunction> {
|
||||
private final TerraPlugin main;
|
||||
private final boolean dynamic;
|
||||
|
||||
public BlockFunctionBuilder(TerraPlugin main) {
|
||||
public BlockFunctionBuilder(TerraPlugin main, boolean dynamic) {
|
||||
this.main = main;
|
||||
this.dynamic = dynamic;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public BlockFunction build(List<Returnable<?>> argumentList, Position position) throws ParseException {
|
||||
public AbstractBlockFunction build(List<Returnable<?>> argumentList, Position position) throws ParseException {
|
||||
if(argumentList.size() < 4) throw new ParseException("Expected data", position);
|
||||
Returnable<Boolean> booleanReturnable = new BooleanConstant(true, position);
|
||||
if(argumentList.size() == 5) booleanReturnable = (Returnable<Boolean>) argumentList.get(4);
|
||||
if(dynamic)
|
||||
return new DynamicBlockFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), booleanReturnable, main, position);
|
||||
return new BlockFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), booleanReturnable, main, position);
|
||||
}
|
||||
|
||||
|
||||
+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
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package com.dfsek.terra.api.structures.script.builders;
|
||||
|
||||
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.functions.FunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
|
||||
import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class UnaryBooleanFunctionBuilder implements FunctionBuilder<Function<Void>> {
|
||||
|
||||
private final BiConsumer<Boolean, TerraImplementationArguments> function;
|
||||
|
||||
public UnaryBooleanFunctionBuilder(BiConsumer<Boolean, TerraImplementationArguments> function) {
|
||||
this.function = function;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function<Void> build(List<Returnable<?>> argumentList, Position position) {
|
||||
return new Function<Void>() {
|
||||
@Override
|
||||
public ReturnType returnType() {
|
||||
return ReturnType.VOID;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
|
||||
function.accept(((Returnable<Boolean>) argumentList.get(0)).apply(implementationArguments, variableMap), (TerraImplementationArguments) implementationArguments);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int argNumber() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Returnable.ReturnType getArgument(int position) {
|
||||
if(position == 0) return Returnable.ReturnType.BOOLEAN;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package com.dfsek.terra.api.structures.script.functions;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.vector.Vector2;
|
||||
import com.dfsek.terra.api.math.vector.Vector3;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
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.TerraImplementationArguments;
|
||||
import com.dfsek.terra.api.structures.structure.RotationUtil;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedBlock;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class AbstractBlockFunction implements Function<Void> {
|
||||
protected final Returnable<Number> x, y, z;
|
||||
protected final Returnable<String> blockData;
|
||||
protected final TerraPlugin main;
|
||||
private final Returnable<Boolean> overwrite;
|
||||
private final Position position;
|
||||
|
||||
protected AbstractBlockFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> blockData, Returnable<Boolean> overwrite, TerraPlugin main, Position position) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.blockData = blockData;
|
||||
this.overwrite = overwrite;
|
||||
this.main = main;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
void setBlock(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap, TerraImplementationArguments arguments, BlockData rot) {
|
||||
Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
|
||||
|
||||
RotationUtil.rotateVector(xz, arguments.getRotation());
|
||||
|
||||
RotationUtil.rotateBlockData(rot, arguments.getRotation().inverse());
|
||||
arguments.getBuffer().addItem(new BufferedBlock(rot, overwrite.apply(implementationArguments, variableMap), main, arguments.isWaterlog()), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).doubleValue(), FastMath.roundToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnType returnType() {
|
||||
return ReturnType.VOID;
|
||||
}
|
||||
}
|
||||
+4
-35
@@ -1,67 +1,36 @@
|
||||
package com.dfsek.terra.api.structures.script.functions;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.vector.Vector2;
|
||||
import com.dfsek.terra.api.math.vector.Vector3;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.structures.parser.exceptions.ParseException;
|
||||
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.constants.ConstantExpression;
|
||||
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.TerraImplementationArguments;
|
||||
import com.dfsek.terra.api.structures.structure.RotationUtil;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedBlock;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class BlockFunction implements Function<Void> {
|
||||
public class BlockFunction extends AbstractBlockFunction {
|
||||
private final BlockData data;
|
||||
private final Returnable<Number> x, y, z;
|
||||
private final Position position;
|
||||
private final Returnable<Boolean> overwrite;
|
||||
private final TerraPlugin main;
|
||||
|
||||
public BlockFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, Returnable<Boolean> overwrite, TerraPlugin main, Position position) throws ParseException {
|
||||
this.position = position;
|
||||
this.main = main;
|
||||
if(!(data instanceof ConstantExpression)) throw new ParseException("Block data must be constant", data.getPosition());
|
||||
super(x, y, z, data, overwrite, main, position);
|
||||
|
||||
if(!(data instanceof ConstantExpression)) throw new ParseException("Block data must be constant", data.getPosition());
|
||||
try {
|
||||
this.data = main.getWorldHandle().createBlockData(((ConstantExpression<String>) data).getConstant());
|
||||
} catch(IllegalArgumentException e) {
|
||||
throw new ParseException("Could not parse block data", data.getPosition(), e);
|
||||
}
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.overwrite = overwrite;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
|
||||
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
|
||||
BlockData rot = data.clone();
|
||||
|
||||
Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
|
||||
|
||||
RotationUtil.rotateVector(xz, arguments.getRotation());
|
||||
|
||||
RotationUtil.rotateBlockData(rot, arguments.getRotation().inverse());
|
||||
arguments.getBuffer().addItem(new BufferedBlock(rot, overwrite.apply(implementationArguments, variableMap), main), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).doubleValue(), FastMath.roundToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld()));
|
||||
setBlock(implementationArguments, variableMap, arguments, rot);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnType returnType() {
|
||||
return ReturnType.VOID;
|
||||
}
|
||||
}
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.dfsek.terra.api.structures.script.functions;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
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.variables.Variable;
|
||||
import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class DynamicBlockFunction extends AbstractBlockFunction {
|
||||
private final Map<String, BlockData> data = new HashMap<>();
|
||||
private final Position position;
|
||||
|
||||
|
||||
public DynamicBlockFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, Returnable<Boolean> overwrite, TerraPlugin main, Position position) {
|
||||
super(x, y, z, data, overwrite, main, position);
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
|
||||
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
|
||||
BlockData rot = data.computeIfAbsent(blockData.apply(implementationArguments, variableMap), main.getWorldHandle()::createBlockData).clone();
|
||||
setBlock(implementationArguments, variableMap, arguments, rot);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+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;
|
||||
}
|
||||
|
||||
|
||||
+9
-2
@@ -4,23 +4,30 @@ import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.block.Block;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.platform.block.data.Waterlogged;
|
||||
|
||||
public class BufferedBlock implements BufferedItem {
|
||||
private final BlockData data;
|
||||
private final boolean overwrite;
|
||||
private final TerraPlugin main;
|
||||
private final boolean waterlog;
|
||||
|
||||
public BufferedBlock(BlockData data, boolean overwrite, TerraPlugin main) {
|
||||
public BufferedBlock(BlockData data, boolean overwrite, TerraPlugin main, boolean waterlog) {
|
||||
this.data = data;
|
||||
this.overwrite = overwrite;
|
||||
this.main = main;
|
||||
this.waterlog = waterlog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paste(Location origin) {
|
||||
Block block = origin.getBlock();
|
||||
try {
|
||||
if(overwrite || block.isEmpty()) block.setBlockData(data, false);
|
||||
if(overwrite || block.isEmpty()) {
|
||||
if(waterlog && data instanceof Waterlogged && block.getBlockData().getBlockType().isWater())
|
||||
((Waterlogged) data).setWaterlogged(true);
|
||||
block.setBlockData(data, false);
|
||||
}
|
||||
} catch(RuntimeException e) {
|
||||
main.logger().severe("Failed to place block at location " + origin + ": " + e.getMessage());
|
||||
main.getDebugLogger().stack(e);
|
||||
|
||||
+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();
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.dfsek.terra.api.world.tree.fractal;
|
||||
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.entity.Entity;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
||||
public class EntitySpawnHolder {
|
||||
private final Location l;
|
||||
private final Class<? extends Entity> e;
|
||||
private final Consumer<Entity> c;
|
||||
|
||||
public EntitySpawnHolder(Location l, Class<? extends Entity> e, Consumer<Entity> c) {
|
||||
this.l = l;
|
||||
this.e = e;
|
||||
this.c = c;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Class getEntity() {
|
||||
return e;
|
||||
}
|
||||
|
||||
public Consumer<Entity> getConsumer() {
|
||||
return c;
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return l;
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package com.dfsek.terra.api.world.tree.fractal;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.platform.entity.Entity;
|
||||
import com.dfsek.terra.api.platform.entity.EntityType;
|
||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
||||
public abstract class FractalTree {
|
||||
protected final TerraPlugin main;
|
||||
|
||||
public abstract MaterialSet getSpawnable();
|
||||
|
||||
/**
|
||||
* Instantiates a TreeGrower at an origin location.
|
||||
*/
|
||||
public FractalTree(TerraPlugin plugin) {
|
||||
this.main = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a block in the tree's storage map to a material.
|
||||
*
|
||||
* @param l - The location to set.
|
||||
* @param m - The material to which it will be set.
|
||||
*/
|
||||
public void setBlock(Location l, BlockData m) {
|
||||
l.getBlock().setBlockData(m, false);
|
||||
}
|
||||
|
||||
public TerraPlugin getMain() {
|
||||
return main;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grows the tree in memory. Intended to be invoked from an async thread.
|
||||
*/
|
||||
public abstract void grow(Location origin, Random random);
|
||||
|
||||
public void spawnEntity(Location spawn, EntityType type, Consumer<Entity> consumer) {
|
||||
consumer.accept(spawn.getWorld().spawnEntity(spawn, type));
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package com.dfsek.terra.api.world.tree.fractal;
|
||||
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.math.vector.Vector3;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.util.collections.ProbabilityCollection;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class TreeGeometry {
|
||||
private final FractalTree tree;
|
||||
|
||||
public TreeGeometry(FractalTree tree) {
|
||||
this.tree = tree;
|
||||
}
|
||||
|
||||
public static Vector3 getPerpendicular(Vector3 v) {
|
||||
return v.getZ() < v.getX() ? new Vector3(v.getY(), -v.getX(), 0) : new Vector3(0, -v.getZ(), v.getY());
|
||||
}
|
||||
|
||||
public FractalTree getTree() {
|
||||
return tree;
|
||||
}
|
||||
|
||||
public void generateSphere(Location l, BlockData m, int radius, boolean overwrite, Random r) {
|
||||
generateSphere(l, new ProbabilityCollection<BlockData>().add(m, 1), radius, overwrite, r);
|
||||
}
|
||||
|
||||
public void generateCylinder(Location l, BlockData m, int radius, int height, boolean overwrite, Random r) {
|
||||
generateCylinder(l, new ProbabilityCollection<BlockData>().add(m, 1), radius, height, overwrite, r);
|
||||
}
|
||||
|
||||
public void generateSphere(Location l, ProbabilityCollection<BlockData> m, int radius, boolean overwrite, Random r) {
|
||||
for(int x = -radius; x <= radius; x++) {
|
||||
for(int y = -radius; y <= radius; y++) {
|
||||
for(int z = -radius; z <= radius; z++) {
|
||||
Vector3 position = l.toVector().clone().add(new Vector3(x, y, z));
|
||||
if(l.toVector().distance(position) <= radius + 0.5 && (overwrite || position.toLocation(l.getWorld()).getBlock().isEmpty()))
|
||||
tree.setBlock(position.toLocation(l.getWorld()), m.get(r));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void generateSponge(Location l, ProbabilityCollection<BlockData> m, int radius, boolean overwrite, int sponginess, Random r) {
|
||||
for(int x = -radius; x <= radius; x++) {
|
||||
for(int y = -radius; y <= radius; y++) {
|
||||
for(int z = -radius; z <= radius; z++) {
|
||||
Vector3 position = l.toVector().clone().add(new Vector3(x, y, z));
|
||||
if(r.nextInt(100) < sponginess && l.toVector().distance(position) <= radius + 0.5 && (overwrite || position.toLocation(l.getWorld()).getBlock().isEmpty()))
|
||||
tree.setBlock(position.toLocation(l.getWorld()), m.get(r));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void generateCylinder(Location l, ProbabilityCollection<BlockData> m, int radius, int height, boolean overwrite, Random r) {
|
||||
for(int x = -radius; x <= radius; x++) {
|
||||
for(int y = 0; y <= height; y++) {
|
||||
for(int z = -radius; z <= radius; z++) {
|
||||
Vector3 position = l.toVector().clone().add(new Vector3(x, 0, z));
|
||||
if(l.toVector().distance(position) <= radius + 0.5 && (overwrite || position.toLocation(l.getWorld()).getBlock().isEmpty()))
|
||||
tree.setBlock(position.toLocation(l.getWorld()), m.get(r));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.dfsek.terra.api.world.tree.fractal.trees;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
||||
import com.dfsek.terra.api.world.tree.fractal.FractalTree;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class Cactus extends FractalTree {
|
||||
@Override
|
||||
public MaterialSet getSpawnable() {
|
||||
return MaterialSet.get(main.getWorldHandle().createBlockData("minecraft:sand"),
|
||||
main.getWorldHandle().createBlockData("minecraft:red_sand"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Instantiates a TreeGrower at an origin location.
|
||||
*/
|
||||
public Cactus(TerraPlugin main) {
|
||||
super(main);
|
||||
}
|
||||
|
||||
/**
|
||||
* Grows the tree in memory. Intended to be invoked from an async thread.
|
||||
*/
|
||||
@Override
|
||||
public void grow(Location origin, Random random) {
|
||||
BlockData cactus = getMain().getWorldHandle().createBlockData("minecraft:cactus");
|
||||
int h = random.nextInt(4) + 1;
|
||||
for(int i = 0; i < h; i++) setBlock(origin.clone().add(0, i, 0), cactus);
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package com.dfsek.terra.api.world.tree.fractal.trees;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.math.vector.Vector3;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.platform.handle.WorldHandle;
|
||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
||||
import com.dfsek.terra.api.util.collections.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.tree.fractal.FractalTree;
|
||||
import com.dfsek.terra.api.world.tree.fractal.TreeGeometry;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
public class IceSpike extends FractalTree {
|
||||
private final TreeGeometry geo;
|
||||
private final ProbabilityCollection<BlockData> ice;
|
||||
|
||||
@Override
|
||||
public MaterialSet getSpawnable() {
|
||||
return MaterialSet.get(main.getWorldHandle().createBlockData("minecraft:stone"),
|
||||
main.getWorldHandle().createBlockData("minecraft:gravel"),
|
||||
main.getWorldHandle().createBlockData("minecraft:snow_block"),
|
||||
main.getWorldHandle().createBlockData("minecraft:grass_block"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a TreeGrower at an origin location.
|
||||
*/
|
||||
public IceSpike(TerraPlugin main) {
|
||||
super(main);
|
||||
geo = new TreeGeometry(this);
|
||||
WorldHandle handle = main.getWorldHandle();
|
||||
ice = new ProbabilityCollection<BlockData>().add(handle.createBlockData("minecraft:packed_ice"), 95).add(handle.createBlockData("minecraft:blue_ice"), 5);
|
||||
}
|
||||
|
||||
private double getOffset(Random r) {
|
||||
return (r.nextDouble() - 0.5D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Grows the tree in memory. Intended to be invoked from an async thread.
|
||||
*/
|
||||
@Override
|
||||
public void grow(Location origin, Random random) {
|
||||
Vector3 direction = new Vector3(getOffset(random), 0, getOffset(random));
|
||||
Location l1 = origin.clone();
|
||||
int h = random.nextInt(16) + 8;
|
||||
for(int i = 0; i < h; i++) {
|
||||
geo.generateSponge(l1.clone().add(0, i, 0).add(direction.clone().multiply(i)), ice, (int) ((1 - ((double) i / h)) * 2 + 1), true, 80, random);
|
||||
}
|
||||
for(int i = 0; i < h / 3; i++) {
|
||||
setBlock(l1.clone().add(0, h + i, 0).add(direction.clone().multiply(h + i)), ice.get(random));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package com.dfsek.terra.api.world.tree.fractal.trees;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.math.vector.Vector3;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
||||
import com.dfsek.terra.api.world.tree.fractal.FractalTree;
|
||||
import com.dfsek.terra.api.world.tree.fractal.TreeGeometry;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
public class OakTree extends FractalTree {
|
||||
private final TreeGeometry geo;
|
||||
|
||||
@Override
|
||||
public MaterialSet getSpawnable() {
|
||||
return MaterialSet.get(main.getWorldHandle().createBlockData("minecraft:podzol"),
|
||||
main.getWorldHandle().createBlockData("minecraft:grass_block"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a TreeGrower at an origin location.
|
||||
*/
|
||||
public OakTree(TerraPlugin main) {
|
||||
super(main);
|
||||
geo = new TreeGeometry(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Grows the tree in memory. Intended to be invoked from an async thread.
|
||||
*/
|
||||
@Override
|
||||
public void grow(Location origin, Random random) {
|
||||
growBranch(origin.clone(), new Vector3(random.nextInt(5) - 2, random.nextInt(4) + 6, random.nextInt(5) - 2), 2, 0, random);
|
||||
}
|
||||
|
||||
private void growBranch(Location l1, Vector3 diff, double d1, int recursions, Random r) {
|
||||
BlockData wood = getMain().getWorldHandle().createBlockData("minecraft:oak_wood");
|
||||
BlockData leaves = getMain().getWorldHandle().createBlockData("minecraft:oak_leaves");
|
||||
if(recursions > 1) {
|
||||
geo.generateSphere(l1, leaves, 1 + r.nextInt(2) + (3 - recursions), false, r);
|
||||
if(recursions > 2) return;
|
||||
}
|
||||
if(diff.getY() < 0) diff.rotateAroundAxis(TreeGeometry.getPerpendicular(diff.clone()).normalize(), FastMath.PI);
|
||||
int d = (int) diff.length();
|
||||
for(int i = 0; i < d; i++) {
|
||||
geo.generateSphere(l1.clone().add(diff.clone().multiply((double) i / d)), wood, FastMath.max((int) d1, 0), true, r);
|
||||
}
|
||||
double runningAngle = (double) 45 / (recursions + 1);
|
||||
growBranch(l1.clone().add(diff), diff.clone().multiply(0.75).rotateAroundX(FastMath.toRadians(runningAngle + getNoise(r))).rotateAroundZ(FastMath.toRadians(getNoise(r))),
|
||||
d1 - 1, recursions + 1, r);
|
||||
growBranch(l1.clone().add(diff), diff.clone().multiply(0.75).rotateAroundX(FastMath.toRadians(-runningAngle + getNoise(r))).rotateAroundZ(FastMath.toRadians(getNoise(r))),
|
||||
d1 - 1, recursions + 1, r);
|
||||
growBranch(l1.clone().add(diff), diff.clone().multiply(0.75).rotateAroundZ(FastMath.toRadians(runningAngle + getNoise(r))).rotateAroundX(FastMath.toRadians(getNoise(r))),
|
||||
d1 - 1, recursions + 1, r);
|
||||
growBranch(l1.clone().add(diff), diff.clone().multiply(0.75).rotateAroundZ(FastMath.toRadians(-runningAngle + getNoise(r))).rotateAroundX(FastMath.toRadians(getNoise(r))),
|
||||
d1 - 1, recursions + 1, r);
|
||||
}
|
||||
|
||||
private int getNoise(Random r) {
|
||||
return r.nextInt(60) - 30;
|
||||
}
|
||||
}
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
package com.dfsek.terra.api.world.tree.fractal.trees;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
||||
import com.dfsek.terra.api.world.tree.fractal.FractalTree;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class ShatteredPillar extends FractalTree {
|
||||
|
||||
@Override
|
||||
public MaterialSet getSpawnable() {
|
||||
return MaterialSet.get(main.getWorldHandle().createBlockData("minecraft:end_stone"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a TreeGrower at an origin location.
|
||||
*/
|
||||
public ShatteredPillar(TerraPlugin main) {
|
||||
super(main);
|
||||
}
|
||||
|
||||
/**
|
||||
* Grows the tree in memory. Intended to be invoked from an async thread.
|
||||
* @param origin
|
||||
* @param random
|
||||
*/
|
||||
@Override
|
||||
public void grow(Location origin, Random random) {
|
||||
BlockData obsidian = getMain().getWorldHandle().createBlockData("minecraft:obsidian");
|
||||
int h = random.nextInt(5) + 8;
|
||||
int max = h;
|
||||
for(int i = -h; i < h; i++) setBlock(origin.clone().add(0, i, 0), obsidian);
|
||||
h = h + (random.nextBoolean() ? random.nextInt(3) + 1 : -(random.nextInt(3) + 1));
|
||||
int[] crystalLoc = new int[] {0, 0};
|
||||
if(h > max) {
|
||||
max = h;
|
||||
crystalLoc = new int[] {1, 0};
|
||||
}
|
||||
for(int i = -h; i < h; i++) setBlock(origin.clone().add(1, i, 0), obsidian);
|
||||
h = h + (random.nextBoolean() ? random.nextInt(3) + 1 : -(random.nextInt(3) + 1));
|
||||
if(h > max) {
|
||||
max = h;
|
||||
crystalLoc = new int[] {0, 1};
|
||||
}
|
||||
for(int i = -h; i < h; i++) setBlock(origin.clone().add(0, i, 1), obsidian);
|
||||
h = h + (random.nextBoolean() ? random.nextInt(3) + 1 : -(random.nextInt(3) + 1));
|
||||
if(h > max) {
|
||||
max = h;
|
||||
crystalLoc = new int[] {1, 1};
|
||||
}
|
||||
for(int i = -h; i < h; i++) setBlock(origin.clone().add(1, i, 1), obsidian);
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
package com.dfsek.terra.api.world.tree.fractal.trees;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.math.vector.Vector3;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.platform.handle.WorldHandle;
|
||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
||||
import com.dfsek.terra.api.util.collections.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.tree.fractal.FractalTree;
|
||||
import com.dfsek.terra.api.world.tree.fractal.TreeGeometry;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class ShatteredTree extends FractalTree {
|
||||
private final TreeGeometry geo;
|
||||
private final ProbabilityCollection<BlockData> bark;
|
||||
private final ProbabilityCollection<BlockData> leaves;
|
||||
|
||||
@Override
|
||||
public MaterialSet getSpawnable() {
|
||||
return MaterialSet.get(main.getWorldHandle().createBlockData("minecraft:end_stone"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a TreeGrower at an origin location.
|
||||
*/
|
||||
public ShatteredTree(TerraPlugin main) {
|
||||
super(main);
|
||||
geo = new TreeGeometry(this);
|
||||
WorldHandle handle = main.getWorldHandle();
|
||||
|
||||
bark = new ProbabilityCollection<BlockData>()
|
||||
.add(handle.createBlockData("minecraft:obsidian"), 1)
|
||||
.add(handle.createBlockData("minecraft:black_concrete"), 1);
|
||||
leaves = new ProbabilityCollection<BlockData>()
|
||||
.add(handle.createBlockData("minecraft:purple_stained_glass"), 1)
|
||||
.add(handle.createBlockData("minecraft:magenta_stained_glass"), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Grows the tree in memory. Intended to be invoked from an async thread.
|
||||
*/
|
||||
@Override
|
||||
public void grow(Location origin, Random random) {
|
||||
growBranch(origin.clone(), new Vector3(random.nextInt(5) - 2, random.nextInt(4) + 6, random.nextInt(5) - 2), 1, 0, random);
|
||||
|
||||
}
|
||||
|
||||
private void growBranch(Location l1, Vector3 diff, double d1, int recursions, Random r) {
|
||||
if(recursions > 2) {
|
||||
geo.generateSphere(l1, leaves, 1 + r.nextInt(2), false, r);
|
||||
return;
|
||||
}
|
||||
if(diff.getY() < 0) diff.rotateAroundAxis(TreeGeometry.getPerpendicular(diff.clone()).normalize(), FastMath.PI);
|
||||
int d = (int) diff.length();
|
||||
for(int i = 0; i < d; i++) {
|
||||
geo.generateSphere(l1.clone().add(diff.clone().multiply((double) i / d)), bark, FastMath.max((int) d1, 0), true, r);
|
||||
}
|
||||
double runningAngle = (double) 45 / (recursions + 1);
|
||||
growBranch(l1.clone().add(diff), diff.clone().multiply(0.9).rotateAroundX(FastMath.toRadians(runningAngle + getNoise(r))).rotateAroundZ(FastMath.toRadians(getNoise(r))),
|
||||
d1 - 1, recursions + 1, r);
|
||||
growBranch(l1.clone().add(diff), diff.clone().multiply(0.9).rotateAroundX(FastMath.toRadians(-runningAngle + getNoise(r))).rotateAroundZ(FastMath.toRadians(getNoise(r))),
|
||||
d1 - 1, recursions + 1, r);
|
||||
growBranch(l1.clone().add(diff), diff.clone().multiply(0.9).rotateAroundZ(FastMath.toRadians(runningAngle + getNoise(r))).rotateAroundX(FastMath.toRadians(getNoise(r))),
|
||||
d1 - 1, recursions + 1, r);
|
||||
growBranch(l1.clone().add(diff), diff.clone().multiply(0.9).rotateAroundZ(FastMath.toRadians(-runningAngle + getNoise(r))).rotateAroundX(FastMath.toRadians(getNoise(r))),
|
||||
d1 - 1, recursions + 1, r);
|
||||
}
|
||||
|
||||
private int getNoise(Random r) {
|
||||
return r.nextInt(90) - 45;
|
||||
}
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
package com.dfsek.terra.api.world.tree.fractal.trees;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
||||
import com.dfsek.terra.api.world.tree.fractal.FractalTree;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class SmallShatteredPillar extends FractalTree {
|
||||
|
||||
@Override
|
||||
public MaterialSet getSpawnable() {
|
||||
return MaterialSet.get(main.getWorldHandle().createBlockData("minecraft:end_stone"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a TreeGrower at an origin location.
|
||||
*/
|
||||
public SmallShatteredPillar(TerraPlugin main) {
|
||||
super(main);
|
||||
}
|
||||
|
||||
/**
|
||||
* Grows the tree in memory. Intended to be invoked from an async thread.
|
||||
* @param origin
|
||||
* @param random
|
||||
*/
|
||||
@Override
|
||||
public void grow(Location origin, Random random) {
|
||||
int h = random.nextInt(5) + 5;
|
||||
BlockData obsidian = getMain().getWorldHandle().createBlockData("minecraft:obsidian");
|
||||
for(int i = -h; i < h; i++) setBlock(origin.clone().add(0, i, 0), obsidian);
|
||||
}
|
||||
}
|
||||
-75
@@ -1,75 +0,0 @@
|
||||
package com.dfsek.terra.api.world.tree.fractal.trees;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.math.vector.Vector3;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.platform.handle.WorldHandle;
|
||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
||||
import com.dfsek.terra.api.util.collections.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.tree.fractal.FractalTree;
|
||||
import com.dfsek.terra.api.world.tree.fractal.TreeGeometry;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class SmallShatteredTree extends FractalTree {
|
||||
private final TreeGeometry geo;
|
||||
private final ProbabilityCollection<BlockData> bark;
|
||||
private final ProbabilityCollection<BlockData> leaves;
|
||||
|
||||
@Override
|
||||
public MaterialSet getSpawnable() {
|
||||
return MaterialSet.get(main.getWorldHandle().createBlockData("minecraft:end_stone"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a TreeGrower at an origin location.
|
||||
*/
|
||||
public SmallShatteredTree(TerraPlugin main) {
|
||||
super(main);
|
||||
geo = new TreeGeometry(this);
|
||||
|
||||
WorldHandle handle = main.getWorldHandle();
|
||||
bark = new ProbabilityCollection<BlockData>()
|
||||
.add(handle.createBlockData("minecraft:obsidian"), 1)
|
||||
.add(handle.createBlockData("minecraft:black_concrete"), 1);
|
||||
leaves = new ProbabilityCollection<BlockData>()
|
||||
.add(handle.createBlockData("minecraft:purple_stained_glass"), 1)
|
||||
.add(handle.createBlockData("minecraft:magenta_stained_glass"), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Grows the tree in memory. Intended to be invoked from an async thread.
|
||||
*/
|
||||
@Override
|
||||
public void grow(Location origin, Random random) {
|
||||
growBranch(origin.clone(), new Vector3(random.nextInt(5) - 2, random.nextInt(3) + 4, random.nextInt(5) - 2), 1.5, 0, random);
|
||||
|
||||
}
|
||||
|
||||
private void growBranch(Location l1, Vector3 diff, double d1, int recursions, Random r) {
|
||||
if(recursions > 2) {
|
||||
geo.generateSphere(l1, leaves, 1 + r.nextInt(2) + (3 - recursions), false, r);
|
||||
return;
|
||||
}
|
||||
if(diff.getY() < 0) diff.rotateAroundAxis(TreeGeometry.getPerpendicular(diff.clone()).normalize(), FastMath.PI);
|
||||
int d = (int) diff.length();
|
||||
for(int i = 0; i < d; i++) {
|
||||
geo.generateSphere(l1.clone().add(diff.clone().multiply((double) i / d)), bark, FastMath.max((int) d1, 0), true, r);
|
||||
}
|
||||
double runningAngle = (double) 45 / (recursions + 1);
|
||||
growBranch(l1.clone().add(diff), diff.clone().multiply(0.7).rotateAroundX(FastMath.toRadians(runningAngle + getNoise(r))).rotateAroundZ(FastMath.toRadians(getNoise(r))),
|
||||
d1 - 1, recursions + 1, r);
|
||||
growBranch(l1.clone().add(diff), diff.clone().multiply(0.7).rotateAroundX(FastMath.toRadians(-runningAngle + getNoise(r))).rotateAroundZ(FastMath.toRadians(getNoise(r))),
|
||||
d1 - 1, recursions + 1, r);
|
||||
growBranch(l1.clone().add(diff), diff.clone().multiply(0.7).rotateAroundZ(FastMath.toRadians(runningAngle + getNoise(r))).rotateAroundX(FastMath.toRadians(getNoise(r))),
|
||||
d1 - 1, recursions + 1, r);
|
||||
growBranch(l1.clone().add(diff), diff.clone().multiply(0.7).rotateAroundZ(FastMath.toRadians(-runningAngle + getNoise(r))).rotateAroundX(FastMath.toRadians(getNoise(r))),
|
||||
d1 - 1, recursions + 1, r);
|
||||
}
|
||||
|
||||
private int getNoise(Random r) {
|
||||
return r.nextInt(90) - 45;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package com.dfsek.terra.api.world.tree.fractal.trees;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.math.vector.Vector3;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
||||
import com.dfsek.terra.api.world.tree.fractal.FractalTree;
|
||||
import com.dfsek.terra.api.world.tree.fractal.TreeGeometry;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class SpruceTree extends FractalTree {
|
||||
private final TreeGeometry geo;
|
||||
|
||||
@Override
|
||||
public MaterialSet getSpawnable() {
|
||||
return MaterialSet.get(main.getWorldHandle().createBlockData("minecraft:podzol"),
|
||||
main.getWorldHandle().createBlockData("minecraft:grass_block"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a TreeGrower at an origin location.
|
||||
*/
|
||||
public SpruceTree(TerraPlugin main) {
|
||||
super(main);
|
||||
geo = new TreeGeometry(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Grows the tree in memory. Intended to be invoked from an async thread.
|
||||
*/
|
||||
@Override
|
||||
public void grow(Location origin, Random random) {
|
||||
growTrunk(origin.clone(), new Vector3(0, 16 + random.nextInt(5), 0), random);
|
||||
}
|
||||
|
||||
private void growTrunk(Location l1, Vector3 diff, Random r) {
|
||||
if(diff.getY() < 0) diff.rotateAroundAxis(TreeGeometry.getPerpendicular(diff.clone()).normalize(), FastMath.PI);
|
||||
int d = (int) diff.length();
|
||||
int rad = 7;
|
||||
BlockData wood = getMain().getWorldHandle().createBlockData("minecraft:spruce_wood");
|
||||
BlockData leaves = getMain().getWorldHandle().createBlockData("minecraft:spruce_leave");
|
||||
for(int i = 0; i < d; i++) {
|
||||
geo.generateSphere(l1.clone().add(diff.clone().multiply((double) i / d)), wood, (int) ((i > d * 0.65) ? 0.5 : 1.5), true, r);
|
||||
if(i > 3)
|
||||
geo.generateCylinder(l1.clone().add(diff.clone().multiply((double) i / d)), leaves, (int) (((6 - (i % 4))) * (1.25 - ((double) i / d))), 1, false, r);
|
||||
}
|
||||
setBlock(l1.clone().add(diff), leaves);
|
||||
setBlock(l1.clone().add(diff).add(0, 1, 0), leaves);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.dfsek.terra.config.factories;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.world.tree.Tree;
|
||||
import com.dfsek.terra.api.platform.world.Tree;
|
||||
import com.dfsek.terra.config.templates.TreeTemplate;
|
||||
import com.dfsek.terra.world.population.items.tree.TerraTree;
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.dfsek.terra.config.loaders;
|
||||
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.platform.world.Tree;
|
||||
import com.dfsek.terra.api.util.collections.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
import com.dfsek.terra.api.world.flora.Flora;
|
||||
import com.dfsek.terra.api.world.palette.Palette;
|
||||
import com.dfsek.terra.api.world.tree.Tree;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -5,9 +5,9 @@ import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.api.math.Range;
|
||||
import com.dfsek.terra.api.math.noise.samplers.noise.random.WhiteNoiseSampler;
|
||||
import com.dfsek.terra.api.platform.world.Tree;
|
||||
import com.dfsek.terra.api.util.collections.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.api.world.tree.Tree;
|
||||
import com.dfsek.terra.config.loaders.Types;
|
||||
import com.dfsek.terra.world.population.items.tree.TreeLayer;
|
||||
|
||||
|
||||
+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;
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.event.events.config.ConfigPackPostLoadEvent;
|
||||
import com.dfsek.terra.api.event.events.config.ConfigPackPreLoadEvent;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.platform.world.Tree;
|
||||
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||
import com.dfsek.terra.api.structures.loot.LootTable;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
|
||||
@@ -20,7 +21,6 @@ import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.flora.Flora;
|
||||
import com.dfsek.terra.api.world.palette.Palette;
|
||||
import com.dfsek.terra.api.world.tree.Tree;
|
||||
import com.dfsek.terra.carving.UserDefinedCarver;
|
||||
import com.dfsek.terra.config.builder.BiomeBuilder;
|
||||
import com.dfsek.terra.config.dummy.DummyWorld;
|
||||
@@ -120,7 +120,7 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
long l = System.nanoTime();
|
||||
floraRegistry = new FloraRegistry(main);
|
||||
paletteRegistry = new PaletteRegistry(main);
|
||||
treeRegistry = new TreeRegistry(main);
|
||||
treeRegistry = new TreeRegistry();
|
||||
register(abstractConfigLoader);
|
||||
register(selfLoader);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -156,7 +157,7 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
long l = System.nanoTime();
|
||||
floraRegistry = new FloraRegistry(main);
|
||||
paletteRegistry = new PaletteRegistry(main);
|
||||
treeRegistry = new TreeRegistry(main);
|
||||
treeRegistry = new TreeRegistry();
|
||||
register(abstractConfigLoader);
|
||||
register(selfLoader);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
package com.dfsek.terra.config.pack;
|
||||
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.platform.block.BlockData;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
import com.dfsek.terra.api.platform.world.Tree;
|
||||
import com.dfsek.terra.api.registry.LockedRegistry;
|
||||
import com.dfsek.terra.api.structures.loot.LootTable;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
|
||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.flora.Flora;
|
||||
import com.dfsek.terra.api.world.palette.Palette;
|
||||
import com.dfsek.terra.api.world.tree.Tree;
|
||||
import com.dfsek.terra.carving.UserDefinedCarver;
|
||||
import com.dfsek.terra.registry.OpenRegistry;
|
||||
import com.dfsek.terra.world.TerraWorld;
|
||||
@@ -22,7 +18,6 @@ import com.dfsek.terra.world.population.items.TerraStructure;
|
||||
import com.dfsek.terra.world.population.items.ores.Ore;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class WorldConfig {
|
||||
private final LockedRegistry<StructureScript> scriptRegistry;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -1,77 +1,11 @@
|
||||
package com.dfsek.terra.registry.config;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.block.BlockFace;
|
||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
||||
import com.dfsek.terra.api.world.tree.Tree;
|
||||
import com.dfsek.terra.api.world.tree.fractal.FractalTree;
|
||||
import com.dfsek.terra.api.world.tree.fractal.trees.Cactus;
|
||||
import com.dfsek.terra.api.world.tree.fractal.trees.IceSpike;
|
||||
import com.dfsek.terra.api.world.tree.fractal.trees.OakTree;
|
||||
import com.dfsek.terra.api.world.tree.fractal.trees.ShatteredPillar;
|
||||
import com.dfsek.terra.api.world.tree.fractal.trees.ShatteredTree;
|
||||
import com.dfsek.terra.api.world.tree.fractal.trees.SmallShatteredPillar;
|
||||
import com.dfsek.terra.api.world.tree.fractal.trees.SmallShatteredTree;
|
||||
import com.dfsek.terra.api.world.tree.fractal.trees.SpruceTree;
|
||||
import com.dfsek.terra.api.platform.world.Tree;
|
||||
import com.dfsek.terra.registry.OpenRegistry;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Random;
|
||||
|
||||
public class TreeRegistry extends OpenRegistry<Tree> {
|
||||
private final TerraPlugin main;
|
||||
|
||||
public TreeRegistry(TerraPlugin main) {
|
||||
this.main = main;
|
||||
tryAdd("CACTUS", Cactus.class);
|
||||
tryAdd("GIANT_OAK", OakTree.class);
|
||||
tryAdd("GIANT_SPRUCE", SpruceTree.class);
|
||||
tryAdd("LARGE_SHATTERED_PILLAR", ShatteredPillar.class);
|
||||
tryAdd("SHATTERED_LARGE", ShatteredTree.class);
|
||||
tryAdd("SHATTERED_SMALL", SmallShatteredTree.class);
|
||||
tryAdd("SMALL_SHATTERED_PILLAR", SmallShatteredPillar.class);
|
||||
tryAdd("ICE_SPIKE", IceSpike.class);
|
||||
}
|
||||
|
||||
private void tryAdd(String id, Class<? extends FractalTree> value) {
|
||||
try {
|
||||
add(id, new FractalTreeHolder(value));
|
||||
} catch(Exception e) {
|
||||
main.logger().warning("Unable to load tree " + id + ": " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(String identifier, Tree value) {
|
||||
return super.add(identifier, value);
|
||||
}
|
||||
|
||||
private final class FractalTreeHolder implements Tree {
|
||||
private final FractalTree tree;
|
||||
|
||||
private FractalTreeHolder(Class<? extends FractalTree> clazz) throws NoSuchMethodException {
|
||||
Constructor<? extends FractalTree> constructor = clazz.getConstructor(TerraPlugin.class);
|
||||
try {
|
||||
tree = constructor.newInstance(main);
|
||||
} catch(InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
throw new IllegalArgumentException("Unable to load tree: " + clazz);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean plant(Location l, Random r) {
|
||||
if(!getSpawnable().contains(l.getBlock().getType())) return false;
|
||||
if(!l.getBlock().getRelative(BlockFace.UP).isEmpty()) return false;
|
||||
tree.grow(l.add(0, 1, 0), r);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialSet getSpawnable() {
|
||||
return tree.getSpawnable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user