Skip to content

Instantly share code, notes, and snippets.

@Barteks2x
Created December 22, 2017 19:03
Show Gist options
  • Save Barteks2x/dded2753f0cd3cb2140541dc7a477b92 to your computer and use it in GitHub Desktop.
Save Barteks2x/dded2753f0cd3cb2140541dc7a477b92 to your computer and use it in GitHub Desktop.
$ git diff --staged;
$ git diff --staged
diff --git a/build.gradle.kts b/build.gradle.kts
index a671967e..ba5ec292 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -11,16 +11,10 @@ import nl.javadude.gradle.plugins.license.LicenseExtension
import nl.javadude.gradle.plugins.license.LicensePlugin
import org.ajoberstar.grgit.Grgit
import org.ajoberstar.grgit.operation.DescribeOp
-import org.gradle.api.JavaVersion
-import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.internal.HasConvention
-import org.gradle.api.plugins.BasePluginConvention
-import org.gradle.api.plugins.JavaPluginConvention
-import org.gradle.api.tasks.testing.Test
-import org.gradle.jvm.tasks.Jar
-import org.gradle.language.jvm.tasks.ProcessResources
+import org.gradle.kotlin.dsl.creating
+import org.gradle.kotlin.dsl.extra
import org.gradle.plugins.ide.idea.model.IdeaModel
-import org.gradle.script.lang.kotlin.*
import org.spongepowered.asm.gradle.plugins.MixinExtension
import org.spongepowered.asm.gradle.plugins.MixinGradlePlugin
import kotlin.apply
@@ -51,9 +45,12 @@ buildscript {
}
plugins {
+ base
java
idea
eclipse
+ maven
+ signing
}
apply {
@@ -89,15 +86,13 @@ val versionSuffix by project
val versionMinorFreeze by project
val sourceSets = the<JavaPluginConvention>().sourceSets
-val mainSourceSet = sourceSets["main"]
-val minecraft = the<ForgeExtension>()
+val mainSourceSet = sourceSets["main"]!!
version = getModVersion()
group = "cubichunks"
-
(mainSourceSet as ExtensionAware).extra["refMap"] = "cubicchunks.mixins.refmap.json"
-configure<IdeaModel> {
+idea {
module.apply {
inheritOutputDirs = true
}
@@ -105,20 +100,20 @@ configure<IdeaModel> {
module.isDownloadSources = true
}
-configure<BasePluginConvention> {
+base {
archivesBaseName = "CubicChunks"
}
-configure<JavaPluginConvention> {
+java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
-configure<MixinExtension> {
+mixin {
token("MC_FORGE", extractForgeMinorVersion())
}
-configure<ForgeExtension> {
+minecraft {
version = theForgeVersion as String
runDir = "run"
mappings = theMappingsVersion as String
@@ -148,7 +143,7 @@ configure<ForgeExtension> {
serverJvmArgs.addAll(args)
}
-configure<LicenseExtension> {
+license {
val ext = (this as HasConvention).convention.extraProperties
ext["project"] = projectName
ext["year"] = licenseYear
@@ -164,21 +159,17 @@ configure<LicenseExtension> {
mapping(mapOf("java" to "SLASHSTAR_STYLE"))
}
-configure<NamedDomainObjectContainer<ReobfTaskFactory.ReobfTaskWrapper>> {
+reobf {
create("shadowJar").apply {
mappingType = ReobfMappingType.SEARGE
}
-}
-// temporary until malisiscore updates
-deobfMcSRG.apply {
- isFailOnAtError = false
-}
-deobfMcMCP.apply{
- isFailOnAtError = false
+ create("coreJar").apply {
+ mappingType = ReobfMappingType.SEARGE
+ }
}
build.dependsOn("reobfShadowJar")
-configure<JMHPluginExtension> {
+jmh {
iterations = 10
benchmarkMode = listOf("thrpt")
batchSize = 16
@@ -195,6 +186,103 @@ configure<JMHPluginExtension> {
jmhVersion = "1.17.1"
}
+
+val javadocJar by tasks.creating(Jar::class) {
+ classifier = "javadoc"
+ from(tasks["javadoc"])
+}
+val sourcesJar by tasks.creating(Jar::class) {
+ classifier = "sources"
+ from(sourceSets["main"].java.srcDirs)
+}
+
+
+// based on:
+// https://github.com/Ordinastie/MalisisCore/blob/30d8efcfd047ac9e9bc75dfb76642bd5977f0305/build.gradle#L204-L256
+// https://github.com/gradle/kotlin-dsl/blob/201534f53d93660c273e09f768557220d33810a9/samples/maven-plugin/build.gradle.kts#L10-L44
+val uploadArchives: Upload by tasks
+uploadArchives.apply {
+ repositories {
+ withConvention(MavenRepositoryHandlerConvention::class) {
+ mavenDeployer {
+ // Sign Maven POM
+ beforeDeployment {
+ signing.signPom(this)
+ }
+
+ val username = if (project.hasProperty("sonatypeUsername")) project.properties["sonatypeUsername"] else System.getenv("sonatypeUsername")
+ val password = if (project.hasProperty("sonatypePassword")) project.properties["sonatypePassword"] else System.getenv("sonatypePassword")
+
+ withGroovyBuilder {
+ "snapshotRepository"("url" to "https://oss.sonatype.org/content/repositories/snapshots") {
+ "authentication"("userName" to username, "password" to password)
+ }
+
+ "repository"("url" to "https://oss.sonatype.org/service/local/staging/deploy/maven2") {
+ "authentication"("userName" to username, "password" to password)
+ }
+ }
+
+ // Maven POM generation
+ pom.project {
+ withGroovyBuilder {
+
+ "name"(projectName)
+ "artifactId"(base.archivesBaseName)
+ "packaging"("jar")
+ "url"("https://github.com/OpenCubicChunks/RegionLib")
+ "description"("Unlimited world height mod for Minecraft")
+
+
+ "scm" {
+ "connection"("scm:git:git://github.com/OpenCubicChunks/RegionLib.git")
+ "developerConnection"("scm:git:ssh://[email protected]:OpenCubicChunks/RegionLib.git")
+ "url"("https://github.com/OpenCubicChunks/RegionLib")
+ }
+
+ "licenses" {
+ "license" {
+ "name"("The MIT License")
+ "url"("http://www.tldrlegal.com/license/mit-license")
+ "distribution"("repo")
+ }
+ }
+
+ "developers" {
+ "developer" {
+ "id"("Barteks2x")
+ "name"("Barteks2x")
+ }
+ "developer" {
+ "id"("xcube16")
+ "name"("xcube16")
+ }
+ }
+
+ "issueManagement" {
+ "system"("github")
+ "url"("https://github.com/OpenCubicChunks/RegionLib/issues")
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// tasks must be before artifacts, don't change the order
+artifacts {
+ withGroovyBuilder {
+ "archives"(tasks["jar"], sourcesJar, javadocJar)
+ }
+}
+
+signing {
+ isRequired = false
+ // isRequired = gradle.taskGraph.hasTask("uploadArchives")
+ sign(configurations.archives)
+}
+
repositories {
mavenLocal()
mavenCentral()
@@ -208,16 +296,9 @@ repositories {
}
dependencies {
- // configurations, some of them aren't necessary but added for consistency when specifying "extendsFrom"
- val jmh by configurations
- val forgeGradleMc by configurations
- val forgeGradleMcDeps by configurations
- val forgeGradleGradleStart by configurations
- val compile by configurations
- val testCompile by configurations
- val deobfCompile by configurations
-
compile("com.flowpowered:flow-noise:1.0.1-SNAPSHOT")
+ // https://mvnrepository.com/artifact/com.typesafe/config
+ compile("com.typesafe:config:1.2.0")
testCompile("junit:junit:4.11")
testCompile("org.hamcrest:hamcrest-junit:2.0.0.0")
testCompile("it.ozimov:java7-hamcrest-matchers:0.7.0")
@@ -234,6 +315,14 @@ dependencies {
isTransitive = false
}
+ // configurations, needed for extendsFrom
+ val jmh by configurations
+ val forgeGradleMc by configurations
+ val forgeGradleMcDeps by configurations
+ val forgeGradleGradleStart by configurations
+ val compile by configurations
+ val testCompile by configurations
+
jmh.extendsFrom(compile)
jmh.extendsFrom(forgeGradleMc)
jmh.extendsFrom(forgeGradleMcDeps)
@@ -244,31 +333,49 @@ dependencies {
// this is needed because it.ozimov:java7-hamcrest-matchers:0.7.0 depends on guava 19, while MC needs guava 21
configurations.all { resolutionStrategy { force("com.google.guava:guava:21.0") } }
-jar.apply {
- jarConfig()
-}
-task<Jar>("jarDev") {
- from(mainSourceSet.output)
- jarConfig()
- classifier = "dev"
- tasks["assemble"].dependsOn(this)
+// modified version of https://github.com/PaleoCrafter/Dependency-Extraction-Example/blob/coremod-separation/build.gradle
+tasks {
+ "coreJar"(org.gradle.api.tasks.bundling.Jar::class) {
+ // need FQN because ForgeGradle needs this exact class and default imports use different one
+ from(mainSourceSet.output) {
+ include("cubicchunks/asm/**")
+ }
+ // Standard coremod manifest definitions
+ manifest {
+ attributes["FMLAT"] = "cubicchunks_at.cfg"
+ attributes["FMLCorePlugin"] = "cubicchunks.asm.CubicChunksCoreMod"
+ attributes["TweakClass"] = "org.spongepowered.asm.launch.MixinTweaker"
+ attributes["TweakOrder"] = "0"
+ // Strictly speaking not required (right now)
+ // Allows Forge to extract the dependency to a local repository (Given that the corresponding PR is merged)
+ // If another mod ships the same dependency, it doesn't have to be extracted twice
+ attributes["Maven-Version"] = "${project.group}:${project.base.archivesBaseName}:${project.version}:core"
+ }
+ classifier = "core"
+ }
}
+jar.apply {
+ val coreJar: Jar by tasks
+
+ exclude("cubicchunks/asm/**")
-fun Jar.jarConfig(): Jar {
- exclude("LICENSE.txt", "log4j2.xml")
- manifest.attributes["FMLAT"] = "cubicchunks_at.cfg"
- manifest.attributes["FMLCorePlugin"] = "cubicchunks.asm.CubicChunksCoreMod"
- manifest.attributes["TweakClass"] = "org.spongepowered.asm.launch.MixinTweaker"
- manifest.attributes["TweakOrder"] = "0"
- manifest.attributes["ForceLoadAsMod"] = "true"
- return this
+ // Add the output of the coremod JAR task to the main JAR for later extraction
+ from(coreJar.archivePath.absolutePath) {
+ include("*") // Due to the way Gradle's copy tasks work, we need this line for the JAR to get added
+ }
+ manifest {
+ // The crucial manifest attribute: Make Forge extract the contained JAR
+ attributes["ContainedDeps"] = coreJar.archivePath.name
+ }
+ // Only run the main jar task after the coremod JAR was completely built
+ dependsOn("reobfCoreJar")
}
shadowJar.apply {
relocate("com.flowpowered", "cubicchunks.com.flowpowered")
exclude("log4j2.xml")
- classifier = ""
+ classifier = "all"
}
test.apply {
@@ -320,7 +427,7 @@ fun getModVersion(): String {
val git = Grgit.open()
val describe = DescribeOp(git.repository).call()
val branch = getGitBranch(git)
- getModVersion_do(describe, branch);
+ getModVersion(describe, branch);
} catch(ex: RuntimeException) {
logger.error("Unknown error when accessing git repository! Are you sure the git repository exists?", ex)
String.format("%s-%s.%s.%s%s%s", getMcVersion(), "9999", "9999", "9999", "", "NOVERSION")
@@ -347,7 +454,7 @@ fun getGitBranch(git: Grgit): String {
return branch
}
-fun getModVersion_do(describe: String, branch: String): String {
+fun getModVersion(describe: String, branch: String): String {
if (branch.startsWith("MC_")) {
val branchMcVersion = branch.substring("MC_".length)
if (branchMcVersion != getMcVersion()) {
@@ -391,8 +498,7 @@ fun getModVersion_do(describe: String, branch: String): String {
val minor = if (minorFreeze < 0) commitSinceTag else minorFreeze
val patch = if (minorFreeze < 0) 0 else (commitSinceTag - minorFreeze)
- val version = String.format("%s-%s.%d.%d%s%s", mcVersion, modAndApiVersion, minor, patch, versionSuffix, branchSuffix)
- return version
+ return String.format("%s-%s.%d.%d%s%s", mcVersion, modAndApiVersion, minor, patch, versionSuffix, branchSuffix)
}
fun extractForgeMinorVersion(): String {
diff --git a/gradle/project-schema.json b/gradle/project-schema.json
new file mode 100644
index 00000000..e1117aae
--- /dev/null
+++ b/gradle/project-schema.json
@@ -0,0 +1,111 @@
+{
+ ":": {
+ "conventions": {
+ "base": "org.gradle.api.plugins.BasePluginConvention",
+ "java": "org.gradle.api.plugins.JavaPluginConvention",
+ "maven": "org.gradle.api.plugins.MavenPluginConvention"
+ },
+ "configurations": [
+ "apiCompile",
+ "apiCompileClasspath",
+ "apiCompileOnly",
+ "apiElements",
+ "apiImplementation",
+ "apiRuntime",
+ "apiRuntimeClasspath",
+ "apiRuntimeOnly",
+ "archives",
+ "compile",
+ "compileClasspath",
+ "compileOnly",
+ "default",
+ "deobfCompile",
+ "deobfProvided",
+ "forgeGradleFfiDeps",
+ "forgeGradleGradleStart",
+ "forgeGradleMc",
+ "forgeGradleMcDeps",
+ "forgeGradleMcDepsClient",
+ "forgeGradleMcNatives",
+ "forgeGradleMcpData",
+ "forgeGradleMcpMappings",
+ "forgeGradleResolvedDeobfCompile",
+ "forgeGradleResovledDeobfProvided",
+ "forgeGradleUserDevPackage",
+ "implementation",
+ "jmh",
+ "jmhCompile",
+ "jmhCompileClasspath",
+ "jmhCompileOnly",
+ "jmhImplementation",
+ "jmhRuntime",
+ "jmhRuntimeClasspath",
+ "jmhRuntimeOnly",
+ "provided",
+ "runtime",
+ "runtimeClasspath",
+ "runtimeElements",
+ "runtimeOnly",
+ "shadow",
+ "signatures",
+ "testCompile",
+ "testCompileClasspath",
+ "testCompileOnly",
+ "testImplementation",
+ "testRuntime",
+ "testRuntimeClasspath",
+ "testRuntimeOnly"
+ ],
+ "extensions": {
+ "ext": "org.gradle.api.plugins.ExtraPropertiesExtension",
+ "defaultArtifacts": "org.gradle.api.internal.plugins.DefaultArtifactPublicationSet",
+ "reporting": "org.gradle.api.reporting.ReportingExtension",
+ "idea": "org.gradle.plugins.ide.idea.model.IdeaModel",
+ "eclipse": "org.gradle.plugins.ide.eclipse.model.EclipseModel",
+ "signing": "org.gradle.plugins.signing.SigningExtension",
+ "minecraft": "net.minecraftforge.gradle.user.patcherUser.forge.ForgeExtension",
+ "reobf": "org.gradle.api.NamedDomainObjectContainer<net.minecraftforge.gradle.user.IReobfuscator>",
+ "shadow": "com.github.jengelman.gradle.plugins.shadow.ShadowExtension",
+ "mixin": "org.spongepowered.asm.gradle.plugins.MixinExtension",
+ "license": "nl.javadude.gradle.plugins.license.LicenseExtension",
+ "downloadLicenses": "nl.javadude.gradle.plugins.license.DownloadLicensesExtension",
+ "jmh": "me.champeau.gradle.JMHPluginExtension"
+ }
+ },
+ ":RegionLib": {
+ "conventions": {
+ "base": "org.gradle.api.plugins.BasePluginConvention",
+ "java": "org.gradle.api.plugins.JavaPluginConvention",
+ "maven": "org.gradle.api.plugins.MavenPluginConvention"
+ },
+ "configurations": [
+ "apiElements",
+ "archives",
+ "compile",
+ "compileClasspath",
+ "compileOnly",
+ "default",
+ "implementation",
+ "runtime",
+ "runtimeClasspath",
+ "runtimeElements",
+ "runtimeOnly",
+ "signatures",
+ "testCompile",
+ "testCompileClasspath",
+ "testCompileOnly",
+ "testImplementation",
+ "testRuntime",
+ "testRuntimeClasspath",
+ "testRuntimeOnly"
+ ],
+ "extensions": {
+ "ext": "org.gradle.api.plugins.ExtraPropertiesExtension",
+ "defaultArtifacts": "org.gradle.api.internal.plugins.DefaultArtifactPublicationSet",
+ "reporting": "org.gradle.api.reporting.ReportingExtension",
+ "signing": "org.gradle.plugins.signing.SigningExtension",
+ "license": "nl.javadude.gradle.plugins.license.LicenseExtension",
+ "downloadLicenses": "nl.javadude.gradle.plugins.license.DownloadLicensesExtension"
+ }
+ }
+}
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 1000940d..8bd6977f 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 620e550c..8edd5864 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Mon May 29 16:40:45 CEST 2017
+#Wed Oct 11 16:16:50 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip
+distributionUrl=https\://repo.gradle.org/gradle/dist-snapshots/gradle-kotlin-dsl-4.3-20171010191714+0000-all.zip
diff --git a/src/main/java/cubicchunks/CubicChunks.java b/src/main/java/cubicchunks/CubicChunks.java
index ee4d8aeb..b432976b 100644
--- a/src/main/java/cubicchunks/CubicChunks.java
+++ b/src/main/java/cubicchunks/CubicChunks.java
@@ -403,9 +403,13 @@ public class CubicChunks {
"Enabling this option will force " + CubicChunks.MODID
+ " to use world generators designed for two dimensional chunks, which are often used for custom ore generators added by mods. To do so "
+ CubicChunks.MODID + " will pregenerate cubes in a range of height from 0 to 255."),
- FORCE_CUBIC_CHUNKS(false,
- "Enabling this will force creating a cubic chunks world, even if it's not cubic chunks world type. This option is automatically"
- + " set in world creation GUI when creating cubic chunks world with non-cubicchunks world type");
+ CUBIC_CHUNKS_BY_DEFAULT(false,
+ "Enabling this will create a cubic chunks world, even if it's not cubic chunks world type. This option is automatically"
+ + " set in world creation GUI when creating cubic chunks world with non-cubicchunks world type"),
+ FORCE_LOAD_AS_CUBIC_CHUNKS_ONCE(false,
+ "The next loaded world will be loaded as cubic chunks world, regardless of what the world is. After it's loaded, the option "
+ + "will be reset back to false. Can be used to restore cubic chunks world if you accidentally loaded it with vanilla. "
+ + "Currently the only way to create cubic chunks world with Open Terrain Generator mod.");
private final boolean defaultValue;
private final String description;
diff --git a/src/main/java/cubicchunks/asm/CubicChunksCoreMod.java b/src/main/java/cubicchunks/asm/CubicChunksCoreMod.java
index 82a1128c..52f91f4b 100644
--- a/src/main/java/cubicchunks/asm/CubicChunksCoreMod.java
+++ b/src/main/java/cubicchunks/asm/CubicChunksCoreMod.java
@@ -55,11 +55,10 @@ public class CubicChunksCoreMod implements IFMLLoadingPlugin {
@Override
public Integer getToken(String token, MixinEnvironment env) {
if ("FORGE".equals(token)) {
- return Integer.valueOf(ForgeVersion.getBuildVersion());
+ return ForgeVersion.getBuildVersion();
} else if ("FML".equals(token)) {
String fmlVersion = Loader.instance().getFMLVersionString();
- int build = Integer.parseInt(fmlVersion.substring(fmlVersion.lastIndexOf('.') + 1));
- return Integer.valueOf(build);
+ return Integer.parseInt(fmlVersion.substring(fmlVersion.lastIndexOf('.') + 1));
} else if ("MC_FORGE".equals(token)) {
return ForgeVersion.minorVersion;
}
diff --git a/src/main/java/cubicchunks/asm/CubicChunksMixinConfig.java b/src/main/java/cubicchunks/asm/CubicChunksCoremodConfig.java
similarity index 88%
rename from src/main/java/cubicchunks/asm/CubicChunksMixinConfig.java
rename to src/main/java/cubicchunks/asm/CubicChunksCoremodConfig.java
index 63673ee2..355003a8 100644
--- a/src/main/java/cubicchunks/asm/CubicChunksMixinConfig.java
+++ b/src/main/java/cubicchunks/asm/CubicChunksCoremodConfig.java
@@ -27,7 +27,6 @@ import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
-import java.util.Arrays;
import java.util.List;
import java.util.Set;
@@ -48,10 +47,10 @@ import com.google.gson.stream.JsonWriter;
* Note, that this plugin is not working in JUnit tests due to missing field of
* FMLInjectionData required for MinecraftForge configuration used here.
* Therefore two Mixin classes with an injection in a same method and with a same priority will cause Mixin to fail. */
-public class CubicChunksMixinConfig implements IMixinConfigPlugin {
+public class CubicChunksCoremodConfig implements IMixinConfigPlugin {
@Nonnull
- public static Logger LOGGER = LogManager.getLogger("CubicChunksMixinConfig");
+ public static Logger LOGGER = LogManager.getLogger("CubicChunksCoremodConfig");
@Override
public void onLoad(String mixinPackage) {
@@ -76,7 +75,7 @@ public class CubicChunksMixinConfig implements IMixinConfigPlugin {
@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
LOGGER.info("Checking config option for "+mixinClassName);
- for (BoolOptions configOption : BoolOptions.values()) {
+ for (MixinOptions configOption : MixinOptions.values()) {
if (configOption.mixinClassNamesOnTrue != null)
for (String mixinClassNameOnTrue : configOption.mixinClassNamesOnTrue)
if (mixinClassName.equals(mixinClassNameOnTrue))
@@ -107,7 +106,7 @@ public class CubicChunksMixinConfig implements IMixinConfigPlugin {
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
- public static enum BoolOptions {
+ public enum MixinOptions {
OPTIMIZE_PATH_NAVIGATOR(false,
null,
new String[] {"cubicchunks.asm.mixin.selectable.common.MixinPathNavigate",
@@ -146,7 +145,7 @@ public class CubicChunksMixinConfig implements IMixinConfigPlugin {
private final String description;
private boolean value;
- private BoolOptions(boolean defaultValue1, String[] mixinClassNamesOnFalse1, String[] mixinClassNamesOnTrue1, String description1) {
+ MixinOptions(boolean defaultValue1, String[] mixinClassNamesOnFalse1, String[] mixinClassNamesOnTrue1, String description1) {
defaultValue = defaultValue1;
mixinClassNamesOnFalse = mixinClassNamesOnFalse1;
mixinClassNamesOnTrue = mixinClassNamesOnTrue1;
@@ -158,27 +157,12 @@ public class CubicChunksMixinConfig implements IMixinConfigPlugin {
return value;
}
}
-
- public static String getNicelyFormattedName(String name) {
- StringBuffer out = new StringBuffer();
- char char_ = '_';
- char prevchar = 0;
- for (char c : name.toCharArray()) {
- if (c != char_ && prevchar != char_) {
- out.append(String.valueOf(c).toLowerCase());
- } else if (c != char_) {
- out.append(String.valueOf(c));
- }
- prevchar = c;
- }
- return out.toString();
- }
private void writeConfigToJson(File configFile) throws IOException {
JsonWriter writer = new JsonWriter(new FileWriter(configFile));
writer.setIndent(" ");
writer.beginArray();
- for (BoolOptions configOption : BoolOptions.values()) {
+ for (MixinOptions configOption : MixinOptions.values()) {
writer.beginObject();
writer.name(configOption.name());
writer.value(configOption.value);
@@ -191,14 +175,14 @@ public class CubicChunksMixinConfig implements IMixinConfigPlugin {
}
private void readConfigFromJson(File configFile) throws IOException {
- int expectingOptionsNumber = BoolOptions.values().length;
+ int expectingOptionsNumber = MixinOptions.values().length;
JsonReader reader = new JsonReader(new FileReader(configFile));
reader.beginArray();
while(reader.hasNext()){
reader.beginObject();
next_object:while(reader.hasNext()){
String name = reader.nextName();
- for(BoolOptions option:BoolOptions.values()){
+ for(MixinOptions option: MixinOptions.values()){
if(option.name().equals(name)){
expectingOptionsNumber--;
option.value = reader.nextBoolean();
diff --git a/src/main/java/cubicchunks/asm/mixin/core/common/MixinChunkCache_HeightLimits.java b/src/main/java/cubicchunks/asm/mixin/core/common/MixinChunkCache_HeightLimits.java
index 7486a225..a62344dc 100644
--- a/src/main/java/cubicchunks/asm/mixin/core/common/MixinChunkCache_HeightLimits.java
+++ b/src/main/java/cubicchunks/asm/mixin/core/common/MixinChunkCache_HeightLimits.java
@@ -23,20 +23,14 @@
*/
package cubicchunks.asm.mixin.core.common;
-import static cubicchunks.asm.JvmNames.BLOCK_POS_GETY;
-
-import cubicchunks.asm.MixinUtils;
import cubicchunks.world.ICubicWorld;
import mcp.MethodsReturnNonnullByDefault;
-import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ChunkCache;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
-import org.spongepowered.asm.mixin.injection.Redirect;
import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/src/main/java/cubicchunks/asm/mixin/core/common/MixinChunk_Cubes.java b/src/main/java/cubicchunks/asm/mixin/core/common/MixinChunk_Cubes.java
index 10ae6a4e..97607d6f 100644
--- a/src/main/java/cubicchunks/asm/mixin/core/common/MixinChunk_Cubes.java
+++ b/src/main/java/cubicchunks/asm/mixin/core/common/MixinChunk_Cubes.java
@@ -123,6 +123,9 @@ public abstract class MixinChunk_Cubes implements IColumn {
@Nullable
private ExtendedBlockStorage getEBS_CubicChunks(int index) {
if (!isColumn) {
+ if (index < 0 || index >= storageArrays.length) {
+ return NULL_BLOCK_STORAGE;
+ }
return storageArrays[index];
}
if (cachedCube != null && cachedCube.getY() == index) {
@@ -228,6 +231,12 @@ public abstract class MixinChunk_Cubes implements IColumn {
@Overwrite
public ExtendedBlockStorage[] getBlockStorageArray() {
if (isColumn) {
+ for (int i = 0; i < 16; i++) {
+ storageArrays[i] = getEBS_CubicChunks(i);
+ }
+ if (true) {
+ return storageArrays;
+ }
// TODO: make the first 16 entries match vanilla
return cubeMap.getStoragesToTick();
}
diff --git a/src/main/java/cubicchunks/asm/mixin/core/common/MixinWorldProvider.java b/src/main/java/cubicchunks/asm/mixin/core/common/MixinWorldProvider.java
index f9cba697..c896de84 100644
--- a/src/main/java/cubicchunks/asm/mixin/core/common/MixinWorldProvider.java
+++ b/src/main/java/cubicchunks/asm/mixin/core/common/MixinWorldProvider.java
@@ -37,6 +37,7 @@ import net.minecraft.world.World;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.gen.IChunkGenerator;
import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -66,7 +67,7 @@ public abstract class MixinWorldProvider implements ICubicWorldProvider {
* @reason return the real world height instead of hardcoded 256
* @author Barteks2x
*/
- // @Overwrite() - overwrite doesn't support unobfuscated methods
+ @Overwrite(remap = false)
public int getHeight() {
return cubicWorld().getMaxHeight();
}
diff --git a/src/main/java/cubicchunks/asm/mixin/core/common/MixinWorld_HeightLimits.java b/src/main/java/cubicchunks/asm/mixin/core/common/MixinWorld_HeightLimits.java
index 2f7860ca..ca136f57 100644
--- a/src/main/java/cubicchunks/asm/mixin/core/common/MixinWorld_HeightLimits.java
+++ b/src/main/java/cubicchunks/asm/mixin/core/common/MixinWorld_HeightLimits.java
@@ -23,14 +23,12 @@
*/
package cubicchunks.asm.mixin.core.common;
-import static cubicchunks.asm.JvmNames.WORLD_GET_LIGHT_WITH_FLAG;
import static cubicchunks.asm.JvmNames.WORLD_IS_AREA_LOADED;
import static cubicchunks.asm.JvmNames.WORLD_IS_BLOCK_LOADED_Z;
import static cubicchunks.asm.JvmNames.WORLD_IS_CHUNK_LOADED;
import static cubicchunks.util.Coords.blockToCube;
import static cubicchunks.util.Coords.cubeToMinBlock;
-import cubicchunks.asm.MixinUtils;
import cubicchunks.world.ICubicWorld;
import cubicchunks.world.cube.BlankCube;
import cubicchunks.world.cube.Cube;
@@ -193,6 +191,7 @@ public abstract class MixinWorld_HeightLimits implements ICubicWorld {
* @author Barteks2x
* @reason CubicChunks needs to check if cube is loaded instead of chunk
*/
+
@Inject(method = WORLD_IS_BLOCK_LOADED_Z, cancellable = true, at = @At(value = "HEAD"))
public void isBlockLoaded(BlockPos pos, boolean allowEmpty, CallbackInfoReturnable<Boolean> cbi) {
if (!isCubicWorld()) {
@@ -206,6 +205,7 @@ public abstract class MixinWorld_HeightLimits implements ICubicWorld {
}
}
+
@Redirect(method = "spawnEntity", at = @At(value = "INVOKE", target = WORLD_IS_CHUNK_LOADED))
private boolean spawnEntity_isChunkLoaded(World world, int chunkX, int chunkZ, boolean allowEmpty, Entity ent) {
assert this == (Object) world;
diff --git a/src/main/java/cubicchunks/asm/mixin/fixes/common/MixinBlockFalling_HeightLimits.java b/src/main/java/cubicchunks/asm/mixin/fixes/common/MixinBlockFalling_HeightLimits.java
index c0ca1edf..55eddbb5 100644
--- a/src/main/java/cubicchunks/asm/mixin/fixes/common/MixinBlockFalling_HeightLimits.java
+++ b/src/main/java/cubicchunks/asm/mixin/fixes/common/MixinBlockFalling_HeightLimits.java
@@ -24,10 +24,8 @@
package cubicchunks.asm.mixin.fixes.common;
import static cubicchunks.asm.JvmNames.BLOCK_FALLING_CAN_FALL_THROUGH;
-import static cubicchunks.asm.JvmNames.BLOCK_POS_GETY;
import static cubicchunks.asm.JvmNames.WORLD_IS_AIR_BLOCK;
-import cubicchunks.asm.MixinUtils;
import cubicchunks.util.CubePos;
import cubicchunks.world.ICubicWorld;
import mcp.MethodsReturnNonnullByDefault;
diff --git a/src/main/java/cubicchunks/asm/mixin/noncritical/client/MixinGuiOverlayDebug.java b/src/main/java/cubicchunks/asm/mixin/noncritical/client/MixinGuiOverlayDebug.java
index 1842bf19..1dc30503 100644
--- a/src/main/java/cubicchunks/asm/mixin/noncritical/client/MixinGuiOverlayDebug.java
+++ b/src/main/java/cubicchunks/asm/mixin/noncritical/client/MixinGuiOverlayDebug.java
@@ -23,14 +23,10 @@
*/
package cubicchunks.asm.mixin.noncritical.client;
-import static cubicchunks.asm.JvmNames.BLOCK_POS_GETY;
-
-import cubicchunks.asm.MixinUtils;
import cubicchunks.world.ICubicWorld;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiOverlayDebug;
-import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -38,7 +34,6 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.Group;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
-import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.Slice;
import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/src/main/java/cubicchunks/asm/mixin/noncritical/common/MixinBlockPistonBase_HeightFix.java b/src/main/java/cubicchunks/asm/mixin/noncritical/common/MixinBlockPistonBase_HeightFix.java
index 03bb0dd0..43351083 100644
--- a/src/main/java/cubicchunks/asm/mixin/noncritical/common/MixinBlockPistonBase_HeightFix.java
+++ b/src/main/java/cubicchunks/asm/mixin/noncritical/common/MixinBlockPistonBase_HeightFix.java
@@ -23,9 +23,6 @@
*/
package cubicchunks.asm.mixin.noncritical.common;
-import static cubicchunks.asm.JvmNames.BLOCK_POS_GETY;
-
-import cubicchunks.asm.MixinUtils;
import cubicchunks.world.ICubicWorld;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.block.BlockPistonBase;
@@ -37,7 +34,6 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Group;
import org.spongepowered.asm.mixin.injection.Redirect;
-import org.spongepowered.asm.mixin.injection.Slice;
import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/src/main/java/cubicchunks/asm/mixin/noncritical/common/command/MixinCommandFill.java b/src/main/java/cubicchunks/asm/mixin/noncritical/common/command/MixinCommandFill.java
index 0359d901..8c3220b8 100644
--- a/src/main/java/cubicchunks/asm/mixin/noncritical/common/command/MixinCommandFill.java
+++ b/src/main/java/cubicchunks/asm/mixin/noncritical/common/command/MixinCommandFill.java
@@ -23,11 +23,9 @@
*/
package cubicchunks.asm.mixin.noncritical.common.command;
-import static cubicchunks.asm.JvmNames.BLOCK_POS_GETY;
import static cubicchunks.asm.JvmNames.ICOMMAND_SENDER_GET_ENTITY_WORLD;
import static cubicchunks.asm.JvmNames.WORLD_IS_BLOCK_LOADED;
-import cubicchunks.asm.MixinUtils;
import cubicchunks.world.ICubicWorld;
import cubicchunks.world.cube.Cube;
import mcp.MethodsReturnNonnullByDefault;
diff --git a/src/main/java/cubicchunks/asm/mixin/selectable/common/MixinWorldServer_UpdateBlocks.java b/src/main/java/cubicchunks/asm/mixin/selectable/common/MixinWorldServer_UpdateBlocks.java
index 321477a6..7b18e140 100644
--- a/src/main/java/cubicchunks/asm/mixin/selectable/common/MixinWorldServer_UpdateBlocks.java
+++ b/src/main/java/cubicchunks/asm/mixin/selectable/common/MixinWorldServer_UpdateBlocks.java
@@ -23,6 +23,7 @@
*/
package cubicchunks.asm.mixin.selectable.common;
+import cubicchunks.asm.CubicChunksCoremodConfig;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@@ -34,7 +35,7 @@ import net.minecraft.world.WorldServer;
@Mixin(value = WorldServer.class, priority = 1001)
public abstract class MixinWorldServer_UpdateBlocks implements ICubicWorldServer {
- /** This redirection (if selected by {@link cubicchunks.asm.CubicChunksMixinConfig})
+ /** This redirection (if selected by {@link CubicChunksCoremodConfig})
* will return value '0' instead of `getGameRules().getInt("randomTickSpeed")` for cubic type worlds.
* Redirected function is located inside WorldServer.updateBlocks() function at a line 404.
* Returned zero will cause `if (i > 0)` check at a line 474 to fail and random block ticks skipped.
diff --git a/src/main/java/cubicchunks/client/ClientEventHandler.java b/src/main/java/cubicchunks/client/ClientEventHandler.java
index 1ada1281..44a8c0ba 100644
--- a/src/main/java/cubicchunks/client/ClientEventHandler.java
+++ b/src/main/java/cubicchunks/client/ClientEventHandler.java
@@ -253,7 +253,7 @@ public class ClientEventHandler {
}
private static void refreshText(GuiCreateWorld gui, GuiButton enableBtn) {
enableBtn.displayString = I18n.format("cubicchunks.gui.worldmenu." +
- (CubicChunks.Config.BoolOptions.FORCE_CUBIC_CHUNKS.getValue() ? "cc_enable" : "cc_disable"));
+ (CubicChunks.Config.BoolOptions.CUBIC_CHUNKS_BY_DEFAULT.getValue() ? "cc_enable" : "cc_disable"));
}
@SubscribeEvent
@@ -281,7 +281,7 @@ public class ClientEventHandler {
break;
}
case CC_ENABLE_BUTTON_ID: {
- CubicChunks.Config.BoolOptions.FORCE_CUBIC_CHUNKS.flip();
+ CubicChunks.Config.BoolOptions.CUBIC_CHUNKS_BY_DEFAULT.flip();
refreshText((GuiCreateWorld) gui, button);
break;
}
@@ -290,7 +290,7 @@ public class ClientEventHandler {
}
@SubscribeEvent public static void onCreateWorldSettings(CreateNewWorldEvent event) {
- ((ICubicWorldSettings) (Object) event.settings).setCubic(CubicChunks.Config.BoolOptions.FORCE_CUBIC_CHUNKS.getValue());
+ ((ICubicWorldSettings) (Object) event.settings).setCubic(CubicChunks.Config.BoolOptions.CUBIC_CHUNKS_BY_DEFAULT.getValue());
}
private static boolean isCreateWorldGui(GuiScreen gui) {
diff --git a/src/main/java/cubicchunks/lighting/LightPropagator.java b/src/main/java/cubicchunks/lighting/LightPropagator.java
index f00790fe..a2930840 100644
--- a/src/main/java/cubicchunks/lighting/LightPropagator.java
+++ b/src/main/java/cubicchunks/lighting/LightPropagator.java
@@ -63,8 +63,8 @@ public class LightPropagator {
* centerPos.getX/Y/Z + }{@link LightUpdateQueue#MAX_POS} of centerPos (inclusive) with {@code
* LightUpdateQueue#MAX_DISTANCE + 1} buffer radius.
* <p>
- * WARNING: You probably shouldn't use this method directly and use {@link LightingManager#relightMultiBlock(BlockPos,
- * BlockPos, EnumSkyBlock)} instead
+ * WARNING: You probably shouldn't use this method directly and use {@link LightingManager#relightMultiBlock(BlockPos, BlockPos, EnumSkyBlock, Consumer)}
+ * instead
*
* @param centerPos position relative to which calculations are done. usually average position.
* @param coords contains all coords that need updating
diff --git a/src/main/java/cubicchunks/server/CubeProviderServer.java b/src/main/java/cubicchunks/server/CubeProviderServer.java
index ac954aec..faff66ce 100644
--- a/src/main/java/cubicchunks/server/CubeProviderServer.java
+++ b/src/main/java/cubicchunks/server/CubeProviderServer.java
@@ -24,7 +24,7 @@
package cubicchunks.server;
import cubicchunks.CubicChunks;
-import cubicchunks.asm.CubicChunksMixinConfig;
+import cubicchunks.asm.CubicChunksCoremodConfig;
import cubicchunks.server.chunkio.ICubeIO;
import cubicchunks.server.chunkio.RegionCubeIO;
import cubicchunks.server.chunkio.async.forge.AsyncWorldIOExecutor;
@@ -100,7 +100,7 @@ public class CubeProviderServer extends ChunkProviderServer implements ICubeProv
throw new UncheckedIOException(e);
}
- doRandomBlockTicksHere = CubicChunksMixinConfig.BoolOptions.RANDOM_TICK_IN_CUBE.getValue();
+ doRandomBlockTicksHere = CubicChunksCoremodConfig.MixinOptions.RANDOM_TICK_IN_CUBE.getValue();
}
@Override
@@ -267,14 +267,14 @@ public class CubeProviderServer extends ChunkProviderServer implements ICubeProv
/**
* Load a cube, asynchronously. The work done to retrieve the column is specified by the
- * {@link Requirement} <code>req</code>
+ * {@link Requirement} {@code req}
*
* @param cubeX Cube x position
* @param cubeY Cube y position
* @param cubeZ Cube z position
* @param req Work done to retrieve the column
- * @param callback Callback to be called when the load finishes. Note that <code>null</code> can be passed to the
- * callback if the work specified by <code>req</code> is not sufficient to provide a cube
+ * @param callback Callback to be called when the load finishes. Note that {@code null} can be passed to the
+ * callback if the work specified by {@code req} is not sufficient to provide a cube
*
* @see #getCube(int, int, int, Requirement) for the synchronous equivalent to this method
*/
@@ -347,11 +347,11 @@ public class CubeProviderServer extends ChunkProviderServer implements ICubeProv
* @param cubeX Cube x position
* @param cubeY Cube y position
* @param cubeZ Cube z positon
- * @param cube The loaded cube, if loaded, else <code>null</code>
+ * @param cube The loaded cube, if loaded, else {@code null}
* @param column The column of the cube
* @param req Work done on the cube
*
- * @return The processed cube, or <code>null</code> if the effort level is not sufficient to provide a cube
+ * @return The processed cube, or {@code null} if the effort level is not sufficient to provide a cube
*/
@Nullable
private Cube postCubeLoadAttempt(int cubeX, int cubeY, int cubeZ, @Nullable Cube cube, IColumn column, Requirement req) {
@@ -477,7 +477,7 @@ public class CubeProviderServer extends ChunkProviderServer implements ICubeProv
/**
* Retrieve a column, asynchronously. The work done to retrieve the column is specified by the
- * {@link Requirement} <code>req</code>
+ * {@link Requirement} {@code req}
*
* @param columnX Column x position
* @param columnZ Column z position
@@ -514,14 +514,14 @@ public class CubeProviderServer extends ChunkProviderServer implements ICubeProv
}
/**
- * After loading a column, do work on it, where the work required is specified by <code>req</code>
+ * After loading a column, do work on it, where the work required is specified by {@code req}
*
* @param columnX X position of the column
* @param columnZ Z position of the column
- * @param column The loaded column, or <code>null</code> if the column couldn't be loaded
+ * @param column The loaded column, or {@code null} if the column couldn't be loaded
* @param req The amount of work to be done on the cube
*
- * @return The postprocessed column, or <code>null</code>
+ * @return The postprocessed column, or {@code null}
*/
@Nullable
private IColumn postProcessColumn(int columnX, int columnZ, @Nullable IColumn column, Requirement req) {
diff --git a/src/main/java/cubicchunks/server/PlayerCubeMap.java b/src/main/java/cubicchunks/server/PlayerCubeMap.java
index 139eb56e..a5e1cc64 100644
--- a/src/main/java/cubicchunks/server/PlayerCubeMap.java
+++ b/src/main/java/cubicchunks/server/PlayerCubeMap.java
@@ -798,7 +798,7 @@ public class PlayerCubeMap extends PlayerChunkMap implements LightingManager.IHe
* Return iterator over 'CubeWatchers' of all cubes loaded
* by players. Iterator first element defined by seed.
*
- * @param seed
+ * @param seed seed that determines the first element
*/
public Iterator<CubeWatcher> getRandomWrappedCubeWatcherIterator(int seed) {
return this.cubeWatchers.randomWrappedIterator(seed);
diff --git a/src/main/java/cubicchunks/server/SpawnCubes.java b/src/main/java/cubicchunks/server/SpawnCubes.java
index 1e1c3adc..c44e0952 100644
--- a/src/main/java/cubicchunks/server/SpawnCubes.java
+++ b/src/main/java/cubicchunks/server/SpawnCubes.java
@@ -118,6 +118,7 @@ public class SpawnCubes {
int totalToGenerate = (radius * 2 + 1) * (radius * 2 + 1) * (radius * 2 + 1);
int generated = 0;
+ serverCubeCache.getCube(0, 0, 0, IProviderExtras.Requirement.LIGHT).getTickets().add(this);
for (int cubeX = spawnCubeX - radius; cubeX <= spawnCubeX + radius; cubeX++) {
for (int cubeZ = spawnCubeZ - radius; cubeZ <= spawnCubeZ + radius; cubeZ++) {
for (int cubeY = spawnCubeY + radius; cubeY >= spawnCubeY - radius; cubeY--) {
diff --git a/src/main/java/cubicchunks/server/chunkio/async/forge/AsyncIOProvider.java b/src/main/java/cubicchunks/server/chunkio/async/forge/AsyncIOProvider.java
index aa683b03..859acbe3 100644
--- a/src/main/java/cubicchunks/server/chunkio/async/forge/AsyncIOProvider.java
+++ b/src/main/java/cubicchunks/server/chunkio/async/forge/AsyncIOProvider.java
@@ -82,7 +82,7 @@ abstract class AsyncIOProvider<T> implements Runnable {
/**
* Check if any callbacks are registered as waiting for this load.
*
- * @return <code>true</code> if there is at least one callback waiting
+ * @return {@code true} if there is at least one callback waiting
*/
boolean hasCallbacks() {
return !callbacks.isEmpty();
diff --git a/src/main/java/cubicchunks/util/XYZMap.java b/src/main/java/cubicchunks/util/XYZMap.java
index 8d2e2402..715e2c0b 100644
--- a/src/main/java/cubicchunks/util/XYZMap.java
+++ b/src/main/java/cubicchunks/util/XYZMap.java
@@ -151,7 +151,7 @@ public class XYZMap<T extends XYZAddressable> implements Iterable<T> {
* Computes the next index to the right of the given index, wrapping around
* if necessary.
*
- * @param index the previous index
+ * @param pointerIndex the previous index
*
* @return the next index
*/
@@ -345,8 +345,6 @@ public class XYZMap<T extends XYZAddressable> implements Iterable<T> {
/**
* Removes the value contained at the given index by shifting suitable
* values on its right to the left.
- *
- * @param index
*
* @param holePointerIndex the index of the ponter to be collapsed
* @param holeIndex an index of the bucket to be collapsed
diff --git a/src/main/java/cubicchunks/world/ICubicWorldClient.java b/src/main/java/cubicchunks/world/ICubicWorldClient.java
index 2fe2312d..0e7933b3 100644
--- a/src/main/java/cubicchunks/world/ICubicWorldClient.java
+++ b/src/main/java/cubicchunks/world/ICubicWorldClient.java
@@ -38,8 +38,8 @@ public interface ICubicWorldClient extends ICubicWorld {
/**
* Initializes the world to be a CubicChunks world. Must be done before any players are online and before any chunks
* are loaded. Cannot be used more than once.
- * @param heightRange
- * @param generationRange
+ * @param heightRange World min and max height
+ * @param generationRange Expected minimum and maximum terrain generation heights
*/
void initCubicWorldClient(IntRange heightRange, IntRange generationRange);
diff --git a/src/main/java/cubicchunks/world/ICubicWorldServer.java b/src/main/java/cubicchunks/world/ICubicWorldServer.java
index 944642af..8e928ef6 100644
--- a/src/main/java/cubicchunks/world/ICubicWorldServer.java
+++ b/src/main/java/cubicchunks/world/ICubicWorldServer.java
@@ -45,8 +45,8 @@ public interface ICubicWorldServer extends ICubicWorld, IConfigUpdateListener {
/**
* Initializes the world to be a CubicChunks world. Must be done before any players are online and before any chunks
* are loaded. Cannot be used more than once.
- * @param heightRange
- * @param generationRange
+ * @param heightRange World min and max height
+ * @param generationRange Expected minimum and maximum terrain generation heights
*/
void initCubicWorldServer(IntRange heightRange, IntRange generationRange);
diff --git a/src/main/java/cubicchunks/world/IProviderExtras.java b/src/main/java/cubicchunks/world/IProviderExtras.java
index 859b79d0..008de68c 100644
--- a/src/main/java/cubicchunks/world/IProviderExtras.java
+++ b/src/main/java/cubicchunks/world/IProviderExtras.java
@@ -35,19 +35,19 @@ import javax.annotation.ParametersAreNonnullByDefault;
public interface IProviderExtras {
/**
- * Retrieve a column. The work done to retrieve the column is specified by the {@link Requirement} <code>req</code>
+ * Retrieve a column. The work done to retrieve the column is specified by the {@link Requirement} {@code req}
*
* @param columnX Column x position
* @param columnZ Column z position
* @param req Work done to retrieve the column
*
- * @return the column, or <code>null</code> if no column could be created with the specified requirement level
+ * @return the column, or {@code null} if no column could be created with the specified requirement level
*/
@Nullable
IColumn getColumn(int columnX, int columnZ, Requirement req);
/**
- * Retrieve a cube. The work done to retrieve the cube is specified by {@link Requirement} <code>req</code>
+ * Retrieve a cube. The work done to retrieve the cube is specified by {@link Requirement} {@code req}
*
* @param cubeX the cube's x coordinate
* @param cubeY the cube's y coordinate
@@ -62,7 +62,7 @@ public interface IProviderExtras {
/**
* The effort made to retrieve a cube or column. Any further work should not be done, and returning
- * <code>null</code> is acceptable in those cases
+ * {@code null} is acceptable in those cases
*/
enum Requirement {
// Warning, don't modify order of these constants - ordinals are used in comparisons
diff --git a/src/main/java/cubicchunks/world/column/CubeMap.java b/src/main/java/cubicchunks/world/column/CubeMap.java
index 85b431cd..1a3ce8e8 100644
--- a/src/main/java/cubicchunks/world/column/CubeMap.java
+++ b/src/main/java/cubicchunks/world/column/CubeMap.java
@@ -54,7 +54,7 @@ public class CubeMap implements Iterable<Cube> {
*
* @param cubeY cube y position
*
- * @return the removed cube if it existed, otherwise <code>null</code>
+ * @return the removed cube if it existed, otherwise {@code null}
*/
@Nullable public Cube remove(int cubeY) {
int index = binarySearch(cubeY);
@@ -75,8 +75,8 @@ public class CubeMap implements Iterable<Cube> {
}
/**
- * Iterate over all cubes between <code>startY</code> and <code>endY</code> in this storage in order. If
- * <code>startY < endY</code>, order is bottom to top, otherwise order is top to bottom.
+ * Iterate over all cubes between {@code startY} and {@code endY} in this storage in order. If
+ * {@code startY < endY}, order is bottom to top, otherwise order is top to bottom.
*
* @param startY initial cube y position
* @param endY last cube y position
@@ -108,7 +108,7 @@ public class CubeMap implements Iterable<Cube> {
* @param cubeY the y coordinate of the cube
* @param searchIndex the index to search at (got form {@link #binarySearch(int)})
*
- * @return <code>true</code> if the cube is contained here, <code>false</code> otherwise
+ * @return {@code true} if the cube is contained here, {@code false} otherwise
*/
private boolean contains(int cubeY, int searchIndex) {
return searchIndex < cubes.size() && cubes.get(searchIndex).getY() == cubeY;
@@ -135,7 +135,7 @@ public class CubeMap implements Iterable<Cube> {
/**
* Check if this storage is empty
*
- * @return <code>true</code> if there are no cubes in this storage, <code>false</code> otherwise
+ * @return {@code true} if there are no cubes in this storage, {@code false} otherwise
*/
public boolean isEmpty() {
return cubes.isEmpty();
diff --git a/src/main/java/cubicchunks/world/column/IColumn.java b/src/main/java/cubicchunks/world/column/IColumn.java
index 6b1ad019..f366cbdf 100644
--- a/src/main/java/cubicchunks/world/column/IColumn.java
+++ b/src/main/java/cubicchunks/world/column/IColumn.java
@@ -178,8 +178,8 @@ public interface IColumn {
*
* @param pos target location
*
- * @return <code>true</code> if there is no block between this block and the sky (including this block),
- * <code>false</code> otherwise
+ * @return {@code true} if there is no block between this block and the sky (including this block),
+ * {@code false} otherwise
* <p>
* CHECKED: 1.11-13.19.0.2148
*/
@@ -191,8 +191,8 @@ public interface IColumn {
* @param pos target location
* @param createType how fast the tile entity is needed
*
- * @return the tile entity at the specified location, or <code>null</code> if there is no entity and
- * <code>createType</code> was not {@link net.minecraft.world.chunk.Chunk.EnumCreateEntityType#IMMEDIATE}
+ * @return the tile entity at the specified location, or {@code null} if there is no entity and
+ * {@code createType} was not {@link net.minecraft.world.chunk.Chunk.EnumCreateEntityType#IMMEDIATE}
*
* @see Cube#getTileEntity(BlockPos, Chunk.EnumCreateEntityType)
*/
@@ -264,8 +264,8 @@ public interface IColumn {
*
* @param flag unused
*
- * @return <code>true</code> if there were modifications since the time this column was loaded from disk,
- * <code>false</code> otherwise
+ * @return {@code true} if there were modifications since the time this column was loaded from disk,
+ * {@code false} otherwise
*/
boolean needsSaving(boolean flag);
@@ -293,7 +293,7 @@ public interface IColumn {
* @param minBlockY Lower end of the section being checked
* @param maxBlockY Upper end of the section being checked
*
- * @return <code>true</code> if there is only air blocks in the checked cubes, <code>false</code> otherwise
+ * @return {@code true} if there is only air blocks in the checked cubes, {@code false} otherwise
*/
boolean isEmptyBetween(int minBlockY, int maxBlockY);
@@ -322,7 +322,7 @@ public interface IColumn {
/**
* Check if this column needs to be ticked
*
- * @return <code>true</code> if any cube in this column needs to be ticked, <code>false</code> otherwise
+ * @return {@code true} if any cube in this column needs to be ticked, {@code false} otherwise
*/
boolean shouldTick();
@@ -349,13 +349,13 @@ public interface IColumn {
Collection<Cube> getLoadedCubes();
/**
- * Iterate over all loaded cubes in this column in order. If <code>startY < endY</code>, order is bottom to top,
+ * Iterate over all loaded cubes in this column in order. If {@code startY < endY}, order is bottom to top,
* otherwise order is top to bottom.
*
* @param startY initial cube y position
* @param endY last cube y position
*
- * @return an iterator over all loaded cubes between <code>startY</code> and <code>endY</code>
+ * @return an iterator over all loaded cubes between {@code startY} and {@code endY}
*/
Iterable<Cube> getLoadedCubes(int startY, int endY);
@@ -364,7 +364,7 @@ public interface IColumn {
*
* @param cubeY cube y position
*
- * @return the cube at that position, or <code>null</code> if it is not loaded
+ * @return the cube at that position, or {@code null} if it is not loaded
*/
@Nullable Cube getLoadedCube(int cubeY);
@@ -389,14 +389,14 @@ public interface IColumn {
*
* @param cubeY cube y position
*
- * @return the removed cube if it existed, otherwise <code>null</code>
+ * @return the removed cube if it existed, otherwise {@code null}
*/
@Nullable Cube removeCube(int cubeY);
/**
* Check if there are any loaded cube in this column
*
- * @return <code>true</code> if there is at least on loaded cube in this column, <code>false</code> otherwise
+ * @return {@code true} if there is at least on loaded cube in this column, {@code false} otherwise
*/
boolean hasLoadedCubes();
diff --git a/src/main/java/cubicchunks/world/cube/Cube.java b/src/main/java/cubicchunks/world/cube/Cube.java
index bb68417d..53fb8091 100644
--- a/src/main/java/cubicchunks/world/cube/Cube.java
+++ b/src/main/java/cubicchunks/world/cube/Cube.java
@@ -317,7 +317,7 @@ public class Cube implements XYZAddressable {
*
* @param pos position where the tile entity should be placed
*
- * @return the created tile entity, or <code>null</code> if the block at that position does not provide tile
+ * @return the created tile entity, or {@code null} if the block at that position does not provide tile
* entities
*/
@Nullable
@@ -337,8 +337,8 @@ public class Cube implements XYZAddressable {
* @param pos target location
* @param createType how fast the tile entity is needed
*
- * @return the tile entity at the specified location, or <code>null</code> if there is no entity and
- * <code>createType</code> was not {@link net.minecraft.world.chunk.Chunk.EnumCreateEntityType#IMMEDIATE}
+ * @return the tile entity at the specified location, or {@code null} if there is no entity and
+ * {@code createType} was not {@link net.minecraft.world.chunk.Chunk.EnumCreateEntityType#IMMEDIATE}
*/
@Nullable public TileEntity getTileEntity(BlockPos pos, Chunk.EnumCreateEntityType createType) {
return column.getTileEntity(pos, createType);
@@ -451,7 +451,7 @@ public class Cube implements XYZAddressable {
/**
* Check if there are any non-air blocks in this cube
*
- * @return <code>true</code> if this cube contains only air blocks, <code>false</code> otherwise
+ * @return {@code true} if this cube contains only air blocks, {@code false} otherwise
*/
public boolean isEmpty() {
return storage == null || this.storage.isEmpty();
@@ -524,7 +524,7 @@ public class Cube implements XYZAddressable {
*
* @param blockPos the position of the block
*
- * @return <code>true</code> if the position is within this cube, <code>false</code> otherwise
+ * @return {@code true} if the position is within this cube, {@code false} otherwise
*/
public boolean containsBlockPos(BlockPos blockPos) {
return this.coords.getX() == blockToCube(blockPos.getX())
@@ -630,7 +630,7 @@ public class Cube implements XYZAddressable {
/**
* Check if any modifications happened to this cube since it was loaded from disk
*
- * @return <code>true</code> if this cube should be written back to disk
+ * @return {@code true} if this cube should be written back to disk
*/
public boolean needsSaving() {
return this.entities.needsSaving(true, this.world.getTotalWorldTime(), this.isModified);
@@ -702,7 +702,7 @@ public class Cube implements XYZAddressable {
* cubicchunks.worldgen.generator.ICubeGenerator#populate(Cube)}. Check there for more information regarding
* population.
*
- * @return <code>true</code> if this cube has been populated, <code>false</code> otherwise
+ * @return {@code true} if this cube has been populated, {@code false} otherwise
*/
public boolean isPopulated() {
return isPopulated;
@@ -725,7 +725,7 @@ public class Cube implements XYZAddressable {
* argument to {@link cubicchunks.worldgen.generator.ICubeGenerator#populate(Cube)}. Check there for more
* information regarding population
*
- * @return <code>true</code> if this cube has been populated, <code>false</code> otherwise
+ * @return {@code true} if this cube has been populated, {@code false} otherwise
*/
public boolean isFullyPopulated() {
return this.isFullyPopulated;
@@ -760,7 +760,7 @@ public class Cube implements XYZAddressable {
/**
* Check whether this cube's initial diffuse skylight has been calculated
*
- * @return <code>true</code> if it has been calculated, <code>false</code> otherwise
+ * @return {@code true} if it has been calculated, {@code false} otherwise
*/
public boolean isInitialLightingDone() {
return isInitialLightingDone;
diff --git a/src/main/java/cubicchunks/world/type/CustomCubicWorldType.java b/src/main/java/cubicchunks/world/type/CustomCubicWorldType.java
index 0a2deb12..24e1fb54 100644
--- a/src/main/java/cubicchunks/world/type/CustomCubicWorldType.java
+++ b/src/main/java/cubicchunks/world/type/CustomCubicWorldType.java
@@ -98,7 +98,8 @@ public class CustomCubicWorldType extends WorldType implements ICubicWorldType {
@SideOnly(Side.CLIENT)
public void onCustomizeButton(Minecraft mc, GuiCreateWorld guiCreateWorld) {
- if (Loader.isModLoaded("malisiscore")) {
+ if (true||Loader.isModLoaded("malisiscore")) {
+
new CustomCubicGui(guiCreateWorld).display();
} else {
mc.displayGuiScreen(new GuiErrorScreen("MalisisCore not found!",
diff --git a/src/main/java/cubicchunks/worldgen/generator/custom/CustomGeneratorSettings.java b/src/main/java/cubicchunks/worldgen/generator/custom/CustomGeneratorSettings.java
index 7183192f..e6e6efdf 100644
--- a/src/main/java/cubicchunks/worldgen/generator/custom/CustomGeneratorSettings.java
+++ b/src/main/java/cubicchunks/worldgen/generator/custom/CustomGeneratorSettings.java
@@ -41,8 +41,8 @@ import cubicchunks.worldgen.generator.custom.biome.replacer.BiomeBlockReplacerCo
import net.minecraft.world.gen.ChunkGeneratorSettings;
public class CustomGeneratorSettings {
- /**
- * Note: many of these values are unused yet
+ /*
+ Note: many of these values are unused yet
*/
/**
diff --git a/src/main/java/cubicchunks/worldgen/generator/custom/CustomTerrainGenerator.java b/src/main/java/cubicchunks/worldgen/generator/custom/CustomTerrainGenerator.java
index bb31a2e0..fc1f0c11 100644
--- a/src/main/java/cubicchunks/worldgen/generator/custom/CustomTerrainGenerator.java
+++ b/src/main/java/cubicchunks/worldgen/generator/custom/CustomTerrainGenerator.java
@@ -165,10 +165,10 @@ public class CustomTerrainGenerator extends BasicCubeGenerator {
}
@Override public void populate(Cube cube) {
- /**
- * If event is not canceled we will use default biome decorators and
- * cube populators from registry.
- **/
+ /*
+ If event is not canceled we will use default biome decorators and
+ cube populators from registry.
+ */
if (!MinecraftForge.EVENT_BUS.post(new CubePopulatorEvent(world, cube))) {
CubicBiome biome = CubicBiome.getCubic(cube.getCubicWorld().getBiome(Coords.getCubeCenter(cube)));
diff --git a/src/main/java/cubicchunks/worldgen/generator/flat/FlatTerrainProcessor.java b/src/main/java/cubicchunks/worldgen/generator/flat/FlatTerrainProcessor.java
index a0d30ceb..efeae4f0 100644
--- a/src/main/java/cubicchunks/worldgen/generator/flat/FlatTerrainProcessor.java
+++ b/src/main/java/cubicchunks/worldgen/generator/flat/FlatTerrainProcessor.java
@@ -92,9 +92,9 @@ public class FlatTerrainProcessor extends BasicCubeGenerator {
@Override
public void populate(Cube cube) {
- /**
- * If event is not canceled we will use cube populators from registry.
- **/
+ /*
+ If event is not canceled we will use cube populators from registry.
+ */
if (!MinecraftForge.EVENT_BUS.post(new CubePopulatorEvent(world, cube))) {
CubeGeneratorsRegistry.generateWorld(cube.getCubicWorld(), new Random(cube.cubeRandomSeed()),
cube.getCoords(), CubicBiome.getCubic(world.getBiome(cube.getCoords().getCenterBlockPos())));
diff --git a/src/main/java/cubicchunks/worldgen/gui/TerrainPreview.java b/src/main/java/cubicchunks/worldgen/gui/TerrainPreview.java
new file mode 100644
index 00000000..664e6560
--- /dev/null
+++ b/src/main/java/cubicchunks/worldgen/gui/TerrainPreview.java
@@ -0,0 +1,380 @@
+/*
+ * This file is part of Cubic Chunks Mod, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2015 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package cubicchunks.worldgen.gui;
+
+import static com.flowpowered.noise.Noise.gradientNoise3D;
+import static cubicchunks.worldgen.gui.CustomCubicGui.HORIZONTAL_INSETS;
+import static cubicchunks.worldgen.gui.CustomCubicGui.HORIZONTAL_PADDING;
+import static cubicchunks.worldgen.gui.CustomCubicGuiUtils.makeCheckbox;
+import static cubicchunks.worldgen.gui.CustomCubicGuiUtils.malisisText;
+
+import com.flowpowered.noise.NoiseQuality;
+import com.flowpowered.noise.Utils;
+import com.google.common.eventbus.Subscribe;
+import cubicchunks.CubicChunks;
+import cubicchunks.api.worldgen.biome.CubicBiome;
+import cubicchunks.util.MathUtil;
+import cubicchunks.worldgen.generator.custom.ConversionUtils;
+import cubicchunks.worldgen.generator.custom.CustomGeneratorSettings;
+import cubicchunks.worldgen.gui.component.ShaderMultiImageView;
+import cubicchunks.worldgen.gui.component.TerrainPreviewScaleOverlay;
+import cubicchunks.worldgen.gui.component.UIBorderLayout;
+import cubicchunks.worldgen.gui.component.UIVerticalTableLayout;
+import cubicchunks.worldgen.gui.render.RawFloatImage;
+import net.malisis.core.client.gui.GuiRenderer;
+import net.malisis.core.client.gui.component.UIComponent;
+import net.malisis.core.client.gui.component.container.UIContainer;
+import net.malisis.core.client.gui.component.control.IControlComponent;
+import net.malisis.core.client.gui.component.interaction.UICheckBox;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.texture.ITextureObject;
+import net.minecraft.client.shader.ShaderManager;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.world.biome.Biome;
+import net.minecraftforge.fml.common.registry.ForgeRegistries;
+import org.lwjgl.util.vector.Matrix4f;
+import org.lwjgl.util.vector.Vector2f;
+import org.lwjgl.util.vector.Vector3f;
+import org.lwjgl.util.vector.Vector4f;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.FloatBuffer;
+import java.util.function.Consumer;
+
+public class TerrainPreview {
+
+ private final UIBorderLayout borderContainer;
+ private Matrix4f previewTransform = new Matrix4f();
+ private float biomeScale = 0.01f;
+ private float biomeOffset = 0;
+
+ UICheckBox keepPreviewVisible;
+
+ public TerrainPreview(CustomCubicGui gui) {
+ ShaderMultiImageView<?> view;
+
+ RawFloatImage img = generateNoiseTexture();
+ RawFloatImage biomes = generateBiomesTexture();
+ view = createImageView(gui, img, biomes);
+
+ TerrainPreviewScaleOverlay overlay = new TerrainPreviewScaleOverlay(gui, view);
+
+ view.addOnShaderTick(shader -> {
+ CustomGeneratorSettings conf = gui.getConfig();
+
+ shader.getShaderUniformOrDefault("previewTransform").set(getZoomOffsetMatrix());
+ shader.getShaderUniformOrDefault("waterLevel").set(conf.waterLevel);
+
+ shader.getShaderUniformOrDefault("heightVariationFactor").set(conf.heightVariationFactor);
+ shader.getShaderUniformOrDefault("heightVariationSpecial").set(conf.specialHeightVariationFactorBelowAverageY);
+ shader.getShaderUniformOrDefault("heightVariationOffset").set(conf.heightVariationOffset);
+ shader.getShaderUniformOrDefault("heightFactor").set(conf.heightFactor);
+ shader.getShaderUniformOrDefault("heightOffset").set(conf.heightOffset);
+
+ shader.getShaderUniformOrDefault("depthFactor").set(conf.depthNoiseFactor);
+ shader.getShaderUniformOrDefault("depthOffset").set(conf.depthNoiseOffset);
+ shader.getShaderUniformOrDefault("depthFreq").set(conf.depthNoiseFrequencyX, conf.depthNoiseFrequencyZ);
+ // this set method should be named setSafeInts
+ shader.getShaderUniformOrDefault("depthOctaves").set(conf.depthNoiseOctaves, 0, 0, 0);
+
+ shader.getShaderUniformOrDefault("selectorFactor").set(conf.selectorNoiseFactor);
+ shader.getShaderUniformOrDefault("selectorOffset").set(conf.selectorNoiseOffset);
+ shader.getShaderUniformOrDefault("selectorFreq").set(
+ conf.selectorNoiseFrequencyX, conf.selectorNoiseFrequencyY, conf.selectorNoiseFrequencyZ);
+ shader.getShaderUniformOrDefault("selectorOctaves").set(conf.selectorNoiseOctaves, 0, 0, 0);
+
+ shader.getShaderUniformOrDefault("lowFactor").set(conf.lowNoiseFactor);
+ shader.getShaderUniformOrDefault("lowOffset").set(conf.lowNoiseOffset);
+ shader.getShaderUniformOrDefault("lowFreq").set(conf.lowNoiseFrequencyX, conf.lowNoiseFrequencyY, conf.lowNoiseFrequencyZ);
+ shader.getShaderUniformOrDefault("lowOctaves").set(conf.lowNoiseOctaves, 0, 0, 0);
+
+ shader.getShaderUniformOrDefault("highFactor").set(conf.highNoiseFactor);
+ shader.getShaderUniformOrDefault("highOffset").set(conf.highNoiseOffset);
+ shader.getShaderUniformOrDefault("highFreq").set(conf.highNoiseFrequencyX, conf.highNoiseFrequencyY, conf.highNoiseFrequencyZ);
+ shader.getShaderUniformOrDefault("highOctaves").set(conf.highNoiseOctaves, 0, 0, 0);
+
+ overlay.setTransform(previewTransform.m00, previewTransform.m30, previewTransform.m31);
+ });
+
+ view.addOnMouseDrag((lastX, lastY, x, y, button) -> {
+ previewTransform = previewTransform.translate(new Vector2f(lastX - x, y - lastY));
+ });
+ view.addControlComponent(new IControlComponent() {
+ public static final long ANIMATION_LENGTH = 300; //ms
+ float startZoom = 1;
+ float targetZoom = 1;
+ long animationStartTime = 0, animationEndTime = 0;
+
+ @Override public void setParent(UIComponent<?> uiComponent) {
+ }
+
+ @Override public UIComponent<?> getParent() {
+ return null;
+ }
+
+ @Override public UIComponent<?> getComponentAt(int i, int i1) {
+ return null;
+ }
+
+ @Override public boolean onKeyTyped(char c, int i) {
+ return false;
+ }
+
+ @Override public boolean onScrollWheel(int x, int y, int delta) {
+ if (delta > 0) {
+ for (int i = 0; i < delta; i++) {
+ targetZoom /= Math.sqrt(2);
+ }
+ } else {
+ for (int i = 0; i < -delta; i++) {
+ targetZoom *= Math.sqrt(2);
+ }
+ }
+ if (delta != 0) {
+ resetAnimation();
+ }
+ return true;
+ }
+
+ private void resetAnimation() {
+ animationStartTime = System.currentTimeMillis();
+ animationEndTime = animationStartTime + ANIMATION_LENGTH;
+ startZoom = previewTransform.m00; // this relies on no rotation, and zoom being the same in all directions
+ }
+
+ @Override public void draw(GuiRenderer guiRenderer, int mouseX, int mouseY, float v) {
+ float progress = MathUtil.unlerp(System.currentTimeMillis(), animationStartTime, animationEndTime);
+ if (Double.isNaN(progress) || Double.isInfinite(progress)) {
+ updateZoom(targetZoom, mouseX - view.getX(), mouseY - view.getY());
+ return;
+ }
+ progress = MathHelper.clamp(progress, 0, 1);
+ updateZoom(MathUtil.lerp(progress, startZoom, targetZoom), mouseX - view.screenX() - view.getWidth() / 2, mouseY - view.screenY()
+ - view.getHeight() / 2);
+ }
+ });
+
+ overlay.setSize(UIComponent.INHERITED - 200, 128);
+
+ UIBorderLayout borderLayout = new UIBorderLayout(gui);
+ borderLayout.setSize(UIComponent.INHERITED, 128);
+ borderLayout.add(overlay, UIBorderLayout.Border.LEFT);
+
+ UIContainer<?> settingsContrainer = new UIVerticalTableLayout(gui, 4)
+ .setInsets(5, 5, 5, 5)
+ .add(keepPreviewVisible = makeCheckbox(gui, "keepPreviewVisible", true), new UIVerticalTableLayout.GridLocation(0, 0, 4));
+ settingsContrainer.setSize(200, 128);
+
+ borderLayout.add(settingsContrainer, UIBorderLayout.Border.RIGHT);
+
+ this.borderContainer = borderLayout;
+ }
+
+ private RawFloatImage generateBiomesTexture() {
+ // TODO: this duplicates vanilla code, and code already in BiomeSource, reuse the BiomeSource code directly?
+ int samplesPerBiome = 16;
+ int count = CubicBiome.REGISTRY.getValues().size();
+ float[][] data = new float[count * samplesPerBiome][2];// 2 values per biome
+ CubicBiome[] biomes = CubicBiome.REGISTRY.getValues().toArray(new CubicBiome[0]);
+
+ int smoothRadius = 2;
+ double[] nearBiomeWeightArray = new double[smoothRadius * 2 + 1];
+ for (int z = -smoothRadius; z <= smoothRadius; z++) {
+ double val = 0;
+ // add up all the weights from the other axis to "simulate" infinitely long lines of biomes
+ for (int x = -smoothRadius; x <= smoothRadius; x++) {
+ val += 10.0F / Math.sqrt(x * x + z * z + 0.2F);
+ }
+
+ nearBiomeWeightArray[z + smoothRadius] = val;
+ }
+
+ for (int x = 0; x < count * samplesPerBiome; x++) {
+ double totalHeight = 0;
+ double totalHeightVariation = 0;
+ double totalWeight = 0;
+
+ int centerIdx = Math.floorDiv(x, samplesPerBiome);
+ CubicBiome centerBiome = biomes[centerIdx];
+
+ for (int dx = -smoothRadius; dx <= smoothRadius; dx++) {
+ int pos = x + dx;
+ int biomeIdx = Math.floorMod(Math.floorDiv(pos, samplesPerBiome), count);
+ CubicBiome biome = biomes[biomeIdx];
+
+ double biomeWeight = nearBiomeWeightArray[dx + smoothRadius];
+
+ double biomeHeight = biome.getBiome().getBaseHeight();
+ if (biomeHeight > centerBiome.getBiome().getBaseHeight()) {
+ // prefer biomes with lower height?
+ biomeWeight /= 2.0F;
+ }
+
+ totalHeight += biomeHeight * biomeWeight;
+ totalWeight += biomeWeight;
+ totalHeightVariation += biome.getBiome().getHeightVariation() * biomeWeight;
+ }
+
+ totalHeight /= totalWeight;
+ totalHeightVariation /= totalWeight;
+
+ data[x][0] = ConversionUtils.biomeHeightVanilla((float) totalHeight);
+ data[x][1] = ConversionUtils.biomeHeightVariationVanilla((float) totalHeightVariation);
+ }
+
+ RawFloatImage obj = new RawFloatImage(data, 2);
+ obj.loadTexture(null);
+ return obj;
+ }
+
+ public void onSetKeepVisible(Consumer<Boolean> handler) {
+ this.keepPreviewVisible.register(new Object() {
+ @Subscribe
+ public void onSet(UICheckBox.CheckEvent evt) {
+ handler.accept(evt.isChecked());
+ }
+ });
+ }
+
+ private Matrix4f getZoomOffsetMatrix() {
+ return previewTransform.transpose(new Matrix4f());
+ }
+
+ private void updateZoom(float newZoom, float mouseX, float mouseY) {
+ float scale = newZoom / previewTransform.m00;
+ previewTransform.translate(new Vector2f(mouseX, -mouseY))
+ .scale(new Vector3f(scale, scale, scale))
+ .translate(new Vector2f(-mouseX, mouseY));
+ }
+
+ private ShaderMultiImageView<?> createImageView(CustomCubicGui gui, RawFloatImage img, RawFloatImage biomes) {
+ // Note: the actual resource location name used will be "shaders/program/" + resourceName + ".json"
+ ShaderMultiImageView<?> view;
+ ShaderManager shader = null;
+ try {
+ shader = new ShaderManager(Minecraft.getMinecraft().getResourceManager(), CubicChunks.MODID + ":custom-cubic-preview");
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ shader.addSamplerTexture("perlin1", img);
+ shader.addSamplerTexture("biomes", biomes);
+ view = new ShaderMultiImageView(gui, shader, img, biomes);
+ return view;
+ }
+
+ private RawFloatImage generateNoiseTexture() {
+ float[][] data = new float[256][256];
+ float max = 0, min = 0;
+ for (int i = 0; i < data.length; i++) {
+ for (int j = 0; j < data[i].length; j++) {
+ data[i][j] = (float) gradientCoherentNoise3DTileable(i * 0.125, j * 0.125, 0, 123456, NoiseQuality.BEST, data.length / 8 - 1);
+ if (data[i][j] > max) {
+ max = data[i][j];
+ }
+ if (data[i][j] < min) {
+ min = data[i][j];
+ }
+ }
+ }
+ System.out.println("MIN=" + min + ", MAX=" + max);
+ RawFloatImage img = new RawFloatImage(data, 1);
+ img.loadTexture(null);
+ return img;
+ }
+
+
+ private static double gradientCoherentNoise3DTileable(double x, double y, double z, int seed, NoiseQuality quality, int mask) {
+
+ // Create a unit-length cube aligned along an integer boundary. This cube
+ // surrounds the input point.
+
+ int x0 = ((x >= 0.0) ? (int) x : (int) x - 1);
+ int x1 = x0 + 1;
+
+ int y0 = ((y >= 0.0) ? (int) y : (int) y - 1);
+ int y1 = y0 + 1;
+
+ int z0 = ((z >= 0.0) ? (int) z : (int) z - 1);
+ int z1 = z0 + 1;
+
+ double fx = x - x0, fy = y - y0, fz = z - z0;
+ // Map the difference between the coordinates of the input value and the
+ // coordinates of the cube's outer-lower-left vertex onto an S-curve.
+ double xs, ys, zs;
+ if (quality == NoiseQuality.FAST) {
+ xs = fx;
+ ys = fy;
+ zs = fz;
+ } else if (quality == NoiseQuality.STANDARD) {
+ xs = Utils.sCurve3(fx);
+ ys = Utils.sCurve3(fy);
+ zs = Utils.sCurve3(fz);
+ } else {
+
+ xs = Utils.sCurve5(fx);
+ ys = Utils.sCurve5(fy);
+ zs = Utils.sCurve5(fz);
+ }
+
+ x0 &= mask;
+ x1 &= mask;
+ y0 &= mask;
+ y1 &= mask;
+ z0 &= mask;
+ z1 &= mask;
+
+ // Now calculate the noise values at each vertex of the cube. To generate
+ // the coherent-noise value at the input point, interpolate these eight
+ // noise values using the S-curve value as the interpolant (trilinear
+ // interpolation.)
+ double n0, n1, ix0, ix1, iy0, iy1;
+ n0 = gradientNoise3D(x0 + fx, y0 + fy, z0 + fz, x0, y0, z0, seed);
+ n1 = gradientNoise3D(x1 + fx - 1, y0 + fy, z0 + fz, x1, y0, z0, seed);
+ ix0 = Utils.linearInterp(n0, n1, xs);
+
+ n0 = gradientNoise3D(x0 + fx, y1 + fy - 1, z0 + fz, x0, y1, z0, seed);
+ n1 = gradientNoise3D(x1 + fx - 1, y1 + fy - 1, z0 + fz, x1, y1, z0, seed);
+ ix1 = Utils.linearInterp(n0, n1, xs);
+ iy0 = Utils.linearInterp(ix0, ix1, ys);
+ n0 = gradientNoise3D(x0 + fx, y0 + fy, z1 + fz - 1, x0, y0, z1, seed);
+ n1 = gradientNoise3D(x1 + fx - 1, y0 + fy, z1 + fz - 1, x1, y0, z1, seed);
+ ix0 = Utils.linearInterp(n0, n1, xs);
+ n0 = gradientNoise3D(x0 + fx, y1 + fy - 1, z1 + fz - 1, x0, y1, z1, seed);
+ n1 = gradientNoise3D(x1 + fx - 1, y1 + fy - 1, z1 + fz - 1, x1, y1, z1, seed);
+ ix1 = Utils.linearInterp(n0, n1, xs);
+ iy1 = Utils.linearInterp(ix0, ix1, ys);
+ return Utils.linearInterp(iy0, iy1, zs) * 2 - 1;
+ }
+
+ public UIContainer<?> containerWithPadding() {
+ borderContainer.setPadding(HORIZONTAL_PADDING + HORIZONTAL_INSETS, 0);
+ return borderContainer;
+ }
+
+ public UIContainer<?> containerNoPadding() {
+ borderContainer.setPadding(0, 0);
+ return borderContainer;
+ }
+}
diff --git a/src/main/java/cubicchunks/worldgen/gui/component/ShaderMultiImageView.java b/src/main/java/cubicchunks/worldgen/gui/component/ShaderMultiImageView.java
new file mode 100644
index 00000000..6e9fb036
--- /dev/null
+++ b/src/main/java/cubicchunks/worldgen/gui/component/ShaderMultiImageView.java
@@ -0,0 +1,99 @@
+/*
+ * This file is part of Cubic Chunks Mod, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2015 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package cubicchunks.worldgen.gui.component;
+
+import cubicchunks.worldgen.gui.event.IMouseDragListener;
+import net.malisis.core.client.gui.GuiRenderer;
+import net.malisis.core.client.gui.MalisisGui;
+import net.malisis.core.client.gui.component.UIComponent;
+import net.malisis.core.renderer.icon.Icon;
+import net.malisis.core.util.MouseButton;
+import net.minecraft.client.renderer.texture.ITextureObject;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.client.shader.ShaderManager;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+
+public class ShaderMultiImageView<T extends ShaderMultiImageView<T>> extends UIComponent<T> {
+
+ private final Icon icon;
+ private ShaderManager shader;
+ private ITextureObject[] textures;
+ private Consumer<ShaderManager> onTick;
+ private List<IMouseDragListener> mouseDragListeners = new ArrayList<>();
+
+ public ShaderMultiImageView(MalisisGui gui, ShaderManager shader, ITextureObject...textures) {
+ super(gui);
+ this.shader = shader;
+ this.textures = textures;
+ this.setSize(300, 128);
+
+ this.icon = new Icon().flip(false, true);
+ }
+
+ public ShaderMultiImageView<T> addOnShaderTick(Consumer<ShaderManager> onTick) {
+ Consumer<ShaderManager> prev = this.onTick;
+ this.onTick = shader -> {
+ if (prev != null) {
+ prev.accept(shader);
+ }
+ onTick.accept(shader);
+ };
+ return this;
+ }
+
+ @Override public void drawBackground(GuiRenderer guiRenderer, int i, int i1, float v) {
+
+ }
+
+ @Override public void drawForeground(GuiRenderer guiRenderer, int i, int i1, float v) {
+
+ // todo: make it possible to set it from the outside
+ float uMin = -getWidth() / 2;
+ float uMax = getWidth() / 2;
+ float vMin = -getHeight() / 2;
+ float vMax = getHeight() / 2;
+ guiRenderer.next(DefaultVertexFormats.POSITION_TEX);
+ shader.useShader();
+ if (onTick != null) {
+ onTick.accept(shader);
+ }
+ this.rp.icon.set(icon);
+ this.rp.icon.get().setUVs(uMin, vMin, uMax, vMax);
+ guiRenderer.drawShape(this.shape, rp);
+ guiRenderer.next();
+ shader.endShader();
+ }
+
+ public void addOnMouseDrag(IMouseDragListener listener) {
+ this.mouseDragListeners.add(listener);
+ }
+
+ @Override public boolean onDrag(int lastX, int lastY, int x, int y, MouseButton button) {
+ mouseDragListeners.forEach(l -> l.onDrag(lastX, lastY, x, y, button));
+ return true;
+ }
+}
diff --git a/src/main/java/cubicchunks/worldgen/gui/component/TerrainPreviewScaleOverlay.java b/src/main/java/cubicchunks/worldgen/gui/component/TerrainPreviewScaleOverlay.java
new file mode 100644
index 00000000..88fced0c
--- /dev/null
+++ b/src/main/java/cubicchunks/worldgen/gui/component/TerrainPreviewScaleOverlay.java
@@ -0,0 +1,183 @@
+/*
+ * This file is part of Cubic Chunks Mod, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2015 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package cubicchunks.worldgen.gui.component;
+
+import cubicchunks.util.MathUtil;
+import net.malisis.core.client.gui.GuiRenderer;
+import net.malisis.core.client.gui.MalisisGui;
+import net.malisis.core.client.gui.component.UIComponent;
+import net.malisis.core.client.gui.component.container.UIContainer;
+import net.malisis.core.client.gui.element.GuiShape;
+import net.malisis.core.client.gui.element.SimpleGuiShape;
+import net.malisis.core.renderer.font.FontOptions;
+import net.malisis.core.renderer.font.MalisisFont;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.util.math.MathHelper;
+import org.lwjgl.util.vector.Matrix4f;
+
+public class TerrainPreviewScaleOverlay extends UIContainer<TerrainPreviewScaleOverlay> {
+
+ private final ShaderMultiImageView<?> wrappedComponent;
+ private float zoom;
+ private float offsetX;
+ private float offsetY;
+ private float biomeScale;
+ private float biomeOffset;
+
+ public TerrainPreviewScaleOverlay(MalisisGui gui, ShaderMultiImageView<?> wrappedComponent) {
+ super(gui);
+ this.wrappedComponent = wrappedComponent;
+ add(wrappedComponent);
+ }
+
+ public void setTransform(float zoom, float offsetX, float offsetY) {
+ this.zoom = zoom;
+ this.offsetX = offsetX;
+ this.offsetY = offsetY;
+ }
+
+ public void setBiomeTransform(float biomeScale, float biomeOffset) {
+ this.biomeScale = biomeScale;
+ this.biomeOffset = biomeOffset;
+ }
+
+ @Override public void drawBackground(GuiRenderer guiRenderer, int i, int i1, float v) {
+ wrappedComponent.setSize(getWidth(), getHeight());
+ super.drawBackground(guiRenderer, i, i1, v);
+ }
+
+ @Override public void drawForeground(GuiRenderer guiRenderer, int i, int i1, float v) {
+ super.drawForeground(guiRenderer, i, i1, v);
+
+ drawXScale();
+ drawYScale();
+ drawBiomeNames();
+ }
+
+ private void drawBiomeNames() {
+
+ }
+
+ private void drawXScale() {
+ float blockLeft = posToX(0);
+ float blockRight = posToX(getWidth());
+
+ float maxVal = Math.max(Math.abs(blockLeft), Math.abs(blockRight));
+ int digits = MathHelper.ceil(Math.log(Math.max(maxVal, 1)) / Math.log(10)) + ((blockLeft < 0 || blockRight < 0) ? 1 : 0);
+
+ int increment = getIncrement(blockLeft, blockRight, getWidth() / (7 * digits));
+ if (increment < 0 || maxVal + increment > Integer.MAX_VALUE) {
+ return;// TODO: handle integer overflow for increment
+ }
+ int start = MathHelper.roundUp(MathHelper.floor(blockLeft), increment);
+
+ FontOptions fo = new FontOptions.FontOptionsBuilder().color(0xFFFFFF).shadow(true).build();
+ for (int x = start; x <= blockRight; x += increment) {
+ int pos = (int) xToPos(x);
+ int strWidth = (int) (MalisisFont.minecraftFont.getStringWidth(String.valueOf(Math.abs(x)), fo) / 2 +
+ (x < 0 ? MalisisFont.minecraftFont.getStringWidth("-", fo) : 0));
+ renderer.drawText(MalisisFont.minecraftFont, String.valueOf(x), pos - strWidth + 1, getHeight() - 10, 0, fo);
+ }
+
+ renderer.next();
+ GlStateManager.disableTexture2D();
+ SimpleGuiShape shape = new SimpleGuiShape();
+ shape.setSize(1, 2);
+ for (int x = start; x <= blockRight; x += increment) {
+ int pos = (int) xToPos(x);
+ int strWidth = (int) (MalisisFont.minecraftFont.getStringWidth(String.valueOf(x), fo) / 2);
+ shape.storeState();
+ shape.setPosition(pos, getHeight() - 1);
+ renderer.drawShape(shape, rp);
+
+ shape.resetState();
+ }
+ renderer.next();
+ GlStateManager.enableTexture2D();
+
+ }
+
+ private void drawYScale() {
+ float blockBottom = posToY(getHeight());// bottom -> getHeight()
+ float blockTop = posToY(0);
+
+ int increment = getIncrement(blockBottom, blockTop, getHeight() / 11);
+ if (increment < 0 || Math.max(Math.abs(blockBottom) + increment, Math.abs(blockTop) + increment) > Integer.MAX_VALUE) {
+ return;// TODO: handle integer overflow for increment
+ }
+ int start = MathHelper.roundUp(MathHelper.floor(blockBottom), increment);
+
+ FontOptions fo = new FontOptions.FontOptionsBuilder().color(0xFFFFFF).shadow(true).build();
+ for (int y = start; y <= blockTop; y += increment) {
+ int pos = (int) yToPos(y);
+ if (pos < 15 || pos > getHeight() - 15) {
+ continue;
+ }
+ int strHeight = (int) (MalisisFont.minecraftFont.getStringHeight() / 2);
+ // use the "-" character as graph mark
+ renderer.drawText(MalisisFont.minecraftFont, "- " + y, 0, pos - strHeight, 0, fo);
+ }
+
+ }
+
+ private float posToY(float pos) {
+ return offsetY + zoom * (-pos + getHeight() / 2);
+ }
+
+ private float yToPos(float y) {
+ return -(y - offsetY) / zoom + getHeight() / 2;
+ }
+
+ private float posToX(float pos) {
+ return offsetX + zoom * (pos - getWidth() / 2);
+ }
+
+ private float xToPos(float y) {
+ return (y - offsetX) / zoom + getWidth() / 2;
+ }
+
+ private int getIncrement(float start, float end, int maxAmount) {
+ float totalSize = Math.abs(end - start);
+
+ int curr = 1;
+ while (curr < totalSize / maxAmount) {
+ long n = curr;
+ if (MathUtil.isPowerOfN(curr, 10)) {
+ n *= 2;
+ } else if (MathUtil.isPowerOfN(curr / 2, 10)) {
+ n /= 2;
+ n *= 5;
+ } else {
+ assert MathUtil.isPowerOfN(curr / 5, 10); // 5*powerOf10
+ n *= 2;
+ }
+ if (n != (int) n) {
+ return -1; // integer overflow, show just the beginning and the end
+ }
+ curr = (int) n;
+ }
+
+ return curr;
+ }
+}
diff --git a/src/main/java/cubicchunks/worldgen/gui/component/UIBlockStateSelect.java b/src/main/java/cubicchunks/worldgen/gui/component/UIBlockStateSelect.java
new file mode 100644
index 00000000..4faa82cb
--- /dev/null
+++ b/src/main/java/cubicchunks/worldgen/gui/component/UIBlockStateSelect.java
@@ -0,0 +1,234 @@
+package cubicchunks.worldgen.gui.component;
+
+import cubicchunks.worldgen.gui.DummyWorld;
+import cubicchunks.worldgen.gui.ExtraGui;
+import net.malisis.core.client.gui.ClipArea;
+import net.malisis.core.client.gui.GuiRenderer;
+import net.malisis.core.client.gui.MalisisGui;
+import net.malisis.core.client.gui.component.IClipable;
+import net.malisis.core.client.gui.component.UIComponent;
+import net.malisis.core.client.gui.component.container.UIContainer;
+import net.malisis.core.client.gui.component.container.UIPanel;
+import net.malisis.core.client.gui.component.control.IScrollable;
+import net.malisis.core.client.gui.component.control.UIScrollBar;
+import net.malisis.core.client.gui.component.control.UISlimScrollbar;
+import net.malisis.core.client.gui.component.interaction.UISelect;
+import net.malisis.core.client.gui.element.GuiShape;
+import net.malisis.core.client.gui.element.SimpleGuiShape;
+import net.malisis.core.client.gui.element.XYResizableGuiShape;
+import net.malisis.core.renderer.icon.provider.GuiIconProvider;
+import net.minecraft.block.Block;
+import net.minecraft.block.state.IBlockState;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.BufferBuilder;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.client.renderer.RenderHelper;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.texture.ITextureObject;
+import net.minecraft.client.renderer.texture.TextureMap;
+import net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer;
+import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
+import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.client.renderer.vertex.VertexFormat;
+import net.minecraft.item.ItemStack;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.MathHelper;
+import net.minecraftforge.fml.common.registry.ForgeRegistries;
+import org.lwjgl.opengl.GL11;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+
+public class UIBlockStateSelect<T extends UIBlockStateSelect<T>> extends UIContainer<T> {
+
+ private static final int PADDING_VERT = 20;
+ private static final int PADDING_HORIZ = 20;
+
+ private Consumer<IBlockState> onSelect;
+
+ private static final List<IBlockState> allStates;
+
+ static {
+ List<IBlockState> states = new ArrayList<>();
+ for (Block block : ForgeRegistries.BLOCKS) {
+ for (IBlockState state : block.getBlockState().getValidStates()) {
+ if (state != block.getStateFromMeta(block.getMetaFromState(state))) {
+ continue;
+ }
+ if (state.getBlock().hasTileEntity(state)
+ && TileEntityRendererDispatcher.instance.getRenderer(state.getBlock().createTileEntity(null, state)) != null) {
+ continue; // Don't allow TESR
+ }
+ states.add(state);
+ }
+ }
+
+ allStates = states;
+ }
+
+ public UIBlockStateSelect(ExtraGui gui) {
+ super(gui);
+
+ UIScrollBar scrollbar = new UIOptionScrollbar((ExtraGui) getGui(), (T) this, UIScrollBar.Type.VERTICAL);
+ scrollbar.setVisible(true);
+ scrollbar.setPosition(0, 0);
+ this.clipContent = true;
+
+ this.setPadding(PADDING_HORIZ, PADDING_VERT);
+ }
+
+ @Override public ClipArea getClipArea() {
+ return new ClipArea(this, getLeftPadding(), getTopPadding(), getWidth() - getRightPadding(), getHeight() - getBottomPadding(), false);
+ }
+
+ public void display(Consumer<IBlockState> onSelect) {
+ this.onSelect = onSelect;
+
+ this.setZIndex(1);
+ getGui().addToScreen(this);
+ }
+
+ @Override public void drawBackground(GuiRenderer renderer, int mouseX, int mouseY, float partialTick) {
+ rp.useTexture.set(false);
+
+ renderer.disableTextures();
+
+ rp.alpha.set(100);
+ rp.colorMultiplier.set(0xFFFFFF);
+
+ shape.resetState();
+ //shape.setSize((int) getAvailableWidth(), (int) getAvailableHeight());
+ //shape.setPosition(getLeftPadding(), getTopPadding());
+ renderer.drawShape(shape, rp);
+
+ renderer.next();
+ renderer.enableTextures();
+ }
+/*
+ @Override public void drawForeground(GuiRenderer renderer, int mouseX, int mouseY, float partialTick) {
+
+ // half of that on the left, half on the right
+ int addPadding =
+ (int) Math.round((getAvailableWidth() - getLineStates() * UIBlockStateButton.SIZE) * 0.5);
+
+ double offsetY = getOffsetY();
+ double pixelsOffset = offsetY * (getContentHeight() - getAvailableHeight());
+
+ int lineStart = (int) (pixelsOffset / UIBlockStateButton.SIZE);
+ int lineEnd = MathHelper.ceil((pixelsOffset + getAvailableHeight()) / UIBlockStateButton.SIZE);
+
+ int itemStart = lineStart * getLineStates();
+ int itemEnd = lineEnd * getLineStates();
+
+ GlStateManager.bindTexture(0);
+ int idx = getSelectedIdx(mouseX, mouseY);
+ if (idx >= 0) {
+ int line = idx / getLineStates();
+ int num = idx % getLineStates();
+
+ shape.resetState();
+ shape.setSize(UIBlockStateButton.SIZE, UIBlockStateButton.SIZE);
+ shape.setPosition(num * UIBlockStateButton.SIZE + getLeftPadding()+ addPadding, (int) (line * UIBlockStateButton.SIZE - pixelsOffset +
+ getTopPadding()));
+ rp.setAlpha(200);
+ rp.setColor(0);
+ renderer.drawShape(shape, rp);
+ }
+
+ renderer.next();
+
+ GlStateManager.enableDepth();
+
+ Tessellator.getInstance().draw();
+ ITextureObject blockTexture = Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
+
+ for (int i = itemStart; i < itemEnd; i++) {
+ if (i >= allStates.size() || i < 0) {
+ continue;
+ }
+ int line = i / getLineStates();
+ int num = i % getLineStates();
+
+ RenderHelper.disableStandardItemLighting();
+ RenderHelper.enableGUIStandardItemLighting();
+ GlStateManager.enableRescaleNormal();
+ GL11.glBindTexture(GL11.GL_TEXTURE_2D, blockTexture.getGlTextureId());
+
+ drawState(allStates.get(i), num * UIBlockStateButton.SIZE + PADDING_HORIZ + addPadding,
+ (int) (line * UIBlockStateButton.SIZE - pixelsOffset + PADDING_VERT));
+ }
+
+
+ renderer.next();
+
+ GlStateManager.disableRescaleNormal();
+ }
+
+ private void drawState(IBlockState state, int x, int y) {
+ GlStateManager.pushMatrix();
+ GlStateManager.translate((float) this.screenX() + x + 2, (float) this.screenY() + 18f + y, 100.0F);
+ GlStateManager.scale(14.0F, 14.0F, -14.0F);
+ GlStateManager.rotate(210.0F, 1.0F, 0.0F, 0.0F);
+ GlStateManager.rotate(45.0F, 0.0F, 1.0F, 0.0F);
+
+ BufferBuilder buf = Tessellator.getInstance().getBuffer();
+
+ buf.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
+
+ Minecraft.getMinecraft().getBlockRendererDispatcher().renderBlock(state, BlockPos.ORIGIN,
+ DummyWorld.getInstanceWithBlockState(state), buf);
+
+ Tessellator.getInstance().draw();
+
+ GlStateManager.popMatrix();
+ }
+
+ private double getAvailableWidth() {
+ return getWidth() - PADDING_HORIZ * 2;
+ }
+
+ private int getSelectedIdx(int mouseX, int mouseY) {
+
+ int addPadding =
+ (int) Math.round((getAvailableWidth() - getLineStates() * UIBlockStateButton.SIZE) * 0.5);
+
+ mouseX -= getLeftPadding() + addPadding;
+ mouseY -= getTopPadding();
+
+ if (mouseX < 0 || mouseX >= getLineStates() * UIBlockStateButton.SIZE) {
+ return -1;
+ }
+ int column = mouseX / UIBlockStateButton.SIZE;
+
+ double pixelsOffset = getOffsetY() * (getContentHeight() - getAvailableHeight());
+ int totalY = (int) (mouseY + pixelsOffset);
+ int row = totalY / UIBlockStateButton.SIZE;
+
+ return row * getLineStates() + column;
+ }
+
+ private double getAvailableHeight() {
+ return getHeight() - PADDING_VERT * 2;
+ }
+
+ private int getLineStates() {
+ return (int) (getAvailableWidth() / UIBlockStateButton.SIZE);
+ }
+
+ private int getLineCount() {
+ return MathHelper.ceil(allStates.size() / (double) getLineStates());
+ }
+
+ @Override
+ public int getContentWidth() {
+ return getWidth();
+ }
+
+ @Override
+ public int getContentHeight() {
+ return getLineCount() * UIBlockStateButton.SIZE;
+ }*/
+}
diff --git a/src/main/java/cubicchunks/worldgen/gui/render/RawFloatImage.java b/src/main/java/cubicchunks/worldgen/gui/render/RawFloatImage.java
new file mode 100644
index 00000000..68735e65
--- /dev/null
+++ b/src/main/java/cubicchunks/worldgen/gui/render/RawFloatImage.java
@@ -0,0 +1,132 @@
+/*
+ * This file is part of Cubic Chunks Mod, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2015 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package cubicchunks.worldgen.gui.render;
+
+import static org.lwjgl.opengl.GL11.GL_FLOAT;
+import static org.lwjgl.opengl.GL11.GL_LUMINANCE;
+import static org.lwjgl.opengl.GL11.GL_RED;
+import static org.lwjgl.opengl.GL11.GL_RGB;
+import static org.lwjgl.opengl.GL11.GL_RGBA;
+import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
+import static org.lwjgl.opengl.GL11.glTexImage2D;
+import static org.lwjgl.opengl.GL12.GL_TEXTURE_MAX_LEVEL;
+import static org.lwjgl.opengl.GL12.GL_TEXTURE_MAX_LOD;
+import static org.lwjgl.opengl.GL12.GL_TEXTURE_MIN_LOD;
+import static org.lwjgl.opengl.GL14.GL_TEXTURE_LOD_BIAS;
+import static org.lwjgl.opengl.GL30.GL_R16F;
+import static org.lwjgl.opengl.GL30.GL_RG;
+import static org.lwjgl.opengl.GL30.GL_RG16F;
+import static org.lwjgl.opengl.GL30.GL_RGB16F;
+import static org.lwjgl.opengl.GL30.GL_RGBA16F;
+
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.client.renderer.texture.ITextureObject;
+import net.minecraft.client.renderer.texture.TextureUtil;
+import net.minecraft.client.resources.IResourceManager;
+import org.lwjgl.BufferUtils;
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.opengl.GL12;
+import org.lwjgl.opengl.GL14;
+import org.lwjgl.opengl.GL30;
+
+import java.io.IOException;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+
+public class RawFloatImage implements ITextureObject {
+
+ private final int width, height;
+ private int texture;
+ private final FloatBuffer data;
+ private int channels;
+
+ public RawFloatImage(float[][] imageData, int channels) {
+ if (channels > 4 || channels < 1) {
+ throw new IllegalArgumentException("Channel count must be between 1 and 4 but was " + channels);
+ }
+ this.channels = channels;
+ FloatBuffer buffer = BufferUtils.createFloatBuffer(imageData.length * imageData[0].length);
+ for (float[] subArr : imageData) {
+ buffer.put(subArr);
+ }
+ buffer.flip();
+
+ this.data = buffer;
+ this.width = imageData[0].length / channels;
+ this.height = imageData.length;
+ }
+
+ public void delete() {
+ if (texture > 0) {
+ TextureUtil.deleteTexture(texture);
+ }
+ }
+
+ @Override public void setBlurMipmap(boolean blurIn, boolean mipmapIn) {
+ // no-op
+ }
+
+ @Override public void restoreLastBlurMipmap() {
+ // no-op
+ }
+
+ @Override public void loadTexture(IResourceManager resourceManager) {
+ delete();
+ int texture = TextureUtil.glGenTextures();
+ GlStateManager.bindTexture(texture);
+ GlStateManager.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+ GlStateManager.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0);
+ GlStateManager.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0);
+ GlStateManager.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, 0.0F);
+
+ int internalFmt;
+ int fmt;
+ switch (channels) {
+ case 1:
+ internalFmt = GL_R16F;
+ fmt = GL_RED;
+ break;
+ case 2:
+ internalFmt = GL_RG16F;
+ fmt = GL_RG;
+ break;
+ case 3:
+ internalFmt = GL_RGB16F;
+ fmt = GL_RGB;
+ break;
+ case 4:
+ internalFmt = GL_RGBA16F;
+ fmt = GL_RGBA;
+ break;
+ default:
+ throw new Error();
+ }
+ glTexImage2D(GL_TEXTURE_2D, 0, internalFmt, width, height, 0, fmt, GL_FLOAT, this.data);
+ this.texture = texture;
+ }
+
+ @Override public int getGlTextureId() {
+ return texture;
+ }
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment